diff --git a/DEPS b/DEPS index fe79a52..f7da473 100644 --- a/DEPS +++ b/DEPS
@@ -232,7 +232,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'af4b1f23209f522bd5b52bb0f9e87f1874b7f713', + 'v8_revision': 'fbba2862f13eda82033d350aad441a4376373afb', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -275,7 +275,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': '61903609674f2a4ad18abbbcb1d40f5c8beeeaf4', + 'freetype_revision': 'b4dddd8244fb59795f030530ad2b401ec4d5b477', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -303,7 +303,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '3a3ff5263355998a3a15963a40f5b213dbc4c3cd', + 'devtools_frontend_revision': 'cd7c3815feebdf809f13cfb3190eae26d443b978', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -343,7 +343,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': 'a10f5331f2b5263375b504a20cf3c1caec9b5d70', + 'dawn_revision': 'f84e7b4edacd5b8942cc66405fc88a1f601fa21e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -773,7 +773,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': '9NWqy0Mwybr2-UnSDAVpZ77TLsWo0E6-CKkEfwzylNYC', + 'version': 'zzVIaEA3uTWNbAiFgL34RFj52xan_NtxkXTFIZjsrroC', }, ], 'condition': 'checkout_android', @@ -1398,7 +1398,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'df2e9fecdfb26f36a6a674b1f97a9117ab714a42', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '8f0fabf54bc923165ac47bc1b7de45b9eee0ff3d', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1619,7 +1619,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '2a6a882c94af7ca19b2121fc268a7db1ea671df6', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '2d0e82e4cfa78787ce11e056d0449f0bd3f76bac', + Var('webrtc_git') + '/src.git' + '@' + '9def99487e3b41a044ae4854ff620b8ff817f10f', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1677,7 +1677,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@d5f6874f5f07feb528bbe51c6f64ed2af63de242', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@f1ede5354069a2e5dd24983323ef922501887011', 'condition': 'checkout_src_internal', }, @@ -1685,7 +1685,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/eche_app/app', - 'version': 'YVUgoZZnc_bC_FLd0b7kMOFR6jjRC7lIUCz5MQ_gwfgC', + 'version': 'vfSvt4_rJR0SPZGxGk0lSP-uaypLPoA6EeKstKVfZicC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -1718,7 +1718,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/projector_app/app', - 'version': '7y9MRIzWlHdbocmrSRj_cR6ywn-cXPir8zejFA4yUboC', + 'version': 'IBU8QLtkSw-VH1bf4vgWHEQrgj01kjHDXYlKrPg-2WQC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal',
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc index c3aed3dd..d16e09e 100644 --- a/ash/app_list/views/search_result_view.cc +++ b/ash/app_list/views/search_result_view.cc
@@ -155,8 +155,6 @@ CONTEXT_SEARCH_RESULT_VIEW, STYLE_PRODUCTIVITY_LAUNCHER)); separator_label_->SetBackgroundColor(SK_ColorTRANSPARENT); separator_label_->SetVisible(false); - separator_label_->SetText( - l10n_util::GetStringUTF16(IDS_ASH_SEARCH_RESULT_SEPARATOR)); separator_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); }
diff --git a/ash/public/cpp/test/test_system_tray_client.cc b/ash/public/cpp/test/test_system_tray_client.cc index efa808a..ae21e3a 100644 --- a/ash/public/cpp/test/test_system_tray_client.cc +++ b/ash/public/cpp/test/test_system_tray_client.cc
@@ -17,7 +17,9 @@ } void TestSystemTrayClient::ShowBluetoothPairingDialog( - absl::optional<base::StringPiece> device_address) {} + absl::optional<base::StringPiece> device_address) { + show_bluetooth_pairing_dialog_count_++; +} void TestSystemTrayClient::ShowDateSettings() {}
diff --git a/ash/public/cpp/test/test_system_tray_client.h b/ash/public/cpp/test/test_system_tray_client.h index 5926f4d..ea2f1c2 100644 --- a/ash/public/cpp/test/test_system_tray_client.h +++ b/ash/public/cpp/test/test_system_tray_client.h
@@ -61,9 +61,15 @@ int show_bluetooth_settings_count() const { return show_bluetooth_settings_count_; } + + int show_bluetooth_pairing_dialog_count() const { + return show_bluetooth_pairing_dialog_count_; + } + int show_multi_device_setup_count() const { return show_multi_device_setup_count_; } + int show_connected_devices_settings_count() const { return show_connected_devices_settings_count_; } @@ -82,6 +88,7 @@ private: int show_bluetooth_settings_count_ = 0; + int show_bluetooth_pairing_dialog_count_ = 0; int show_multi_device_setup_count_ = 0; int show_connected_devices_settings_count_ = 0; int show_os_settings_privacy_and_security_count_ = 0;
diff --git a/ash/quick_pair/common/BUILD.gn b/ash/quick_pair/common/BUILD.gn index 6bac4904..1a17beb7 100644 --- a/ash/quick_pair/common/BUILD.gn +++ b/ash/quick_pair/common/BUILD.gn
@@ -21,6 +21,8 @@ "device.h", "fast_pair/fast_pair_decoder.cc", "fast_pair/fast_pair_decoder.h", + "fast_pair/fast_pair_metrics.cc", + "fast_pair/fast_pair_metrics.h", "fast_pair/fast_pair_service_data_creator.cc", "fast_pair/fast_pair_service_data_creator.h", "log_buffer.cc",
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc b/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc new file mode 100644 index 0000000..d668568 --- /dev/null +++ b/ash/quick_pair/common/fast_pair/fast_pair_metrics.cc
@@ -0,0 +1,20 @@ +// 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 "ash/quick_pair/common/fast_pair/fast_pair_metrics.h" + +#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" +#include "base/metrics/sparse_histogram.h" + +namespace ash { +namespace quick_pair { + +void RecordFastPairEngagementFlow(FastPairEngagementFlowEvent event) { + base::UmaHistogramSparse("Bluetooth.ChromeOS.FastPair.EngagementFunnel.Steps", + static_cast<int>(event)); +} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/common/fast_pair/fast_pair_metrics.h b/ash/quick_pair/common/fast_pair/fast_pair_metrics.h new file mode 100644 index 0000000..dd3f9a0 --- /dev/null +++ b/ash/quick_pair/common/fast_pair/fast_pair_metrics.h
@@ -0,0 +1,33 @@ +// 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 ASH_QUICK_PAIR_COMMON_FAST_PAIR_FAST_PAIR_METRICS_H_ +#define ASH_QUICK_PAIR_COMMON_FAST_PAIR_FAST_PAIR_METRICS_H_ + +#include "base/component_export.h" + +namespace ash { +namespace quick_pair { + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. The numbers here correspond to the +// ordering of the flow. This enum should be kept in sync with the +// FastPairEngagementFlowEvent enum in src/tools/metrics/histograms/enums.xml. +enum COMPONENT_EXPORT(QUICK_PAIR_COMMON) FastPairEngagementFlowEvent { + kDiscoveryUiShown = 1, + kDiscoveryUiDismissed = 11, + kDiscoveryUiConnectPressed = 12, + kPairingFailed = 121, + kPairingSucceeded = 122, + kErrorUiDismissed = 1211, + kErrorUiSettingsPressed = 1212, +}; + +COMPONENT_EXPORT(QUICK_PAIR_COMMON) +void RecordFastPairEngagementFlow(FastPairEngagementFlowEvent event); + +} // namespace quick_pair +} // namespace ash + +#endif // ASH_QUICK_PAIR_COMMON_FAST_PAIR_FAST_PAIR_METRICS_LOGGER_H_
diff --git a/ash/quick_pair/keyed_service/BUILD.gn b/ash/quick_pair/keyed_service/BUILD.gn index 8af69b8..845b35dbab 100644 --- a/ash/quick_pair/keyed_service/BUILD.gn +++ b/ash/quick_pair/keyed_service/BUILD.gn
@@ -13,6 +13,8 @@ "quick_pair_keyed_service.h", "quick_pair_mediator.cc", "quick_pair_mediator.h", + "quick_pair_metrics_logger.cc", + "quick_pair_metrics_logger.h", ] deps = [ @@ -32,7 +34,10 @@ source_set("unit_tests") { testonly = true - sources = [ "quick_pair_mediator_unittest.cc" ] + sources = [ + "quick_pair_mediator_unittest.cc", + "quick_pair_metrics_logger_unittest.cc", + ] deps = [ ":keyed_service",
diff --git a/ash/quick_pair/keyed_service/quick_pair_mediator.cc b/ash/quick_pair/keyed_service/quick_pair_mediator.cc index 82497cf8..31b8b6a 100644 --- a/ash/quick_pair/keyed_service/quick_pair_mediator.cc +++ b/ash/quick_pair/keyed_service/quick_pair_mediator.cc
@@ -10,6 +10,7 @@ #include "ash/quick_pair/common/logging.h" #include "ash/quick_pair/feature_status_tracker/quick_pair_feature_status_tracker.h" #include "ash/quick_pair/feature_status_tracker/quick_pair_feature_status_tracker_impl.h" +#include "ash/quick_pair/keyed_service/quick_pair_metrics_logger.h" #include "ash/quick_pair/pairing/pairer_broker_impl.h" #include "ash/quick_pair/repository/fast_pair_repository_impl.h" #include "ash/quick_pair/scanning/scanner_broker_impl.h" @@ -58,6 +59,9 @@ ui_broker_(std::move(ui_broker)), fast_pair_repository_(std::move(fast_pair_repository)), process_manager_(std::move(process_manager)) { + metrics_logger_ = std::make_unique<QuickPairMetricsLogger>( + scanner_broker_.get(), pairer_broker_.get(), ui_broker_.get()); + feature_status_tracker_observation_.Observe(feature_status_tracker_.get()); scanner_broker_observation_.Observe(scanner_broker_.get()); pairer_broker_observation_.Observe(pairer_broker_.get()); @@ -67,7 +71,11 @@ quick_pair_process::SetProcessManager(process_manager_.get()); } -Mediator::~Mediator() = default; +Mediator::~Mediator() { + // The metrics logger must be deleted first because it depends on other + // members. + metrics_logger_.reset(); +} void Mediator::OnFastPairEnabledChanged(bool is_enabled) { SetFastPairState(is_enabled);
diff --git a/ash/quick_pair/keyed_service/quick_pair_mediator.h b/ash/quick_pair/keyed_service/quick_pair_mediator.h index 72a76cb..9522050 100644 --- a/ash/quick_pair/keyed_service/quick_pair_mediator.h +++ b/ash/quick_pair/keyed_service/quick_pair_mediator.h
@@ -20,6 +20,7 @@ class FastPairRepository; struct Device; class QuickPairProcessManager; +class QuickPairMetricsLogger; // Implements the Mediator design pattern for the components in the Quick Pair // system, e.g. the UI Broker, Scanning Broker and Pairing Broker. @@ -81,6 +82,7 @@ std::unique_ptr<UIBroker> ui_broker_; std::unique_ptr<FastPairRepository> fast_pair_repository_; std::unique_ptr<QuickPairProcessManager> process_manager_; + std::unique_ptr<QuickPairMetricsLogger> metrics_logger_; base::ScopedObservation<FeatureStatusTracker, FeatureStatusTracker::Observer> feature_status_tracker_observation_{this};
diff --git a/ash/quick_pair/keyed_service/quick_pair_metrics_logger.cc b/ash/quick_pair/keyed_service/quick_pair_metrics_logger.cc new file mode 100644 index 0000000..340f5c2 --- /dev/null +++ b/ash/quick_pair/keyed_service/quick_pair_metrics_logger.cc
@@ -0,0 +1,104 @@ +// 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 "ash/quick_pair/keyed_service/quick_pair_metrics_logger.h" + +#include "ash/quick_pair/common/device.h" +#include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h" +#include "ash/quick_pair/common/logging.h" + +namespace ash { +namespace quick_pair { + +QuickPairMetricsLogger::QuickPairMetricsLogger(ScannerBroker* scanner_broker, + PairerBroker* pairer_broker, + UIBroker* ui_broker) { + scanner_broker_observation_.Observe(scanner_broker); + pairer_broker_observation_.Observe(pairer_broker); + ui_broker_observation_.Observe(ui_broker); +} + +QuickPairMetricsLogger::~QuickPairMetricsLogger() = default; + +void QuickPairMetricsLogger::OnDevicePaired(scoped_refptr<Device> device) { + switch (device->protocol) { + case Protocol::kFastPair: + RecordFastPairEngagementFlow( + FastPairEngagementFlowEvent::kPairingSucceeded); + break; + } +} + +void QuickPairMetricsLogger::OnPairFailure(scoped_refptr<Device> device, + PairFailure failure) { + switch (device->protocol) { + case Protocol::kFastPair: + RecordFastPairEngagementFlow(FastPairEngagementFlowEvent::kPairingFailed); + break; + } +} + +void QuickPairMetricsLogger::OnDiscoveryAction(scoped_refptr<Device> device, + DiscoveryAction action) { + switch (device->protocol) { + case Protocol::kFastPair: + switch (action) { + case DiscoveryAction::kPairToDevice: + RecordFastPairEngagementFlow( + FastPairEngagementFlowEvent::kDiscoveryUiConnectPressed); + break; + case DiscoveryAction::kDismissedByUser: + case DiscoveryAction::kDismissed: + RecordFastPairEngagementFlow( + FastPairEngagementFlowEvent::kDiscoveryUiDismissed); + break; + } + break; + } +} + +void QuickPairMetricsLogger::OnPairingFailureAction( + scoped_refptr<Device> device, + PairingFailedAction action) { + switch (device->protocol) { + case Protocol::kFastPair: + switch (action) { + case PairingFailedAction::kNavigateToSettings: + RecordFastPairEngagementFlow( + FastPairEngagementFlowEvent::kErrorUiSettingsPressed); + break; + case PairingFailedAction::kDismissedByUser: + case PairingFailedAction::kDismissed: + RecordFastPairEngagementFlow( + FastPairEngagementFlowEvent::kErrorUiDismissed); + break; + } + break; + } +} + +void QuickPairMetricsLogger::OnDeviceFound(scoped_refptr<Device> device) { + switch (device->protocol) { + case Protocol::kFastPair: + RecordFastPairEngagementFlow( + FastPairEngagementFlowEvent::kDiscoveryUiShown); + break; + } +} + +void QuickPairMetricsLogger::OnAccountKeyWrite( + scoped_refptr<Device> device, + absl::optional<AccountKeyFailure> error) {} + +void QuickPairMetricsLogger::OnCompanionAppAction(scoped_refptr<Device> device, + CompanionAppAction action) {} + +void QuickPairMetricsLogger::OnAssociateAccountAction( + scoped_refptr<Device> device, + AssociateAccountAction action) {} + +void QuickPairMetricsLogger::OnDeviceLost(scoped_refptr<Device> device) {} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/quick_pair/keyed_service/quick_pair_metrics_logger.h b/ash/quick_pair/keyed_service/quick_pair_metrics_logger.h new file mode 100644 index 0000000..4a1e4a98 --- /dev/null +++ b/ash/quick_pair/keyed_service/quick_pair_metrics_logger.h
@@ -0,0 +1,64 @@ +// 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 ASH_QUICK_PAIR_KEYED_SERVICE_QUICK_PAIR_METRICS_LOGGER_H_ +#define ASH_QUICK_PAIR_KEYED_SERVICE_QUICK_PAIR_METRICS_LOGGER_H_ + +#include "ash/quick_pair/pairing/pairer_broker.h" +#include "ash/quick_pair/scanning/scanner_broker.h" +#include "ash/quick_pair/ui/ui_broker.h" +#include "base/memory/scoped_refptr.h" +#include "base/scoped_observation.h" + +namespace ash { +namespace quick_pair { + +struct Device; + +// Observes pairing, scanning and UI events and logs corresponding metrics. +class QuickPairMetricsLogger : public PairerBroker::Observer, + public ScannerBroker::Observer, + public UIBroker::Observer { + public: + QuickPairMetricsLogger(ScannerBroker* scanner_broker, + PairerBroker* pairer_broker, + UIBroker* ui_broker); + QuickPairMetricsLogger(const QuickPairMetricsLogger&) = delete; + QuickPairMetricsLogger& operator=(const QuickPairMetricsLogger&) = delete; + ~QuickPairMetricsLogger() override; + + private: + // PairerBroker::Observer + void OnDevicePaired(scoped_refptr<Device> device) override; + void OnPairFailure(scoped_refptr<Device> device, + PairFailure failure) override; + void OnAccountKeyWrite(scoped_refptr<Device> device, + absl::optional<AccountKeyFailure> error) override; + + // UIBroker::Observer + void OnDiscoveryAction(scoped_refptr<Device> device, + DiscoveryAction action) override; + void OnCompanionAppAction(scoped_refptr<Device> device, + CompanionAppAction action) override; + void OnPairingFailureAction(scoped_refptr<Device> device, + PairingFailedAction action) override; + void OnAssociateAccountAction(scoped_refptr<Device> device, + AssociateAccountAction action) override; + + // ScannerBroker::Observer + void OnDeviceFound(scoped_refptr<Device> device) override; + void OnDeviceLost(scoped_refptr<Device> device) override; + + base::ScopedObservation<ScannerBroker, ScannerBroker::Observer> + scanner_broker_observation_{this}; + base::ScopedObservation<PairerBroker, PairerBroker::Observer> + pairer_broker_observation_{this}; + base::ScopedObservation<UIBroker, UIBroker::Observer> ui_broker_observation_{ + this}; +}; + +} // namespace quick_pair +} // namespace ash + +#endif // ASH_QUICK_PAIR_KEYED_SERVICE_QUICK_PAIR_METRICS_LOGGER_H_
diff --git a/ash/quick_pair/keyed_service/quick_pair_metrics_logger_unittest.cc b/ash/quick_pair/keyed_service/quick_pair_metrics_logger_unittest.cc new file mode 100644 index 0000000..20b8044d --- /dev/null +++ b/ash/quick_pair/keyed_service/quick_pair_metrics_logger_unittest.cc
@@ -0,0 +1,342 @@ +// 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 "ash/quick_pair/keyed_service/quick_pair_metrics_logger.h" + +#include <memory> + +#include "ash/quick_pair/common/device.h" +#include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h" +#include "ash/quick_pair/common/logging.h" +#include "ash/quick_pair/common/pair_failure.h" +#include "ash/quick_pair/common/protocol.h" +#include "ash/quick_pair/pairing/mock_pairer_broker.h" +#include "ash/quick_pair/pairing/pairer_broker.h" +#include "ash/quick_pair/scanning/mock_scanner_broker.h" +#include "ash/quick_pair/scanning/scanner_broker.h" +#include "ash/quick_pair/ui/mock_ui_broker.h" +#include "ash/quick_pair/ui/ui_broker.h" +#include "base/memory/scoped_refptr.h" +#include "base/run_loop.h" +#include "base/test/metrics/histogram_tester.h" +#include "base/test/task_environment.h" +#include "base/time/time.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace { + +constexpr char kTestMetadataId[] = "test_metadata_id"; +constexpr char kTestAddress[] = "test_address"; +constexpr char kFastPairEngagementFlowMetric[] = + "Bluetooth.ChromeOS.FastPair.EngagementFunnel.Steps"; + +} // namespace + +namespace ash { +namespace quick_pair { + +class QuickPairMetricsLoggerTest : public testing::Test { + public: + void SetUp() override { + scanner_broker_ = std::make_unique<MockScannerBroker>(); + mock_scanner_broker_ = + static_cast<MockScannerBroker*>(scanner_broker_.get()); + + pairer_broker_ = std::make_unique<MockPairerBroker>(); + mock_pairer_broker_ = static_cast<MockPairerBroker*>(pairer_broker_.get()); + + ui_broker_ = std::make_unique<MockUIBroker>(); + mock_ui_broker_ = static_cast<MockUIBroker*>(ui_broker_.get()); + + device_ = base::MakeRefCounted<Device>(kTestMetadataId, kTestAddress, + Protocol::kFastPair); + + metrics_logger_ = std::make_unique<QuickPairMetricsLogger>( + scanner_broker_.get(), pairer_broker_.get(), ui_broker_.get()); + } + + void SimulateDiscoveryUiShown() { + mock_scanner_broker_->NotifyDeviceFound(device_); + } + + void SimulateDiscoveryUiDismissed() { + mock_ui_broker_->NotifyDiscoveryAction(device_, + DiscoveryAction::kDismissedByUser); + } + + void SimulateDiscoveryUiConnectPressed() { + mock_ui_broker_->NotifyDiscoveryAction(device_, + DiscoveryAction::kPairToDevice); + } + + void SimulatePairingFailed() { + mock_pairer_broker_->NotifyPairFailure( + device_, PairFailure::kKeyBasedPairingCharacteristicDiscovery); + } + + void SimulatePairingSucceeded() { + mock_pairer_broker_->NotifyDevicePaired(device_); + } + + void SimulateErrorUiDismissed() { + mock_ui_broker_->NotifyPairingFailedAction( + device_, PairingFailedAction::kDismissedByUser); + } + + void SimulateErrorUiSettingsPressed() { + mock_ui_broker_->NotifyPairingFailedAction( + device_, PairingFailedAction::kNavigateToSettings); + } + + base::HistogramTester& histogram_tester() { return histogram_tester_; } + + protected: + base::HistogramTester histogram_tester_; + base::test::SingleThreadTaskEnvironment task_environment_; + scoped_refptr<Device> device_; + + MockScannerBroker* mock_scanner_broker_ = nullptr; + MockPairerBroker* mock_pairer_broker_ = nullptr; + MockUIBroker* mock_ui_broker_ = nullptr; + + std::unique_ptr<ScannerBroker> scanner_broker_; + std::unique_ptr<PairerBroker> pairer_broker_; + std::unique_ptr<UIBroker> ui_broker_; + std::unique_ptr<QuickPairMetricsLogger> metrics_logger_; +}; + +TEST_F(QuickPairMetricsLoggerTest, LogDiscoveryUiShown) { + SimulateDiscoveryUiShown(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiShown), + 1); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiConnectPressed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingFailed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingSucceeded), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiSettingsPressed), + 0); +} + +TEST_F(QuickPairMetricsLoggerTest, LogDiscoveryUiDismissed) { + SimulateDiscoveryUiDismissed(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiShown), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiDismissed), + 1); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiConnectPressed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingFailed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingSucceeded), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiSettingsPressed), + 0); +} + +TEST_F(QuickPairMetricsLoggerTest, LogDiscoveryUiConnectPressed) { + SimulateDiscoveryUiConnectPressed(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiShown), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiConnectPressed), + 1); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingFailed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingSucceeded), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiSettingsPressed), + 0); +} + +TEST_F(QuickPairMetricsLoggerTest, LogPairingFailed) { + SimulatePairingFailed(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiShown), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiConnectPressed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingFailed), + 1); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingSucceeded), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiSettingsPressed), + 0); +} + +TEST_F(QuickPairMetricsLoggerTest, LogPairingSucceeded) { + SimulatePairingSucceeded(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiShown), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiConnectPressed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingFailed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingSucceeded), + 1); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiSettingsPressed), + 0); +} + +TEST_F(QuickPairMetricsLoggerTest, LogErrorUiDismissed) { + SimulateErrorUiDismissed(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiShown), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiConnectPressed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingFailed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingSucceeded), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiDismissed), + 1); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiSettingsPressed), + 0); +} + +TEST_F(QuickPairMetricsLoggerTest, LogErrorUiSettingsPressed) { + SimulateErrorUiSettingsPressed(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiShown), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kDiscoveryUiConnectPressed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingFailed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kPairingSucceeded), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiDismissed), + 0); + EXPECT_EQ(histogram_tester().GetBucketCount( + kFastPairEngagementFlowMetric, + FastPairEngagementFlowEvent::kErrorUiSettingsPressed), + 1); +} + +} // namespace quick_pair +} // namespace ash
diff --git a/ash/strings/ash_strings_am.xtb b/ash/strings/ash_strings_am.xtb index 75c6f23..68eb5a26 100644 --- a/ash/strings/ash_strings_am.xtb +++ b/ash/strings/ash_strings_am.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">ትርፍ ፍሰት</translation> <translation id="1346748346194534595">ቀኝ</translation> <translation id="1351937230027495976">ምናሌ ሰብስብ</translation> +<translation id="1364382257761975320">የእርስዎን Chromebook ለመክፈት የጣት አሻራዎን ይጠቀሙ</translation> <translation id="1383597849754832576">የንግግር ፋይሎችን ማውረድ አልተቻለም። ቆይተው እንደገና ይሞክሩ።</translation> <translation id="1383876407941801731">ፍለጋ </translation> <translation id="1391102559483454063">አብራ</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">የስቲለስ ቅንብሮች</translation> <translation id="2354174487190027830"><ph name="NAME" />ን በማግበር ላይ</translation> <translation id="2359808026110333948">ቀጥል</translation> +<translation id="2367186422933365202">ወደ የእርስዎ Chromebook መግባት አልተቻለም</translation> <translation id="2369165858548251131">«Hello» በቻይንኛ</translation> <translation id="2390318262976603432">የቋንቋ ቅንብሮች</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">የሚዲያ መቆጣጠሪያዎች</translation> +<translation id="2402411679569069051">የእርስዎን Chromebook ለመክፈት የጣት አሻራዎን ይጠቀሙ ወይም ስልክዎን ይክፈቱ</translation> <translation id="2405664212338326887">አልተገናኘም</translation> <translation id="2408955596600435184">የእርስዎን ፒን ያስገቡ</translation> <translation id="2412593942846481727">ዝማኔ ይገኛል</translation> @@ -290,6 +293,7 @@ <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="3252248118006571685">የእርስዎን Chromebook ለመክፈት የስልክዎን ብሉቱዝ ያብሩ</translation> <translation id="3255483164551725916">ምን ማድረግ ይችላሉ?</translation> <translation id="3269597722229482060">የቀኝ ጠቅታ</translation> <translation id="3289674678944039601">በአስማሚ በኩል በመሙላት ላይ</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control-Shift-Space</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />፣ <ph name="CONNECTION_STATUS" />፣ የሲግናል ጥንካሬ <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">ብየና</translation> +<translation id="3509391053705095206">የእርስዎን ስልክ ማግኘት አልተቻለም። የእርስዎ ስልክ ብሉቱዝ እንደበራ ያረጋግጡ።</translation> <translation id="3510164367642747937">የመዳፊት ጠቋሚን አድምቅ</translation> <translation id="3513798432020909783">መለያው በ<ph name="MANAGER_EMAIL" /> ነው የሚቀናበረው</translation> <translation id="353086728817903341">ከ<ph name="NUM_DEVICES" /> መሣሪያዎች ጋር ተገናኝቷል</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">የፊት ማይክሮፎን</translation> <translation id="3713734891607377840">ሲጠናቀቅ ይክፈቱ</translation> <translation id="3742055079367172538">ቅጽበታዊ ገጽ እይታ ተነስቷል</translation> +<translation id="3744282433224562605">የእርስዎን Chromebook ለመክፈት የይለፍ ቃል ያስገቡ</translation> <translation id="3771549900096082774">ባለከፍተኛ ንፅፅር ሁነታ</translation> <translation id="3773700760453577392">አንድ አስተዳዳሪ ለ<ph name="USER_EMAIL" /> በበርካታ መለያ መግባቶችን ከልክሏል። ለመቀጠል ሁሉም ተጠቃሚዎች ዘግተው መውጣት አለባቸው።</translation> <translation id="3779139509281456663"><ph name="NAME" /> በማገናኘት ላይ</translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">በቀኝ ጠቅታ ወይም ተጭኖ በመያዝ አማካኝነት ረዳት እርስዎ ምርጫ እንደ ፍቺ፣ ትርጉም ወይም የአሃድ ልወጣ ያለ መረጃን ያሳያል።</translation> <translation id="4505050298327493054">ንቁ ዴስክ።</translation> <translation id="4513946894732546136">ግብረ መልስ</translation> +<translation id="4518404433291145981">የእርስዎን Chromebook ለመክፈት መጀመሪያ ስልክዎን ይክፈቱ</translation> <translation id="4527045527269911712">የብሉቱዝ መሣሪያ «<ph name="DEVICE_NAME" />» ለመጣመር ፍቃድ ይፈልጋል።</translation> <translation id="453661520163887813"><ph name="TIME" /> ሙሉ እስከሚሆን ድረስ</translation> <translation id="4538824937723742295">የሙሉ ማያ ገጽ ቅጽበታዊ ገጽ ዕይታን ያንሱ</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">የተሳሳተ ፒን</translation> <translation id="5083553833479578423">ተጨማሪ የረዳት ባህሪያትን ያስከፍቱ።</translation> <translation id="5136175204352732067">የተለየ የቁልፍ ሰሌዳ ተገናኝቷል</translation> +<translation id="5147567197700016471">ተከፍቷል</translation> <translation id="5155897006997040331">የንባብ ፍጥነት</translation> <translation id="5166918508782100047">የፈጣን መልሶች ቅንብሮች</translation> <translation id="5168181903108465623">የCast መሣሪያዎች ይገኛሉ</translation> <translation id="5170568018924773124">በአቃፊ አሳይ</translation> <translation id="5176318573511391780">ከፊል የማያ ገጽን ቅረጽ</translation> +<translation id="5199367439331364630">ወደ የእርስዎ Chromebook ለመግባት የይለፍ ቃል ያስገቡ</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{1 ሌላ ማሳወቂያ}one{# ሌሎች ማሳወቂያዎች}other{# ሌሎች ማሳወቂያዎች}}</translation> <translation id="5207949376430453814">የጽሑፍ ድፋቱን አድምቅ</translation> <translation id="5208059991603368177">አብራ</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">አዲስ መሣሪያ ያጣምሩ</translation> <translation id="5322611492012084517">የእርስዎን ስልክ ማግኘት አልተቻለም</translation> <translation id="5329548388331921293">በማገናኘት ላይ...</translation> +<translation id="5330201449517439522">ለመግባት መታ ወይም ጠቅ ያድርጉ</translation> <translation id="5331975486040154427">USB-C መሣሪያ (የግራ ጎን ኋላ ወደብ)</translation> <translation id="5352250171825660495">ጠቆር ያለ ገጽታ በርቷል</translation> <translation id="5379115545237091094">በጣም ብዙ ሙከራዎች</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">የተገናኙ መሣሪያዎች ቅንብሮች</translation> <translation id="583281660410589416">ያልታወቀ </translation> <translation id="5837036133683224804"><ph name="RECEIVER_NAME" /> ላይ <ph name="ROUTE_TITLE" />ን አስቁም</translation> +<translation id="584525477304726060">ለማስፋት ይያዙ</translation> <translation id="5860033963881614850">አጥፋ</translation> <translation id="5860491529813859533">አብራ</translation> <translation id="5867217927013474703">የአውታረ መረብ መረጃን በመሰብሰብ ላይ</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">ከስልክዎ መገናኛ ነጥብ ጋር ያገናኙ፣ የመሣሪያዎ ድምጽ ይዝጉትና ያግኙት፣ እና በስልክዎ ላይ የተከፈቱ የቅርብ ጊዜ የChrome ትሮችን ይመልከቱ</translation> <translation id="6670153871843998651">ዴስክ 3</translation> <translation id="6671495933530132209">ምስል ቅዳ</translation> +<translation id="6671661918848783005">የእርስዎን Chromebook መክፈት አልተቻለም</translation> <translation id="6692996468359469499">ከእርስዎ ምርጫ ጋር የተገናኘ መረጃ ያግኙ</translation> <translation id="6696025732084565524">የእርስዎ ተነቃይ የቁልፍ ሰሌዳ ወሳኝ የሆነ ዝማኔ ያስፈልገዋል</translation> <translation id="6700713906295497288">የIME ምናሌ አዝራር</translation>
diff --git a/ash/strings/ash_strings_as.xtb b/ash/strings/ash_strings_as.xtb index 7d93d47e..2045148 100644 --- a/ash/strings/ash_strings_as.xtb +++ b/ash/strings/ash_strings_as.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">অভাৰফ্ল'</translation> <translation id="1346748346194534595">সোঁ</translation> <translation id="1351937230027495976">মেনু সংকোচন কৰক</translation> +<translation id="1364382257761975320">আপোনাৰ Chromebook আনলক কৰিবলৈ, নিজৰ ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক</translation> <translation id="1383597849754832576">কথন ফাইল ডাউনল’ড কৰিব নোৱাৰি। পাছত পুনৰ চেষ্টা কৰক।</translation> <translation id="1383876407941801731">Search</translation> <translation id="1391102559483454063">অন আছে</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">ষ্টাইলাছৰ ছেটিংসমূহ</translation> <translation id="2354174487190027830"><ph name="NAME" /> সক্ৰিয় কৰি থকা হৈছে</translation> <translation id="2359808026110333948">অব্যাহত ৰাখক</translation> +<translation id="2367186422933365202">আপোনাৰ Chromebookত ছাইন ইন কৰিব পৰা নাই</translation> <translation id="2369165858548251131">চীনা ভাষাত "নমস্কাৰ"</translation> <translation id="2390318262976603432">স্থানীয় ভাষাৰ ছেটিংসমূহ</translation> <translation id="2391579633712104609">১৮০°</translation> <translation id="240006516586367791">মিডিয়াৰ নিয়ন্ত্ৰণ</translation> +<translation id="2402411679569069051">আপোনাৰ Chromebook আনলক কৰিবলৈ নিজৰ ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক অথবা আপোনাৰ ফ’নটো আনলক কৰক</translation> <translation id="2405664212338326887">সংযুক্ত হৈ থকা নাই</translation> <translation id="2408955596600435184">আপোনাৰ পিন দিয়ক</translation> <translation id="2412593942846481727">আপডে’ট উপলব্ধ</translation> @@ -290,6 +293,7 @@ <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="3252248118006571685">আপোনাৰ Chromebook আনলক কৰিবলৈ, আপোনাৰ ফ’নটোত ব্লুটুথ অন কৰক</translation> <translation id="3255483164551725916">আপুনি কি কৰিব পাৰে?</translation> <translation id="3269597722229482060">সোঁফালে ক্লিক কৰক</translation> <translation id="3289674678944039601">এডাপ্টৰেৰে চাৰ্জ হৈ আছে</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control-Shift-Space</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, ছিগনেলৰ ক্ষমতা <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">সংজ্ঞা</translation> +<translation id="3509391053705095206">আপোনাৰ ফ’নটো বিচাৰি পোৱা নাই। আপোনাৰ ফ’নৰ ব্লুটুথ অন হৈ থকাটো নিশ্চিত কৰক।</translation> <translation id="3510164367642747937">মাউছৰ কাৰ্ছৰ হাইলাইট কৰক</translation> <translation id="3513798432020909783"><ph name="MANAGER_EMAIL" />এ একাউণ্ট পৰিচালনা কৰে</translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> টা ডিভাইচৰ সৈতে সংযুক্ত হৈ আছে</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">সন্মুখৰ মাইক্ৰ’ফ’ন</translation> <translation id="3713734891607377840">সম্পূৰ্ণ হোৱাৰ পাছত খোলক</translation> <translation id="3742055079367172538">স্ক্ৰীণশ্বট লোৱা হ’ল</translation> +<translation id="3744282433224562605">আপোনাৰ Chromebook আনলক কৰিবলৈ পাছৱৰ্ড দিয়ক</translation> <translation id="3771549900096082774">হাই কনট্ৰাষ্ট ম’ড</translation> <translation id="3773700760453577392">কোনো প্ৰশাসকে <ph name="USER_EMAIL" />ৰ বাবে একাধিক ছাইন ইনৰ সুবিধাটোৰ অনুমতি বাতিল কৰিছে। অব্যাহত ৰাখিবলৈ সকলো ব্যৱহাৰকাৰীয়ে ছাইন আউট কৰিবই লাগিব।</translation> <translation id="3779139509281456663"><ph name="NAME" /> সংযোগ কৰি থকা হৈছে</translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">ৰাইট-ক্লিক কৰিলে অথবা দীঘলীয়াকৈ টিপিলে Assistantএ আপুনি কৰা বাছনিটোৰ সংজ্ঞা, অনুবাদ অথবা একক ৰূপান্তৰণৰ দৰে তথ্য দেখুৱায়।</translation> <translation id="4505050298327493054">সক্ৰিয় ডেস্ক৷</translation> <translation id="4513946894732546136">মতামত</translation> +<translation id="4518404433291145981">আপোনাৰ Chromebook আনলক কৰিবলৈ, প্ৰথমে আপোনাৰ ফ’নটো আনলক কৰক</translation> <translation id="4527045527269911712">ব্লুটুথ ডিভাইচ "<ph name="DEVICE_NAME" />"এ যোৰা লাগিবলৈ অনুমতি বিচাৰে।</translation> <translation id="453661520163887813">সম্পূর্ণ হ'বলৈ <ph name="TIME" /> বাকী</translation> <translation id="4538824937723742295">পূৰ্ণ স্ক্রীনৰ স্ক্ৰীনশ্বট লওক</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">ভুল পিন</translation> <translation id="5083553833479578423">Assistantৰ অন্যান্য সুবিধাসমূহ ব্যৱহাৰ কৰক।</translation> <translation id="5136175204352732067">বিভিন্ন কীব’র্ড সংযোগ কৰা হৈছে</translation> +<translation id="5147567197700016471">আনলক কৰা হ’ল</translation> <translation id="5155897006997040331">পঢ়াৰ গতিবেগ</translation> <translation id="5166918508782100047">দ্ৰুত উত্তৰৰ ছেটিং</translation> <translation id="5168181903108465623">কাষ্ট কৰিব পৰা ডিভাইচ উপলব্ধ</translation> <translation id="5170568018924773124">ফ’ল্ডাৰত দেখুৱাওক</translation> <translation id="5176318573511391780">আংশিক স্ক্ৰীন ৰেকৰ্ড কৰক</translation> +<translation id="5199367439331364630">আপোনাৰ Chromebookত ছাইন ইন কৰিবলৈ পাছৱৰ্ড দিয়ক</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{১ টা অন্য জাননী}one{# টা অন্য জাননী}other{# টা অন্য জাননী}}</translation> <translation id="5207949376430453814">পাঠৰ কেৰেট হাইলাইট কৰক</translation> <translation id="5208059991603368177">অন আছে</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">নতুন ডিভাইচ পেয়াৰ কৰক</translation> <translation id="5322611492012084517">আপোনাৰ ফ’নটো বিচাৰি পোৱা নাই</translation> <translation id="5329548388331921293">সংযোগ কৰি থকা হৈছে…</translation> +<translation id="5330201449517439522">Chromebook ব্যৱহাৰ কৰিবলৈ টিপক অথবা ক্লিক কৰক</translation> <translation id="5331975486040154427">USB-C ডিভাইচ (বাওঁফালৰ বেকপর্টত)</translation> <translation id="5352250171825660495">গাঢ় ৰঙৰ থীম অন হৈ আছে</translation> <translation id="5379115545237091094">অতি বেছি প্ৰয়াস</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">সংযুক্ত হৈ থকা ডিভাইচৰ ছেটিংসমূহ</translation> <translation id="583281660410589416">অজ্ঞাত</translation> <translation id="5837036133683224804"><ph name="RECEIVER_NAME" />ত <ph name="ROUTE_TITLE" /> বন্ধ কৰক</translation> +<translation id="584525477304726060">আকাৰ সৰ্বাধিক কৰিবলৈ টিপি ধৰি থাকক</translation> <translation id="5860033963881614850">অফ আছে</translation> <translation id="5860491529813859533">অন কৰক</translation> <translation id="5867217927013474703">নেটৱৰ্কৰ তথ্য সংগ্ৰহ কৰি থকা হৈছে</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">আপোনাৰ ফ'নৰ হ'টস্প'টৰ সৈতে সংযোগ কৰক, আপোনাৰ ডিভাইচটো নিৰৱ কৰক আৰু সেইটোৰ অৱস্থান নিৰ্ধাৰণ কৰক আৰু আপোনাৰ ফ'নত খোলা শেহতীয়া Chromeৰ টেবসমূহ চাওক</translation> <translation id="6670153871843998651">ডেস্ক ৩</translation> <translation id="6671495933530132209">প্ৰতিচ্ছবি প্ৰতিলিপি কৰক</translation> +<translation id="6671661918848783005">আপোনাৰ Chromebook আনলক কৰিব পৰা নাই</translation> <translation id="6692996468359469499">আপুনি বাছনি সম্পর্কীয় তথ্য পাওক</translation> <translation id="6696025732084565524">আপোনাৰ পৃথক কৰিব পৰা কীব’ৰ্ডত এটা গুৰুত্বপূর্ণ আপডে’ট কৰাৰ প্ৰয়োজন</translation> <translation id="6700713906295497288">IME মেনু বুটাম</translation>
diff --git a/ash/strings/ash_strings_az.xtb b/ash/strings/ash_strings_az.xtb index ee4208e2..4ecb874 100644 --- a/ash/strings/ash_strings_az.xtb +++ b/ash/strings/ash_strings_az.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">Kənara çıxma</translation> <translation id="1346748346194534595">Sağ</translation> <translation id="1351937230027495976">Menyunu yığcamlaşdırın</translation> +<translation id="1364382257761975320">Chromebook'u kiliddən çıxarmaq üçün barmaq izinizi istifadə edin</translation> <translation id="1383597849754832576">Nitq fayllarını endirmək olmur. Sonra yenidən cəhd edin.</translation> <translation id="1383876407941801731">Axtar</translation> <translation id="1391102559483454063">Aktiv</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">Staylus ayarları</translation> <translation id="2354174487190027830"><ph name="NAME" /> aktivləşdirilir</translation> <translation id="2359808026110333948">Davam edin</translation> +<translation id="2367186422933365202">Chromebook'a daxil olmaq olmur</translation> <translation id="2369165858548251131">Çin dilində "Salam"</translation> <translation id="2390318262976603432">Yerli ayarlar</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">Media nizamlayıcıları</translation> +<translation id="2402411679569069051">Chromebook'u kiliddən çıxarmaq üçün barmaq izinizi istifadə edin və ya telefonunuzu kiliddən çıxarın</translation> <translation id="2405664212338326887">Qoşulmayıb</translation> <translation id="2408955596600435184">PİN kodunuzu daxil edin</translation> <translation id="2412593942846481727">Güncəlləmə əlçatandır</translation> @@ -290,6 +293,7 @@ <translation id="3226991577105957773">+<ph name="COUNT" /></translation> <translation id="324366796737464147">Səs-küyün əngəllənməsi</translation> <translation id="3249513730522716925"><ph name="WINDOW_TITLE" /> pəncərəsi <ph name="ACTIVE_DESK" /> Masasından <ph name="TARGET_DESK" /> Masasına köçürüldü</translation> +<translation id="3252248118006571685">Chromebook'u kiliddən çıxarmaq üçün telefonda Bluetooth'u aktiv edin</translation> <translation id="3255483164551725916">Nə edə bilərsiniz?</translation> <translation id="3269597722229482060">Sağ düymə ilə toxunun</translation> <translation id="3289674678944039601">Adapter ilə şarj edilir</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control-Shift-Space</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, Siqnal Gücü <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">təsvir</translation> +<translation id="3509391053705095206">Telefonunuzu tapmaq olmur. Telefonda Bluetooth'un aktiv olduğuna əmin olun.</translation> <translation id="3510164367642747937">Maus kursorunu vurğulayın</translation> <translation id="3513798432020909783"><ph name="MANAGER_EMAIL" /> tərəfindən idarə edilən hesab</translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> cihaza qoşulub</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">Ön mikrofon</translation> <translation id="3713734891607377840">Tamamlandıqda açın</translation> <translation id="3742055079367172538">Skrinşot çəkildi</translation> +<translation id="3744282433224562605">Chromebook'u kiliddən çıxarmaq üçün parolu daxil edin</translation> <translation id="3771549900096082774">Yüksək Kontrast Rejimi</translation> <translation id="3773700760453577392">Administrator <ph name="USER_EMAIL" /> üçün çoxsaylı girişə icazə verməyib. Bütün istifadəçilər davam etmək üçün çıxış etməlidir.</translation> <translation id="3779139509281456663"><ph name="NAME" /> qoşulur</translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">Sağ düymə ilə toxunduqda və ya basıb saxladıqda Assistent seçiminiz üçün izahat, tərcümə və ya vahidin çevrilməsi kimi məlumatı göstərir.</translation> <translation id="4505050298327493054">Aktiv masa.</translation> <translation id="4513946894732546136">Geri əlaqə</translation> +<translation id="4518404433291145981">Chromebook'u kiliddən çıxarmaq üçün əvvəlcə telefonunuzu kiliddən çıxarın</translation> <translation id="4527045527269911712">"<ph name="DEVICE_NAME" />" cihazı cütlənmək üçün icazə istəyir.</translation> <translation id="453661520163887813">dolana qədər <ph name="TIME" /></translation> <translation id="4538824937723742295">Tam ekranın skrinşotunu çəkin</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">Yanlış PIN</translation> <translation id="5083553833479578423">Daha çox Assistent funksiyalarını kiliddən çıxarın.</translation> <translation id="5136175204352732067">Fərqli klaviatura qoşuldu</translation> +<translation id="5147567197700016471">Kiliddən çıxarılmış</translation> <translation id="5155897006997040331">Oxuma sürəti</translation> <translation id="5166918508782100047">Cəld cavab ayarları</translation> <translation id="5168181903108465623">Mövcud Cast cihazlar</translation> <translation id="5170568018924773124">Qovluqda göstərin</translation> <translation id="5176318573511391780">Ekranın bir hissəsini çəkin</translation> +<translation id="5199367439331364630">Chromebook'a daxil olmaq üçün parolu daxil edin</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{Digər 1 bildiriş}other{Digər # bildiriş}}</translation> <translation id="5207949376430453814">Mətn karetini vurğulayın</translation> <translation id="5208059991603368177">Aktiv</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">Yeni cihaz birləşdirin</translation> <translation id="5322611492012084517">Telefonunuzu tapmaq olmur</translation> <translation id="5329548388331921293">Qoşulur…</translation> +<translation id="5330201449517439522">Daxil olmaq üçün toxunun və ya tıklayın</translation> <translation id="5331975486040154427">USB-C cihazı (arxa sol port)</translation> <translation id="5352250171825660495">Tünd tema aktivdir</translation> <translation id="5379115545237091094">Həddindən çox cəhd</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">Qoşulmuş cihazların ayarları</translation> <translation id="583281660410589416">Naməlum</translation> <translation id="5837036133683224804"><ph name="RECEIVER_NAME" /> pəncərəsində <ph name="ROUTE_TITLE" /> dayandırma düyməsi</translation> +<translation id="584525477304726060">Böyütmək üçün toxunub saxlayın</translation> <translation id="5860033963881614850">Deaktiv</translation> <translation id="5860491529813859533">Aktiv edin</translation> <translation id="5867217927013474703">Şəbəkə məlumatları toplanır</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">Telefonunuzun hotspotuna qoşulun, cihazınızı susdurun və tapın və telefonunuzda açılan son Chrome tablarına baxın</translation> <translation id="6670153871843998651">Masa 3</translation> <translation id="6671495933530132209">Şəkli kopyalayın</translation> +<translation id="6671661918848783005">Chromebook'u kiliddən çıxarmaq olmur</translation> <translation id="6692996468359469499">Seçiminizlə bağlı məlumat əldə edin</translation> <translation id="6696025732084565524">Çıxarıla bilən klaviatura mühüm yeniləmə tələb edir</translation> <translation id="6700713906295497288">IME menyu düyməsi</translation>
diff --git a/ash/strings/ash_strings_cs.xtb b/ash/strings/ash_strings_cs.xtb index 71136b8..ec851bc5 100644 --- a/ash/strings/ash_strings_cs.xtb +++ b/ash/strings/ash_strings_cs.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">Přetečení</translation> <translation id="1346748346194534595">Doprava</translation> <translation id="1351937230027495976">Sbalit nabídku</translation> +<translation id="1364382257761975320">Pokud chcete Chromebook odemknout, použijte otisk prstu</translation> <translation id="1383597849754832576">Stažení řečových souborů se nezdařilo. Zkuste to znovu později.</translation> <translation id="1383876407941801731">Vyhledávání</translation> <translation id="1391102559483454063">Zapnuto</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">Nastavení dotykového pera</translation> <translation id="2354174487190027830">Aktivace sítě <ph name="NAME" /></translation> <translation id="2359808026110333948">Pokračovat</translation> +<translation id="2367186422933365202">Přihlášení do Chromebooku se nezdařilo</translation> <translation id="2369165858548251131">„Ahoj“ čínsky</translation> <translation id="2390318262976603432">Nastavení národního prostředí</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">Ovládání médií</translation> +<translation id="2402411679569069051">Pokud chcete Chromebook odemknout, odemkněte telefon pomocí otisku prstu</translation> <translation id="2405664212338326887">Nepřipojeno</translation> <translation id="2408955596600435184">Zadejte PIN</translation> <translation id="2412593942846481727">K dispozici je aktualizace</translation> @@ -290,6 +293,7 @@ <translation id="3226991577105957773">a ještě <ph name="COUNT" /></translation> <translation id="324366796737464147">Potlačení hluku</translation> <translation id="3249513730522716925">Okno <ph name="WINDOW_TITLE" /> bylo přesunuto z plochy <ph name="ACTIVE_DESK" /> na plochu <ph name="TARGET_DESK" /></translation> +<translation id="3252248118006571685">Pokud chcete Chromebook odemknout, zapněte v telefonu Bluetooth</translation> <translation id="3255483164551725916">Co umíš?</translation> <translation id="3269597722229482060">Kliknutí pravým tlačítkem</translation> <translation id="3289674678944039601">Nabíjení pomocí adaptéru</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control + Shift + mezerník</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, síla signálu: <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">definice</translation> +<translation id="3509391053705095206">Telefon se nepodařilo najít. Zkontrolujte, zda je na telefonu zapnutý Bluetooth.</translation> <translation id="3510164367642747937">Zvýraznit ukazatel myši</translation> <translation id="3513798432020909783">Správce účtu: <ph name="MANAGER_EMAIL" /></translation> <translation id="353086728817903341">Připojeno k několika zařízením (<ph name="NUM_DEVICES" />)</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">Přední mikrofon</translation> <translation id="3713734891607377840">Po dokončení otevřít</translation> <translation id="3742055079367172538">Byl vytvořen snímek obrazovky</translation> +<translation id="3744282433224562605">Pokud chcete Chromebook odemknout, zadejte heslo</translation> <translation id="3771549900096082774">Režim vysokého kontrastu</translation> <translation id="3773700760453577392">Administrátor zakázal vícenásobné přihlášení pro účet <ph name="USER_EMAIL" />. Všichni uživatelé se před pokračováním musejí odhlásit.</translation> <translation id="3779139509281456663">Připojování zařízení <ph name="NAME" /></translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">Po kliknutí pravým tlačítkem nebo dlouhém stisknutí vám Asistent zobrazí informace, jako je definice, překlad nebo převod jednotky související s vybraným obsahem.</translation> <translation id="4505050298327493054">Aktivní plocha.</translation> <translation id="4513946894732546136">Zpětná vazba</translation> +<translation id="4518404433291145981">Pokud chcete Chromebook odemknout, nejdřív odemkněte telefon</translation> <translation id="4527045527269911712">Zařízení Bluetooth „<ph name="DEVICE_NAME" />“ žádá o povolení ke spárování.</translation> <translation id="453661520163887813"><ph name="TIME" /> do úplného nabití</translation> <translation id="4538824937723742295">Pořídit snímek celé obrazovky</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">Nesprávný kód PIN</translation> <translation id="5083553833479578423">Odemkněte další funkce Asistenta.</translation> <translation id="5136175204352732067">Je připojena jiná klávesnice</translation> +<translation id="5147567197700016471">Odemknuto</translation> <translation id="5155897006997040331">Rychlost čtení</translation> <translation id="5166918508782100047">Nastavení rychlých odpovědí</translation> <translation id="5168181903108465623">Dostupná zařízení pro streamování obsahu</translation> <translation id="5170568018924773124">Zobrazit ve složce</translation> <translation id="5176318573511391780">Zaznamenat část obrazovky</translation> +<translation id="5199367439331364630">Pokud se chcete přihlásit do Chromebooku, zadejte heslo</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{1 další oznámení}few{# další oznámení}many{# dalšího oznámení}other{# dalších oznámení}}</translation> <translation id="5207949376430453814">Zvýraznit textový kurzor</translation> <translation id="5208059991603368177">Zap</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">Spárovat nové zařízení</translation> <translation id="5322611492012084517">Telefon nebyl nalezen</translation> <translation id="5329548388331921293">Připojování…</translation> +<translation id="5330201449517439522">Pokračujte klepnutím nebo kliknutím</translation> <translation id="5331975486040154427">Zařízení USB Type-C (levý zadní port)</translation> <translation id="5352250171825660495">Tmavý motiv je zapnutý</translation> <translation id="5379115545237091094">Příliš mnoho pokusů</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">Nastavení připojených zařízení</translation> <translation id="583281660410589416">Neznámé</translation> <translation id="5837036133683224804">Zastavit <ph name="ROUTE_TITLE" /> na přijímači <ph name="RECEIVER_NAME" /></translation> +<translation id="584525477304726060">Podržením maximalizujete</translation> <translation id="5860033963881614850">Vypnuto</translation> <translation id="5860491529813859533">Zapnout</translation> <translation id="5867217927013474703">Shromažďování informací o síti</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">Připojení k hotspotu telefonu, ztlumení a nalezení zařízení a zobrazení karet Chromu nedávno otevřených v telefonu</translation> <translation id="6670153871843998651">Plocha 3</translation> <translation id="6671495933530132209">Zkopírovat obrázek</translation> +<translation id="6671661918848783005">Chromebook se nepodařilo odemknout.</translation> <translation id="6692996468359469499">Získejte informace týkající se vybraného obsahu</translation> <translation id="6696025732084565524">Odpojitelná klávesnice vyžaduje kritickou aktualizaci</translation> <translation id="6700713906295497288">Tlačítko nabídky IME</translation>
diff --git a/ash/strings/ash_strings_de.xtb b/ash/strings/ash_strings_de.xtb index 7a06931..c210e05 100644 --- a/ash/strings/ash_strings_de.xtb +++ b/ash/strings/ash_strings_de.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">Überlauf</translation> <translation id="1346748346194534595">Rechts</translation> <translation id="1351937230027495976">Menü minimieren</translation> +<translation id="1364382257761975320">Zum Entsperren des Chromebooks Fingerabdruck verwenden</translation> <translation id="1383597849754832576">Sprachdateien können nicht heruntergeladen werden. Versuch es später noch einmal.</translation> <translation id="1383876407941801731">Durchsuchen</translation> <translation id="1391102559483454063">An</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">Eingabestift-Einstellungen</translation> <translation id="2354174487190027830"><ph name="NAME" /> wird aktiviert</translation> <translation id="2359808026110333948">Weiter</translation> +<translation id="2367186422933365202">Anmeldung auf dem Chromebook nicht möglich</translation> <translation id="2369165858548251131">"Hallo" auf Chinesisch</translation> <translation id="2390318262976603432">Spracheinstellungen</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">Mediensteuerelemente</translation> +<translation id="2402411679569069051">Zum Entsperren des Chromebooks Fingerabdruck verwenden oder Smartphone entsperren</translation> <translation id="2405664212338326887">Nicht verbunden</translation> <translation id="2408955596600435184">PIN eingeben</translation> <translation id="2412593942846481727">Update verfügbar</translation> @@ -290,6 +293,7 @@ <translation id="3226991577105957773">+ <ph name="COUNT" /> weitere</translation> <translation id="324366796737464147">Geräuschunterdrückung</translation> <translation id="3249513730522716925">Das Fenster "<ph name="WINDOW_TITLE" />" wurde von Desktop <ph name="ACTIVE_DESK" /> zu Desktop <ph name="TARGET_DESK" /> verschoben</translation> +<translation id="3252248118006571685">Zum Entsperren des Chromebooks Bluetooth auf Smartphone aktivieren</translation> <translation id="3255483164551725916">Was kannst du alles tun?</translation> <translation id="3269597722229482060">Rechtsklick</translation> <translation id="3289674678944039601">Aufladen über das Netzteil</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Strg + Umschalttaste + Leertaste</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, Signalstärke bei <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">Definition</translation> +<translation id="3509391053705095206">Ihr Smartphone wurde nicht gefunden. Auf Ihrem Smartphone muss Bluetooth aktiviert sein.</translation> <translation id="3510164367642747937">Cursor hervorheben</translation> <translation id="3513798432020909783">Konto verwaltet von <ph name="MANAGER_EMAIL" /></translation> <translation id="353086728817903341">Mit <ph name="NUM_DEVICES" /> Geräten verbunden</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">Mikrofon auf der Vorderseite</translation> <translation id="3713734891607377840">Nach dem Herunterladen öffnen</translation> <translation id="3742055079367172538">Screenshot erstellt</translation> +<translation id="3744282433224562605">Zum Entsperren des Chromebooks Passwort eingeben</translation> <translation id="3771549900096082774">Modus mit hohem Kontrast</translation> <translation id="3773700760453577392">Ein Administrator hat die Mehrfachanmeldung für <ph name="USER_EMAIL" /> deaktiviert. Alle Nutzer müssen sich abmelden, um fortfahren zu können.</translation> <translation id="3779139509281456663">Verbindung mit <ph name="NAME" /> wird hergestellt</translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">Wenn Sie mit der rechten Maustaste klicken oder lange drücken, zeigt Assistant Informationen wie die Definition, Übersetzung oder das Umrechnen von Einheiten für Ihre Auswahl.</translation> <translation id="4505050298327493054">Aktiver Desktop.</translation> <translation id="4513946894732546136">Feedback</translation> +<translation id="4518404433291145981">Zum Entsperren des Chromebooks zuerst Smartphone entsperren</translation> <translation id="4527045527269911712">Das Bluetooth-Gerät "<ph name="DEVICE_NAME" />" bittet um Erlaubnis für Kopplung.</translation> <translation id="453661520163887813">Voll geladen in <ph name="TIME" /> h</translation> <translation id="4538824937723742295">Screenshot vom ganzen Bildschirm machen</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">Falsche PIN</translation> <translation id="5083553833479578423">Möchten Sie weitere Assistant-Funktionen freischalten?</translation> <translation id="5136175204352732067">Andere Tastatur angeschlossen</translation> +<translation id="5147567197700016471">Entsperrt</translation> <translation id="5155897006997040331">Lesegeschwindigkeit</translation> <translation id="5166918508782100047">Einstellungen für die Funktion „Schnellinfo“</translation> <translation id="5168181903108465623">Übertragungsgeräte verfügbar</translation> <translation id="5170568018924773124">In Ordner zeigen</translation> <translation id="5176318573511391780">Teil des Bildschirms aufzeichnen</translation> +<translation id="5199367439331364630">Zum Anmelden auf dem Chromebook Passwort eingeben</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{1 weitere Benachrichtigung}other{# weitere Benachrichtigungen}}</translation> <translation id="5207949376430453814">Textcursor hervorheben</translation> <translation id="5208059991603368177">An</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">Neues Gerät koppeln</translation> <translation id="5322611492012084517">Ihr Smartphone wurde nicht gefunden</translation> <translation id="5329548388331921293">Wird verbunden…</translation> +<translation id="5330201449517439522">Zum Anmelden tippen oder klicken</translation> <translation id="5331975486040154427">USB-C-Gerät (Port hinten links)</translation> <translation id="5352250171825660495">Dunkles Design ist aktiviert</translation> <translation id="5379115545237091094">Zu viele Versuche</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">Einstellungen für verbundene Geräte</translation> <translation id="583281660410589416">Unbekannt</translation> <translation id="5837036133683224804"><ph name="ROUTE_TITLE" /> auf <ph name="RECEIVER_NAME" /> beenden</translation> +<translation id="584525477304726060">Zum Maximieren gedrückt halten</translation> <translation id="5860033963881614850">Aus</translation> <translation id="5860491529813859533">Aktivieren</translation> <translation id="5867217927013474703">Netzwerkinformationen werden erfasst</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">In Phone Hub können Sie sich mit dem Hotspot Ihres Smartphones verbinden, Ihr Gerät stummschalten und suchen und kürzlich auf Ihrem Smartphone geöffnete Chrome-Tabs aufrufen</translation> <translation id="6670153871843998651">Desktop 3</translation> <translation id="6671495933530132209">Bild kopieren</translation> +<translation id="6671661918848783005">Entsperren des Chromebooks nicht möglich</translation> <translation id="6692996468359469499">Informationen zu Ihrer Auswahl erhalten</translation> <translation id="6696025732084565524">Wichtiges Update für Ihre abnehmbare Tastatur</translation> <translation id="6700713906295497288">IME-Menüschaltfläche</translation>
diff --git a/ash/strings/ash_strings_fa.xtb b/ash/strings/ash_strings_fa.xtb index 3a06ff0..a978b0e1 100644 --- a/ash/strings/ash_strings_fa.xtb +++ b/ash/strings/ash_strings_fa.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">سرریز</translation> <translation id="1346748346194534595">راست</translation> <translation id="1351937230027495976">کوچک کردن منو</translation> +<translation id="1364382257761975320">برای باز کردن قفل Chromebook، از اثر انگشتتان استفاده کنید</translation> <translation id="1383597849754832576">نمیتوان فایلهای گفتاری را بارگیری کرد. بعداً دوباره امتحان کنید.</translation> <translation id="1383876407941801731">جستجو</translation> <translation id="1391102559483454063">روشن</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">تنظیمات قلم</translation> <translation id="2354174487190027830">فعالسازی <ph name="NAME" /></translation> <translation id="2359808026110333948">ادامه</translation> +<translation id="2367186422933365202">نمیتوان به سیستم Chromebook وارد شد</translation> <translation id="2369165858548251131">«Hello» in Chinese (سلام به زبان چینی)</translation> <translation id="2390318262976603432">تنظیمات منطقه زبانی</translation> <translation id="2391579633712104609">۱۸۰°</translation> <translation id="240006516586367791">کنترلهای رسانه</translation> +<translation id="2402411679569069051">برای باز کردن قفل Chromebook، از اثر انگشت استفاده کنید یا قفل تلفنتان را باز کنید</translation> <translation id="2405664212338326887">متصل نیست</translation> <translation id="2408955596600435184">پین را وارد کنید</translation> <translation id="2412593942846481727">بهروزرسانی دردسترس است</translation> @@ -290,6 +293,7 @@ <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="3252248118006571685">برای باز کردن قفل Chromebook، بلوتوث تلفنتان را روشن کنید</translation> <translation id="3255483164551725916">What can you do? (چه کاری میتوانی انجام دهی؟)</translation> <translation id="3269597722229482060">کلیک راست</translation> <translation id="3289674678944039601">درحال شارژ ازطریق آداپتور</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control-Shift-Space</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />، <ph name="CONNECTION_STATUS" />، قدرت سیگنال <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">معنی</translation> +<translation id="3509391053705095206">نمیتوان تلفنتان را پیدا کرد. مطمئن شوید بلوتوث تلفن روشن باشد.</translation> <translation id="3510164367642747937">برجسته کردن نشانگر موشواره</translation> <translation id="3513798432020909783">حساب تحت مدیریت <ph name="MANAGER_EMAIL" /> است</translation> <translation id="353086728817903341">به <ph name="NUM_DEVICES" /> دستگاه متصل است</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">میکروفون جلو</translation> <translation id="3713734891607377840">بعداز تکمیل بارگیری باز میشود</translation> <translation id="3742055079367172538">نماگرفت گرفته شد</translation> +<translation id="3744282433224562605">برای باز کردن قفل Chromebook، گذرواژه را وارد کنید</translation> <translation id="3771549900096082774">حالت تضاد بالا</translation> <translation id="3773700760453577392">یکی از سرپرستان ورود چندگانه به سیستم را برای <ph name="USER_EMAIL" /> غیرمجاز کرده است. برای ادامه دادن، همه کاربران باید از سیستم خارج شوند.</translation> <translation id="3779139509281456663">درحال اتصال <ph name="NAME" /></translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">با کلیک راست یا فشار طولانی، «دستیار» اطلاعاتی ازقبیل معنی واژه، ترجمه، یا تبدیل واحد انتخابشده را نمایش میدهد.</translation> <translation id="4505050298327493054">میز فعال.</translation> <translation id="4513946894732546136">بازخورد</translation> +<translation id="4518404433291145981">برای باز کردن قفل Chromebook، ابتدا قفل تلفنتان را باز کنید</translation> <translation id="4527045527269911712">دستگاه بلوتوث «<ph name="DEVICE_NAME" />» برای مرتبطسازی به مجوز نیاز دارد.</translation> <translation id="453661520163887813"><ph name="TIME" /> مانده تا کامل شود</translation> <translation id="4538824937723742295">گرفتن نماگرفت تمامصفحه</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">پین اشتباه</translation> <translation id="5083553833479578423">باز کردن قفل ویژگیهای بیشتری از «دستیار».</translation> <translation id="5136175204352732067">صفحهکلید دیگری متصل شد</translation> +<translation id="5147567197700016471">قفل باز شد</translation> <translation id="5155897006997040331">سرعت خواندن</translation> <translation id="5166918508782100047">تنظیمات پاسخهای سریع</translation> <translation id="5168181903108465623">دستگاههای فرستادن موجود هستند</translation> <translation id="5170568018924773124">نمایش در پوشه</translation> <translation id="5176318573511391780">ضبط کردن نیمصفحه</translation> +<translation id="5199367439331364630">برای ورود به سیستم Chromebook، گذرواژه را وارد کنید</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{۱ اعلان دیگر}one{# اعلان دیگر}other{# اعلان دیگر}}</translation> <translation id="5207949376430453814">برجسته کردن هشتک نوشتار</translation> <translation id="5208059991603368177">روشن</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">مرتبطسازی دستگاه جدید</translation> <translation id="5322611492012084517">نمیتوان تلفنتان را پیدا کرد</translation> <translation id="5329548388331921293">درحال اتصال...</translation> +<translation id="5330201449517439522">برای ورود، ضربه بزنید یا کلیک کنید</translation> <translation id="5331975486040154427">دستگاه USB-C (درگاه عقب سمت چپ)</translation> <translation id="5352250171825660495">طرح زمینه تیره روشن است</translation> <translation id="5379115545237091094">تلاشهای ناموفق زیادی انجام شده است</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">تنظیمات دستگاههای متصل</translation> <translation id="583281660410589416">ناشناس</translation> <translation id="5837036133683224804">توقف <ph name="ROUTE_TITLE" /> به <ph name="RECEIVER_NAME" /></translation> +<translation id="584525477304726060">برای بزرگ کردن، نگه دارید</translation> <translation id="5860033963881614850">خاموش</translation> <translation id="5860491529813859533">روشن کردن</translation> <translation id="5867217927013474703">درحال جمعآوری اطلاعات شبکه</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">به نقطه اتصال تلفنتان وصل شوید، دستگاهتان را بیصدا و موقعیتیابی کنید، و برگههای اخیر Chrome را که در تلفنتان باز هستند مشاهده کنید</translation> <translation id="6670153871843998651">میز ۳</translation> <translation id="6671495933530132209">کپی تصویر</translation> +<translation id="6671661918848783005">قفل Chromebook باز نشد</translation> <translation id="6692996468359469499">دریافت اطلاعاتی که با انتخابتان مرتبط است</translation> <translation id="6696025732084565524">لازم است صفحهکلید قابل جدا شدن بهروزرسانی ضروری شود</translation> <translation id="6700713906295497288">دکمه منو IME</translation>
diff --git a/ash/strings/ash_strings_fr-CA.xtb b/ash/strings/ash_strings_fr-CA.xtb index 710aa83..562eff8b 100644 --- a/ash/strings/ash_strings_fr-CA.xtb +++ b/ash/strings/ash_strings_fr-CA.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">Dépassement</translation> <translation id="1346748346194534595">À droite</translation> <translation id="1351937230027495976">Réduire le menu</translation> +<translation id="1364382257761975320">Utilisez votre empreinte digitale pour déverrouiller votre Chromebook</translation> <translation id="1383597849754832576">Impossible de télécharger les fichiers de synthèse textuelle. Réessayez plus tard.</translation> <translation id="1383876407941801731">Rechercher</translation> <translation id="1391102559483454063">Activé</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">Paramètres du stylet</translation> <translation id="2354174487190027830">Activation du réseau <ph name="NAME" /> en cours…</translation> <translation id="2359808026110333948">Continuer</translation> +<translation id="2367186422933365202">Impossible de se connecter à votre Chromebook</translation> <translation id="2369165858548251131">Comment dit-on « Bonjour » en chinois?</translation> <translation id="2390318262976603432">Paramètres régionaux</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">Commandes multimédias</translation> +<translation id="2402411679569069051">Pour déverrouiller votre Chromebook, utilisez votre empreinte digitale ou déverrouillez votre téléphone</translation> <translation id="2405664212338326887">Fonctionnalité non connectée</translation> <translation id="2408955596600435184">Entrez votre NIP</translation> <translation id="2412593942846481727">Mise à jour disponible</translation> @@ -290,6 +293,7 @@ <translation id="3226991577105957773">et <ph name="COUNT" /> autres</translation> <translation id="324366796737464147">Suppression du bruit</translation> <translation id="3249513730522716925">La fenêtre <ph name="WINDOW_TITLE" /> a passé du bureau <ph name="ACTIVE_DESK" /> au bureau <ph name="TARGET_DESK" /></translation> +<translation id="3252248118006571685">Pour déverrouiller votre Chromebook, activez le Bluetooth sur votre téléphone</translation> <translation id="3255483164551725916">Que peux-tu faire?</translation> <translation id="3269597722229482060">Clic droit</translation> <translation id="3289674678944039601">Recharge par l'adaptateur</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Ctrl + Maj + Espace</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, force du signal : <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">définition</translation> +<translation id="3509391053705095206">Impossible de trouver votre téléphone. Assurez-vous que le Bluetooth est activé sur votre téléphone.</translation> <translation id="3510164367642747937">Mettre le curseur de la souris en surbrillance</translation> <translation id="3513798432020909783">Compte géré par <ph name="MANAGER_EMAIL" /></translation> <translation id="353086728817903341">Connecté à <ph name="NUM_DEVICES" /> appareils</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">Microphone avant</translation> <translation id="3713734891607377840">Ouvrir une fois terminé</translation> <translation id="3742055079367172538">Saisie d'écran enregistrée</translation> +<translation id="3744282433224562605">Pour déverrouiller votre Chromebook, entrez votre mot de passe</translation> <translation id="3771549900096082774">Mode de contraste élevé</translation> <translation id="3773700760453577392">Un administrateur a désactivé la connexion multicompte pour <ph name="USER_EMAIL" />. Tous les utilisateurs doivent se déconnecter pour continuer.</translation> <translation id="3779139509281456663">Connexion à <ph name="NAME" /> en cours…</translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">Si vous effectuez un clic droit ou maintenez un doigt sur l'écran, l'Assistant vous présente de l'information, comme la définition, la traduction ou la conversion d'unités, relative à votre sélection.</translation> <translation id="4505050298327493054">Bureau actif.</translation> <translation id="4513946894732546136">Commentaires</translation> +<translation id="4518404433291145981">Pour déverrouiller votre Chromebook, déverrouillez d'abord votre téléphone</translation> <translation id="4527045527269911712">L'appareil Bluetooth « <ph name="DEVICE_NAME" /> » demande l'autorisation de s'associer.</translation> <translation id="453661520163887813"><ph name="TIME" /> avant la recharge complète</translation> <translation id="4538824937723742295">Prendre une capture de l'écran au complet</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">NIP incorrect</translation> <translation id="5083553833479578423">Déverrouillez davantage de fonctionnalités de l'Assistant Google.</translation> <translation id="5136175204352732067">Autre clavier branché</translation> +<translation id="5147567197700016471">Déverrouillé</translation> <translation id="5155897006997040331">Vitesse de lecture</translation> <translation id="5166918508782100047">Paramètres des réponses rapides</translation> <translation id="5168181903108465623">Appareils de diffusion disponibles</translation> <translation id="5170568018924773124">Afficher dans le dossier</translation> <translation id="5176318573511391780">Enregistrer une partie de l'écran</translation> +<translation id="5199367439331364630">Pour vous connecter à votre Chromebook, entrez votre mot de passe</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{1 autre notification}one{# autre notification}other{# autres notifications}}</translation> <translation id="5207949376430453814">Mettre le point d'insertion de texte en surbrillance</translation> <translation id="5208059991603368177">Activé</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">Associer un appareil</translation> <translation id="5322611492012084517">Impossible de trouver votre téléphone</translation> <translation id="5329548388331921293">Connexion en cours…</translation> +<translation id="5330201449517439522">Touchez l'écran ou cliquez sur celui-ci pour avoir accès</translation> <translation id="5331975486040154427">Appareil USB-C (port arrière-gauche)</translation> <translation id="5352250171825660495">Le thème sombre est activé</translation> <translation id="5379115545237091094">Trop de tentatives</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">Paramètres des appareils connectés</translation> <translation id="583281660410589416">Inconnu</translation> <translation id="5837036133683224804">Arrêter <ph name="ROUTE_TITLE" /> sur <ph name="RECEIVER_NAME" /></translation> +<translation id="584525477304726060">Maintenez le doigt sur la fenêtre pour l'agrandir</translation> <translation id="5860033963881614850">Désactivé</translation> <translation id="5860491529813859533">Activer</translation> <translation id="5867217927013474703">Collecte de renseignements relatifs au réseau en cours…</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">Connectez-vous au point d'accès de votre téléphone, mettez votre appareil en mode silencieux, localisez-le et consultez les onglets récents ouverts dans Chrome sur votre téléphone</translation> <translation id="6670153871843998651">Bureau 3</translation> <translation id="6671495933530132209">Copier l'image</translation> +<translation id="6671661918848783005">Impossible de déverrouiller votre Chromebook</translation> <translation id="6692996468359469499">Obtenir de l'information sur votre sélection</translation> <translation id="6696025732084565524">Votre clavier amovible nécessite une mise à jour critique</translation> <translation id="6700713906295497288">Bouton de menu IME</translation>
diff --git a/ash/strings/ash_strings_gu.xtb b/ash/strings/ash_strings_gu.xtb index 367579f..b5eb53a 100644 --- a/ash/strings/ash_strings_gu.xtb +++ b/ash/strings/ash_strings_gu.xtb
@@ -770,6 +770,7 @@ <translation id="6919251195245069855">તમારું સ્માર્ટ કાર્ડ ઓળખી શક્યાં નથી. ફરી પ્રયાસ કરો.</translation> <translation id="6921188888306725546">કીબોર્ડ શૉર્ટકટને બહેતર બનાવવામાં આવ્યા છે</translation> <translation id="6929655271276551705">તારીખના સેટિંગ</translation> +<translation id="6931576957638141829">આમાં સાચવો</translation> <translation id="6945221475159498467">પસંદ કરો</translation> <translation id="6961121602502368900">ઑફિસની પ્રોફાઇલમાં ફોન સાઇલન્ટ રાખવાની સુવિધા ઉપલબ્ધ નથી</translation> <translation id="6961840794482373852">Alt કી + ઉપરની ઍરો કી કીબોર્ડ શૉર્ટકટ બદલવામાં આવ્યો છે. Page Up કીનો ઉપયોગ કરવા માટે, <ph name="LAUNCHER_KEY_NAME" /> કી + ઉપરની ઍરો કી દબાવો.</translation> @@ -906,6 +907,7 @@ <translation id="79341161159229895"><ph name="FIRST_PARENT_EMAIL" /> અને <ph name="SECOND_PARENT_EMAIL" /> દ્વારા મેનેજ કરાતું એકાઉન્ટ</translation> <translation id="793716872548410480">તમારું ક્લિપબોર્ડ જોવા માટે <ph name="SHORTCUT_KEY_NAME" /> + V દબાવો. તમે કૉપિ કરેલી છેલ્લી 5 આઇટમ તમારા ક્લિપબોર્ડ પર સાચવવામાં આવી છે.</translation> <translation id="7955885781510802139">ઉચ્ચ કોન્ટ્રાસ્ટ મોડ</translation> +<translation id="7968693143708939792">ફોલ્ડર પસંદ કરો...</translation> <translation id="7977927628060636163">મોબાઇલ નેટવર્કની શોધ કરી રહ્યું છે...</translation> <translation id="7980780401175799550">Chrome OS પર નૅવિગેટ કરવાની નવી રીતો અજમાવી જુઓ</translation> <translation id="7982789257301363584">નેટવર્ક</translation>
diff --git a/ash/strings/ash_strings_hy.xtb b/ash/strings/ash_strings_hy.xtb index b61e6106..6120383f 100644 --- a/ash/strings/ash_strings_hy.xtb +++ b/ash/strings/ash_strings_hy.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">Բացել լրացուցիչ ընտրացանկը</translation> <translation id="1346748346194534595">Աջ</translation> <translation id="1351937230027495976">Ծալել ընտրացանկը</translation> +<translation id="1364382257761975320">Ապակողպեք ձեր Chromebook-ը մատնահետքի միջոցով</translation> <translation id="1383597849754832576">Չհաջողվեց ներբեռնել ենթագրերի ֆայլը։ Փորձեք ավելի ուշ։</translation> <translation id="1383876407941801731">Որոնում</translation> <translation id="1391102559483454063">Միացված է</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">Ստիլուսի կարգավորումներ</translation> <translation id="2354174487190027830"><ph name="NAME" />-ի ակտիվացում</translation> <translation id="2359808026110333948">Շարունակել</translation> +<translation id="2367186422933365202">Չհաջողվեց մուտք գործել Chromebook</translation> <translation id="2369165858548251131">Ինչպես չինարեն ասել «Բարև»</translation> <translation id="2390318262976603432">Լեզվի կարգավորումներ</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">Մեդիա կարգավորումներ</translation> +<translation id="2402411679569069051">Ապակողպեք ձեր Chromebook-ը մատնահետքի կամ հեռախոսն ապակողպելու միջոցով</translation> <translation id="2405664212338326887">Միացված չէ</translation> <translation id="2408955596600435184">Մուտքագրեք ձեր PIN կոդը</translation> <translation id="2412593942846481727">Հասանելի է նոր տարբերակը</translation> @@ -290,6 +293,7 @@ <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="3252248118006571685">Ձեր Chromebook-ն ապակողպելու համար միացրեք հեռախոսի Bluetooth-ը</translation> <translation id="3255483164551725916">Ի՞նչ կարող ես անել:</translation> <translation id="3269597722229482060">Աջ սեղմում</translation> <translation id="3289674678944039601">Լիցքավորում ադապտերի միջոցով</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Ctrl+Shift+Բացատ</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, ազդանշանի ուժգնությունը՝ <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">սահմանում</translation> +<translation id="3509391053705095206">Չհաջողվեց գտնել ձեր հեռախոսը։ Համոզվեք, որ հեռախոսի Bluetooth-ը միացված է։</translation> <translation id="3510164367642747937">Ընդգծել մկնիկի նշորդը</translation> <translation id="3513798432020909783">Հաշվի կառավարիչ՝ <ph name="MANAGER_EMAIL" /></translation> <translation id="353086728817903341">Միացված է <ph name="NUM_DEVICES" /> սարքի</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">Առջևի խոսափող</translation> <translation id="3713734891607377840">Բացել ներբեռնելուց հետո</translation> <translation id="3742055079367172538">Սքրինշոթը ստեղծված է</translation> +<translation id="3744282433224562605">Ձեր Chromebook-ն ապակողպելու համար մուտքագրեք գաղտնաբառը</translation> <translation id="3771549900096082774">Բարձր կոնտրաստով ռեժիմ</translation> <translation id="3773700760453577392">Ադմինիստրատորն արգելել է բազմակի մուտքը <ph name="USER_EMAIL" />-ի հաշվի համար: Շարունակելու համար բոլոր օգտատերերը պետք է դուրս գրվեն:</translation> <translation id="3779139509281456663"><ph name="NAME" /> սարքը զուգակցվում է</translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">Օգնականը կցուցադրի տարրի մասին տեղեկություններ, օրինակ՝ սահմանումը, թարգմանությունը կամ փոխարկման միավորը, երբ երկար սեղմեք դրա վրա կամ ուղղակի սեղմեք մկնիկի աջ կոճակով։</translation> <translation id="4505050298327493054">Ակտիվ աշխատանքային սեղան։</translation> <translation id="4513946894732546136">Հետադարձ կապ</translation> +<translation id="4518404433291145981">Ձեր Chromebook-ն ապակողպելու համար նախ ապակողպեք ձեր հեռախոսը</translation> <translation id="4527045527269911712">«<ph name="DEVICE_NAME" />» Bluetooth սարքը զուգավորվելու թույլտվություն է խնդրում:</translation> <translation id="453661520163887813">Լրիվ կլիցքավորվի <ph name="TIME" />-ից</translation> <translation id="4538824937723742295">Լիաէկրան սքրինշոթ անել</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">Սխալ PIN կոդ</translation> <translation id="5083553833479578423">Օգտվեք Օգնականի այլ գործառույթներից</translation> <translation id="5136175204352732067">Այլ ստեղնաշար է միացվել</translation> +<translation id="5147567197700016471">Ապակողպվեց</translation> <translation id="5155897006997040331">Ընթերցման արագությունը</translation> <translation id="5166918508782100047">Արագ պատասխանների կարգավորումներ</translation> <translation id="5168181903108465623">Առկա են հեռարձակման սարքեր</translation> <translation id="5170568018924773124">Ցույց տալ պանակում</translation> <translation id="5176318573511391780">Տեսագրել էկրանի մի մասը</translation> +<translation id="5199367439331364630">Ձեր Chromebook մուտք գործելու համար մուտքագրեք գաղտնաբառը</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{Եվս 1 ծանուցում}one{Եվս # ծանուցում}other{Եվս # ծանուցում}}</translation> <translation id="5207949376430453814">Ընդգծել տեքստի նշորդը</translation> <translation id="5208059991603368177">Միացված է</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">Նոր սարքի զուգակցում</translation> <translation id="5322611492012084517">Չհաջողվեց գտնել ձեր հեռախոսը</translation> <translation id="5329548388331921293">Միանում է…</translation> +<translation id="5330201449517439522">Հպեք կամ սեղմեք՝ մուտքագրելու համար</translation> <translation id="5331975486040154427">USB-C սարք (հետևի ձախակողմյան միացք)</translation> <translation id="5352250171825660495">Մուգ թեման միացված է</translation> <translation id="5379115545237091094">Չափազանց շատ փորձեր</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">Կապված սարքերի կարգավորումներ</translation> <translation id="583281660410589416">Անհայտ</translation> <translation id="5837036133683224804">Դադարեցնել <ph name="ROUTE_TITLE" /> ներդիրի հեռարձակումը «<ph name="RECEIVER_NAME" />» սարքին</translation> +<translation id="584525477304726060">Պահեք՝ մեծացնելու համար</translation> <translation id="5860033963881614850">Անջատ.</translation> <translation id="5860491529813859533">Միացնել</translation> <translation id="5867217927013474703">Ցանցի մասին տեղեկությունների հավաքում</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">Միացեք ձեր հեռախոսի թեժ կետին, անջատեք սարքի ձայնը կամ տեղորոշեք այն, ինչպես նաև դիտեք ձեր հեռախոսում բացված Chrome-ի վերջին ներդիրները</translation> <translation id="6670153871843998651">Աշխատասեղան 3</translation> <translation id="6671495933530132209">Պատճենել պատկերը</translation> +<translation id="6671661918848783005">Չհաջողվեց ապակողպել Chromebook-ը</translation> <translation id="6692996468359469499">Ստացեք տեղեկություններ էկրանի տարրերի վերաբերյալ</translation> <translation id="6696025732084565524">Անհրաժեշտ է թարմացնել արտաքին ստեղնաշարը</translation> <translation id="6700713906295497288">IME ընտրացանկի կոճակ</translation>
diff --git a/ash/strings/ash_strings_iw.xtb b/ash/strings/ash_strings_iw.xtb index f5e4025..0e04703 100644 --- a/ash/strings/ash_strings_iw.xtb +++ b/ash/strings/ash_strings_iw.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">אפשרויות נוספות</translation> <translation id="1346748346194534595">ימינה</translation> <translation id="1351937230027495976">כיווץ התפריט</translation> +<translation id="1364382257761975320">כדי לבטל את נעילת ה-Chromebook, עליך להשתמש בטביעת האצבע שלך</translation> <translation id="1383597849754832576">אין אפשרות להוריד קובצי דיבור. יש לנסות שוב מאוחר יותר.</translation> <translation id="1383876407941801731">חיפוש</translation> <translation id="1391102559483454063">מופעלת</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">הגדרות סטיילוס</translation> <translation id="2354174487190027830">המערכת מפעילה את <ph name="NAME" /></translation> <translation id="2359808026110333948">המשך</translation> +<translation id="2367186422933365202">לא ניתן להיכנס אל ה-Chromebook</translation> <translation id="2369165858548251131">"שלום" בסינית</translation> <translation id="2390318262976603432">הגדרות שילוב של שפה ואזור</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">פקדי מדיה</translation> +<translation id="2402411679569069051">כדי לבטל את נעילת ה-Chromebook, עליך להשתמש בטביעת האצבע או לבטל את נעילת הטלפון שלך</translation> <translation id="2405664212338326887">לא מחובר</translation> <translation id="2408955596600435184">יש להזין את קוד האימות</translation> <translation id="2412593942846481727">יש עדכון זמין</translation> @@ -290,6 +293,7 @@ <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="3252248118006571685">כדי לבטל את נעילת ה-Chromebook, עליך להפעיל את ה-Bluetooth של הטלפון</translation> <translation id="3255483164551725916">מה אפשר לעשות?</translation> <translation id="3269597722229482060">לחיצה ימנית</translation> <translation id="3289674678944039601">מתבצעת טעינה באמצעות מתאם</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control+Shift+מקש הרווח</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, עוצמת האות: <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">הגדרה</translation> +<translation id="3509391053705095206">לא ניתן למצוא את הטלפון. יש לוודא שה-Bluetooth של הטלפון מופעל.</translation> <translation id="3510164367642747937">הדגשה של סמן העכבר</translation> <translation id="3513798432020909783">החשבון מנוהל על-ידי <ph name="MANAGER_EMAIL" /></translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> מכשירים מחוברים</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">מיקרופון קדמי</translation> <translation id="3713734891607377840">פתיחה לאחר השלמת ההורדה</translation> <translation id="3742055079367172538">צילום המסך בוצע</translation> +<translation id="3744282433224562605">כדי לבטל את נעילת ה-Chromebook, עליך להזין סיסמה</translation> <translation id="3771549900096082774">מצב ניגודיות גבוהה</translation> <translation id="3773700760453577392">מנהל מערכת ביטל הרשאה של כניסה עם מספר חשבונות עבור <ph name="USER_EMAIL" />. כדי להמשיך, כל המשתמשים חייבים לבצע יציאה.</translation> <translation id="3779139509281456663">מתבצע חיבור של <ph name="NAME" /></translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">כשלוחצים לחיצה ימנית או לחיצה ארוכה, Assistant מציגה פריט מידע, למשל ההגדרה, התרגום או המרת היחידות של הטקסט שבחרת.</translation> <translation id="4505050298327493054">שולחן עבודה וירטואלי פעיל.</translation> <translation id="4513946894732546136">משוב</translation> +<translation id="4518404433291145981">כדי לבטל את נעילת ה-Chromebook, תחילה צריך לבטל את נעילת הטלפון</translation> <translation id="4527045527269911712">מכשיר ה-Bluetooth "<ph name="DEVICE_NAME" />" מבקש הרשאה לבצע התאמה.</translation> <translation id="453661520163887813"><ph name="TIME" /> עד למילוי</translation> <translation id="4538824937723742295">לצילום מסך מלא</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">PIN שגוי</translation> <translation id="5083553833479578423">אפשר להפעיל תכונות Assistant נוספות.</translation> <translation id="5136175204352732067">חוברה מקלדת אחרת</translation> +<translation id="5147567197700016471">הנעילה בוטלה</translation> <translation id="5155897006997040331">מהירות הקריאה</translation> <translation id="5166918508782100047">ההגדרות של התשובות המהירות</translation> <translation id="5168181903108465623">מכשירי העברה זמינים</translation> <translation id="5170568018924773124">הצגה בתיקייה</translation> <translation id="5176318573511391780">הקלטה של מסך חלקי</translation> +<translation id="5199367439331364630">כדי לבטל את נעילת ה-Chromebook, עליך להזין סיסמה</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{התראה אחת נוספת}two{# התראות נוספות}many{# התראות נוספות}other{# התראות נוספות}}</translation> <translation id="5207949376430453814">הדגשה של סמן הטקסט</translation> <translation id="5208059991603368177">פועל</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">התאמת מכשיר חדש</translation> <translation id="5322611492012084517">לא ניתן למצוא את הטלפון</translation> <translation id="5329548388331921293">מתבצעת התחברות…</translation> +<translation id="5330201449517439522">כדי להיכנס, צריך להקיש או ללחוץ</translation> <translation id="5331975486040154427">מכשיר עם יציאת USB-C (יציאה שמאלית-אחורית)</translation> <translation id="5352250171825660495">עיצוב כהה פועל</translation> <translation id="5379115545237091094">יותר מדי ניסיונות</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">הגדרות של מכשירים מחוברים</translation> <translation id="583281660410589416">לא ידוע</translation> <translation id="5837036133683224804">הפסקת <ph name="ROUTE_TITLE" /> במכשיר <ph name="RECEIVER_NAME" /></translation> +<translation id="584525477304726060">כדי להגדיל, צריך ללחוץ לחיצה ארוכה</translation> <translation id="5860033963881614850">כבוי</translation> <translation id="5860491529813859533">הפעלה</translation> <translation id="5867217927013474703">מתבצע איסוף של פרטי הרשת</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">ניתן להתחבר לנקודה לשיתוף אינטרנט (Hotspot) של הטלפון, להשתיק את המכשיר ולאתר אותו וכן להציג את הכרטיסיות האחרונות שפתוחות בטלפון</translation> <translation id="6670153871843998651">שולחן עבודה 3</translation> <translation id="6671495933530132209">העתקת התמונה</translation> +<translation id="6671661918848783005">אי אפשר לבטל את נעילת ה-Chromebook</translation> <translation id="6692996468359469499">קבלת מידע בקשר לבחירה שלך</translation> <translation id="6696025732084565524">למקלדת הניתנת לניתוק דרוש עדכון קריטי</translation> <translation id="6700713906295497288">לחצן תפריט IME</translation>
diff --git a/ash/strings/ash_strings_ja.xtb b/ash/strings/ash_strings_ja.xtb index 7ea8eb7..d2e1f95 100644 --- a/ash/strings/ash_strings_ja.xtb +++ b/ash/strings/ash_strings_ja.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">オーバーフロー</translation> <translation id="1346748346194534595">右</translation> <translation id="1351937230027495976">メニューを折りたたむ</translation> +<translation id="1364382257761975320">Chromebook のロックを解除するには、指紋認証を使用します</translation> <translation id="1383597849754832576">読み上げファイルをダウンロードできません。しばらくしてからもう一度お試しください。</translation> <translation id="1383876407941801731">検索</translation> <translation id="1391102559483454063">オン</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">タッチペンの設定</translation> <translation id="2354174487190027830"><ph name="NAME" /> を有効にしています</translation> <translation id="2359808026110333948">続行</translation> +<translation id="2367186422933365202">Chromebook にログインできません</translation> <translation id="2369165858548251131">中国語で「こんにちは」ってどう言うの</translation> <translation id="2390318262976603432">言語 / 地域設定</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">メディア コントロール</translation> +<translation id="2402411679569069051">Chromebook のロックを解除するには、指紋認証を使用するか、スマートフォンのロックを解除します</translation> <translation id="2405664212338326887">未接続</translation> <translation id="2408955596600435184">PIN を入力してください</translation> <translation id="2412593942846481727">アップデートが利用可能</translation> @@ -290,6 +293,7 @@ <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="3252248118006571685">Chromebook のロックを解除するには、スマートフォンの Bluetooth をオンにします</translation> <translation id="3255483164551725916">何ができる?</translation> <translation id="3269597722229482060">右クリック</translation> <translation id="3289674678944039601">アダプター経由で充電しています</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control+Shift+Space</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />、<ph name="CONNECTION_STATUS" />、信号強度 <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">定義</translation> +<translation id="3509391053705095206">スマートフォンが見つかりません。スマートフォンの Bluetooth がオンになっていることを確認してください。</translation> <translation id="3510164367642747937">マウスカーソルをハイライト表示する</translation> <translation id="3513798432020909783">このアカウントは <ph name="MANAGER_EMAIL" /> により管理されています</translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> 台のデバイスに接続しています</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">前方のマイク</translation> <translation id="3713734891607377840">完了したら開く</translation> <translation id="3742055079367172538">スクリーンショット撮影完了</translation> +<translation id="3744282433224562605">Chromebook のロックを解除するには、パスワードを入力します</translation> <translation id="3771549900096082774">ハイ コントラスト モード</translation> <translation id="3773700760453577392"><ph name="USER_EMAIL" /> へのマルチログインは、管理者によって禁止されています。続行するには、すべてのユーザーがログアウトする必要があります。</translation> <translation id="3779139509281456663"><ph name="NAME" /> を接続中</translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">右クリックするか長押しすると、選択した項目の情報(定義、翻訳、単位変換など)が表示されます。</translation> <translation id="4505050298327493054">使用中のデスクです。</translation> <translation id="4513946894732546136">フィードバック</translation> +<translation id="4518404433291145981">Chromebook のロックを解除するには、先にスマートフォンのロックを解除します</translation> <translation id="4527045527269911712">Bluetooth デバイス「<ph name="DEVICE_NAME" />」がペア設定の権限をリクエストしています。</translation> <translation id="453661520163887813">あと <ph name="TIME" /> で充電完了</translation> <translation id="4538824937723742295">全画面のスクリーンショットを撮影</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">PIN が正しくありません</translation> <translation id="5083553833479578423">さらに多くのアシスタント機能をぜひご活用ください。</translation> <translation id="5136175204352732067">別のキーボードが接続されています</translation> +<translation id="5147567197700016471">ロック解除済み</translation> <translation id="5155897006997040331">読み上げ速度</translation> <translation id="5166918508782100047">クイック アンサーの設定</translation> <translation id="5168181903108465623">キャスト デバイスを利用できます</translation> <translation id="5170568018924773124">フォルダを開く</translation> <translation id="5176318573511391780">画面の一部を録画</translation> +<translation id="5199367439331364630">Chromebook にログインするには、パスワードを入力します</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{他 1 件の通知}other{他 # 件の通知}}</translation> <translation id="5207949376430453814">テキスト カーソルをハイライト表示する</translation> <translation id="5208059991603368177">オン</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">新しいデバイスとペア設定</translation> <translation id="5322611492012084517">スマートフォンが見つかりません</translation> <translation id="5329548388331921293">接続中…</translation> +<translation id="5330201449517439522">タップまたはクリックで Chromebook を開きます</translation> <translation id="5331975486040154427">USB-C デバイス(左奥のポート)</translation> <translation id="5352250171825660495">ダークモードはオンになっています</translation> <translation id="5379115545237091094">試行回数が上限を超えました</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">接続済みデバイスの設定</translation> <translation id="583281660410589416">不明</translation> <translation id="5837036133683224804"><ph name="RECEIVER_NAME" /> の「<ph name="ROUTE_TITLE" />」を停止します</translation> +<translation id="584525477304726060">長押しして最大化</translation> <translation id="5860033963881614850">オフ</translation> <translation id="5860491529813859533">オンにする</translation> <translation id="5867217927013474703">ネットワーク情報を収集しています</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">スマートフォンのアクセス ポイントに接続することや、スマートフォンをサイレント モードに切り替える、探すなどのほか、スマートフォンで最近使った Chrome タブを表示することができます</translation> <translation id="6670153871843998651">デスク 3</translation> <translation id="6671495933530132209">画像をコピー</translation> +<translation id="6671661918848783005">Chromebook のロックを解除できません</translation> <translation id="6692996468359469499">選択した項目に関連する情報を取得する</translation> <translation id="6696025732084565524">お使いのキーボード(取り外し可能)に重要なアップデートを適用する必要があります</translation> <translation id="6700713906295497288">IME メニューボタン</translation> @@ -770,6 +782,7 @@ <translation id="6919251195245069855">スマートカードを認識できませんでした。もう一度お試しください。</translation> <translation id="6921188888306725546">キーボード ショートカットが改善されました</translation> <translation id="6929655271276551705">日付の設定</translation> +<translation id="6931576957638141829">保存先</translation> <translation id="6945221475159498467">選択</translation> <translation id="6961121602502368900">スマートフォンの消音は仕事用プロファイルでは使用できません</translation> <translation id="6961840794482373852">キーボード ショートカット「Alt+上矢印」が変更されました。PageUp キーを使用するには、<ph name="LAUNCHER_KEY_NAME" />+上矢印キーを押してください。</translation> @@ -907,6 +920,7 @@ <translation id="79341161159229895">このアカウントは <ph name="FIRST_PARENT_EMAIL" /> と <ph name="SECOND_PARENT_EMAIL" /> により管理されています</translation> <translation id="793716872548410480"><ph name="SHORTCUT_KEY_NAME" />+V キーを押すと、クリップボードを表示できます。クリップボードに、コピーした最新のアイテム 5 件が保存されています。</translation> <translation id="7955885781510802139">ハイコントラスト モード</translation> +<translation id="7968693143708939792">フォルダを選択...</translation> <translation id="7977927628060636163">モバイル ネットワークを検索しています...</translation> <translation id="7980780401175799550">Chrome OS の新しい操作方法をお試しください</translation> <translation id="7982789257301363584">ネットワーク</translation>
diff --git a/ash/strings/ash_strings_kk.xtb b/ash/strings/ash_strings_kk.xtb index f703c712..d867149 100644 --- a/ash/strings/ash_strings_kk.xtb +++ b/ash/strings/ash_strings_kk.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">Қосымша мәзір</translation> <translation id="1346748346194534595">Оңға</translation> <translation id="1351937230027495976">Мәзірді жию</translation> +<translation id="1364382257761975320">Chromebook құрылғысының құлпын ашу үшін саусақ ізін пайдаланыңыз.</translation> <translation id="1383597849754832576">Автоматты субтитр файлдары жүктеп алынбады. Кейінірек қайталап көріңіз.</translation> <translation id="1383876407941801731">Іздеу</translation> <translation id="1391102559483454063">Қосулы</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">Стилус параметрлері</translation> <translation id="2354174487190027830"><ph name="NAME" /> белсендіру</translation> <translation id="2359808026110333948">Жалғастыру</translation> +<translation id="2367186422933365202">Chromebook құрылғысына кіру мүмкін емес.</translation> <translation id="2369165858548251131">Қытай тілінде "Сәлем" қалай болады?</translation> <translation id="2390318262976603432">Тіл параметрлері</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">Мультимедианы басқару элементтері</translation> +<translation id="2402411679569069051">Chromebook құрылғысының құлпын ашу үшін саусақ ізін пайдаланыңыз немесе телефоныңыздың құлпын ашыңыз.</translation> <translation id="2405664212338326887">Қосылмаған</translation> <translation id="2408955596600435184">PIN кодын енгізіңіз</translation> <translation id="2412593942846481727">Жаңартылған нұсқа қолжетімді</translation> @@ -290,6 +293,7 @@ <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="3252248118006571685">Chromebook құрылғысының құлпын ашу үшін телефонның Bluetooth функциясын қосыңыз.</translation> <translation id="3255483164551725916">Сен не істей аласың?</translation> <translation id="3269597722229482060">Тінтуірдің оң жақ түймесін басу</translation> <translation id="3289674678944039601">Адаптер арқылы зарядталып жатыр.</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control-Shift-Space</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, сигнал күші: <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">анықтама</translation> +<translation id="3509391053705095206">Телефоныңызды табу мүмкін емес. Телефоныңыздағы Bluetooth қосылып тұрғанына көз жеткізіңіз.</translation> <translation id="3510164367642747937">Тінтуір курсорын бөлектеу</translation> <translation id="3513798432020909783"><ph name="MANAGER_EMAIL" /> басқаратын аккаунт</translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> құрылғыға қосылды.</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">Алдыңғы микрофон</translation> <translation id="3713734891607377840">Жүктеп алынған соң ашу</translation> <translation id="3742055079367172538">Скриншот түсірілді</translation> +<translation id="3744282433224562605">Chromebook құрылғысының құлпын ашу үшін құпия сөзді енгізіңіз.</translation> <translation id="3771549900096082774">Жоғары контраст режимі</translation> <translation id="3773700760453577392">Әкімшінің шешімі бойынша енді <ph name="USER_EMAIL" /> электрондық поштасына бір уақытта бірнеше пайдаланушы кіре алмайды. Жалғастыру үшін пайдаланушылардың барлығы аккаунттан шығуы керек.</translation> <translation id="3779139509281456663"><ph name="NAME" /> құрылғысы қосылуда</translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">Тінтуірдің оң жақ түймесін бассаңыз немесе басып тұрсаңыз, Assistant таңдаған нәрсеңізге қатысты анықтама, аударма немесе бірлікті түрлендіру сияқты ақпаратты көрсетеді.</translation> <translation id="4505050298327493054">Белсенді жұмыс үстелі.</translation> <translation id="4513946894732546136">Пікір жіберу</translation> +<translation id="4518404433291145981">Chromebook құрылғысының құлпын ашу үшін алдымен телефонның құлпын ашыңыз.</translation> <translation id="4527045527269911712">"<ph name="DEVICE_NAME" />" Bluetooth құрылғысы жұптасуға рұқсат сұрайды.</translation> <translation id="453661520163887813">Зарядтау аяқталғанға дейін <ph name="TIME" /> қалды</translation> <translation id="4538824937723742295">Толық экранның скриншотын жасау</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">PIN коды дұрыс емес</translation> <translation id="5083553833479578423">Басқа да Assistant мүмкіндіктерін ашыңыз.</translation> <translation id="5136175204352732067">Басқа пернетақта жалғанды</translation> +<translation id="5147567197700016471">Құлпы ашық</translation> <translation id="5155897006997040331">Оқу жылдамдығы</translation> <translation id="5166918508782100047">Жылдам жауаптар параметрлері</translation> <translation id="5168181903108465623">Трансляциялау құрылғылары қолжетімді</translation> <translation id="5170568018924773124">Қалтада көрсету</translation> <translation id="5176318573511391780">Экранның бір бөлігін жазу</translation> +<translation id="5199367439331364630">Chromebook құрылғысына кіру үшін құпия сөзді енгізіңіз.</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{Тағы 1 хабарландыру}other{Тағы # хабарландыру}}</translation> <translation id="5207949376430453814">Мәтін курсорын бөлектеу</translation> <translation id="5208059991603368177">Қосулы</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">Жаңа құрылғымен жұптау</translation> <translation id="5322611492012084517">Телефоныңызды табу мүмкін емес</translation> <translation id="5329548388331921293">Қосылуда…</translation> +<translation id="5330201449517439522">Кіру үшін түртіңіз не басыңыз.</translation> <translation id="5331975486040154427">USB-C құрылғысы (сол жақ артқы порты)</translation> <translation id="5352250171825660495">Қараңғы тақырып қосулы.</translation> <translation id="5379115545237091094">Тым көп әрекет жасалды</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">Байланыстырылған құрылғылар параметрлері</translation> <translation id="583281660410589416">Белгісіз</translation> <translation id="5837036133683224804"><ph name="RECEIVER_NAME" /> қабылдағышында <ph name="ROUTE_TITLE" /> трансляциясын тоқтату</translation> +<translation id="584525477304726060">Үлкейту үшін басып тұрыңыз.</translation> <translation id="5860033963881614850">Өшірулі</translation> <translation id="5860491529813859533">Қосу</translation> <translation id="5867217927013474703">Желі туралы ақпарат жиналуда</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">Телефоныңыздың хотспотына қосылыңыз, құрылғыңыздың дауысын өшіріп, қай жерде тұрғанын көріңіз, сондай-ақ телефоныңызда соңғы ашылған Chrome қойындыларын көре аласыз.</translation> <translation id="6670153871843998651">3-ші жұмыс үстелі</translation> <translation id="6671495933530132209">Кескінді көшіру</translation> +<translation id="6671661918848783005">Chromebook құрылғысының құлпын ашу мүмкін емес.</translation> <translation id="6692996468359469499">Таңдауға қатысты ақпарат алу</translation> <translation id="6696025732084565524">Алынбалы пернетақтаны жаңарту қажет</translation> <translation id="6700713906295497288">IME мәзір түймесі</translation>
diff --git a/ash/strings/ash_strings_ko.xtb b/ash/strings/ash_strings_ko.xtb index 4e72181..2b565e8b 100644 --- a/ash/strings/ash_strings_ko.xtb +++ b/ash/strings/ash_strings_ko.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">더보기</translation> <translation id="1346748346194534595">오른쪽</translation> <translation id="1351937230027495976">메뉴 접기</translation> +<translation id="1364382257761975320">Chromebook을 잠금 해제하려면 지문을 사용하세요.</translation> <translation id="1383597849754832576">음성 파일을 다운로드할 수 없습니다. 나중에 다시 시도해 보세요.</translation> <translation id="1383876407941801731">검색</translation> <translation id="1391102559483454063">사용</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">스타일러스 설정</translation> <translation id="2354174487190027830"><ph name="NAME" /> 활성화 중</translation> <translation id="2359808026110333948">계속</translation> +<translation id="2367186422933365202">Chromebook에 로그인할 수 없음</translation> <translation id="2369165858548251131">중국어로 '안녕'</translation> <translation id="2390318262976603432">언어 설정</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">미디어 컨트롤</translation> +<translation id="2402411679569069051">Chromebook을 잠금 해제하려면 지문을 사용하거나 휴대전화를 잠금 해제하세요.</translation> <translation id="2405664212338326887">연결되지 않음</translation> <translation id="2408955596600435184">PIN 입력</translation> <translation id="2412593942846481727">업데이트 가능</translation> @@ -290,6 +293,7 @@ <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="3252248118006571685">Chromebook을 잠금 해제하려면 휴대전화의 블루투스를 켜세요.</translation> <translation id="3255483164551725916">무엇을 할 수 있어?</translation> <translation id="3269597722229482060">마우스 오른쪽 버튼 클릭</translation> <translation id="3289674678944039601">어댑터를 통해 충전 중</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control-Shift-Space</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, 신호 강도 <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">정의</translation> +<translation id="3509391053705095206">휴대전화를 찾을 수 없습니다. 휴대전화의 블루투스가 켜져 있는지 확인하세요.</translation> <translation id="3510164367642747937">마우스 커서 강조표시</translation> <translation id="3513798432020909783">계정 관리자: <ph name="MANAGER_EMAIL" /></translation> <translation id="353086728817903341">기기 <ph name="NUM_DEVICES" />대에 연결됨</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">전면 마이크</translation> <translation id="3713734891607377840">완료되면 열기</translation> <translation id="3742055079367172538">찍은 스크린샷</translation> +<translation id="3744282433224562605">Chromebook을 잠금 해제하려면 비밀번호를 입력하세요.</translation> <translation id="3771549900096082774">고대비 모드</translation> <translation id="3773700760453577392">관리자가 <ph name="USER_EMAIL" />의 멀티 로그인을 허용하지 않습니다. 계속하려면 모든 사용자가 로그아웃해야 합니다.</translation> <translation id="3779139509281456663"><ph name="NAME" /> 연결 중</translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">마우스 오른쪽 버튼으로 클릭하거나 길게 누르면 어시스턴트가 선택한 항목의 정의, 번역 또는 단위 변환과 같은 정보를 표시합니다.</translation> <translation id="4505050298327493054">활성 데스크입니다.</translation> <translation id="4513946894732546136">문제 신고</translation> +<translation id="4518404433291145981">Chromebook을 잠금 해제하려면 먼저 휴대전화를 잠금 해제하세요.</translation> <translation id="4527045527269911712">블루투스 기기 '<ph name="DEVICE_NAME" />'에서 페어링 허가를 요청합니다.</translation> <translation id="453661520163887813"><ph name="TIME" /> 후 충전 완료</translation> <translation id="4538824937723742295">화면 전체 스크린샷 촬영</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">잘못된 PIN</translation> <translation id="5083553833479578423">더 많은 어시스턴트 기능을 사용해 보세요.</translation> <translation id="5136175204352732067">다른 키보드 연결됨</translation> +<translation id="5147567197700016471">잠금 해제됨</translation> <translation id="5155897006997040331">읽기 속도</translation> <translation id="5166918508782100047">빠른 답변 설정</translation> <translation id="5168181903108465623">전송 기기를 사용할 수 있음</translation> <translation id="5170568018924773124">폴더 열기</translation> <translation id="5176318573511391780">화면 일부 녹화</translation> +<translation id="5199367439331364630">Chromebook에 로그인하려면 비밀번호를 입력하세요.</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{기타 알림 1개}other{기타 알림 #개}}</translation> <translation id="5207949376430453814">텍스트 캐럿 강조표시</translation> <translation id="5208059991603368177">켜짐</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">새 기기와 페어링</translation> <translation id="5322611492012084517">휴대전화를 찾을 수 없음</translation> <translation id="5329548388331921293">연결 중...</translation> +<translation id="5330201449517439522">탭 또는 클릭하여 입력</translation> <translation id="5331975486040154427">USB-C 기기(좌측 후면 포트)</translation> <translation id="5352250171825660495">어두운 테마가 켜져 있습니다.</translation> <translation id="5379115545237091094">시도 횟수가 너무 많음</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">연결된 기기 설정</translation> <translation id="583281660410589416">알 수 없음</translation> <translation id="5837036133683224804"><ph name="RECEIVER_NAME" />에서 <ph name="ROUTE_TITLE" /> 중지</translation> +<translation id="584525477304726060">눌러서 최대화</translation> <translation id="5860033963881614850">사용 안함</translation> <translation id="5860491529813859533">사용</translation> <translation id="5867217927013474703">네트워크 정보 수집 중</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">휴대전화 핫스팟에 연결하고, 기기를 음소거하고, 기기를 찾고, 휴대전화에서 최근 열었던 Chrome 탭을 확인하세요.</translation> <translation id="6670153871843998651">데스크 3</translation> <translation id="6671495933530132209">이미지 복사</translation> +<translation id="6671661918848783005">Chromebook을 잠금 해제할 수 없음</translation> <translation id="6692996468359469499">선택 항목과 관련된 정보 얻기</translation> <translation id="6696025732084565524">분리식 키보드에 중요 업데이트 필요</translation> <translation id="6700713906295497288">IME 메뉴 버튼</translation>
diff --git a/ash/strings/ash_strings_sq.xtb b/ash/strings/ash_strings_sq.xtb index 1583e00..12cc97bb 100644 --- a/ash/strings/ash_strings_sq.xtb +++ b/ash/strings/ash_strings_sq.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">Tejkalo</translation> <translation id="1346748346194534595">Djathtas</translation> <translation id="1351937230027495976">Palos menynë</translation> +<translation id="1364382257761975320">Për të shkyçur Chromebook-un tënd, përdor gjurmën e gishtit</translation> <translation id="1383597849754832576">Skedarët e ligjërimit nuk mund të shkarkohen. Provo përsëri më vonë.</translation> <translation id="1383876407941801731">Kërko</translation> <translation id="1391102559483454063">Aktiv</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">Cilësimet e stilolapsit</translation> <translation id="2354174487190027830">Po aktivizon <ph name="NAME" /></translation> <translation id="2359808026110333948">Vazhdo</translation> +<translation id="2367186422933365202">Nuk mund të identifikohesh në Chromebook-un tënd</translation> <translation id="2369165858548251131">"Përshëndetje" në kinezisht</translation> <translation id="2390318262976603432">Cilësimet rajonale</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">Kontrollet e medias</translation> +<translation id="2402411679569069051">Për të shkyçur Chromebook-un tënd, përdor gjurmën e gishtit ose shkyç telefonin</translation> <translation id="2405664212338326887">Nuk është i lidhur</translation> <translation id="2408955596600435184">Fut kodin PIN</translation> <translation id="2412593942846481727">Ka përditësim</translation> @@ -290,6 +293,7 @@ <translation id="3226991577105957773">+<ph name="COUNT" /> më shumë</translation> <translation id="324366796737464147">Anulimi i zhurmës</translation> <translation id="3249513730522716925">Dritarja <ph name="WINDOW_TITLE" /> u zhvendos nga tavolina e punës <ph name="ACTIVE_DESK" /> në tavolinën e punës <ph name="TARGET_DESK" /></translation> +<translation id="3252248118006571685">Për të shkyçur Chromebook-un tënd, aktivizo Bluetooth-in e telefonit</translation> <translation id="3255483164551725916">Çfarë mund të bësh?</translation> <translation id="3269597722229482060">Kliko me butonin djathtas</translation> <translation id="3289674678944039601">Po karikohet përmes përshtatësit</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control-Shift-Hapësirë</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, fuqia e sinjalit <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">përkufizimi</translation> +<translation id="3509391053705095206">Telefoni yt nuk mund të gjendet. Sigurohu që të jetë aktivizuar Bluetooth-i i telefonit tënd.</translation> <translation id="3510164367642747937">Thekso kursorin e miut</translation> <translation id="3513798432020909783">Llogaria menaxhohet nga <ph name="MANAGER_EMAIL" /></translation> <translation id="353086728817903341">U lidh me <ph name="NUM_DEVICES" /> pajisje</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">Mikrofoni i përparmë</translation> <translation id="3713734891607377840">Hape kur të përfundojë</translation> <translation id="3742055079367172538">Pamja e ekranit u mor</translation> +<translation id="3744282433224562605">Për të shkyçur Chromebook-un tënd, fut fjalëkalimin</translation> <translation id="3771549900096082774">Modaliteti i kontrastit të lartë</translation> <translation id="3773700760453577392">Një administrator ka ndaluar identifikimin e shumëfishtë për <ph name="USER_EMAIL" />. Të gjithë përdoruesit duhet të dalin për të vazhduar.</translation> <translation id="3779139509281456663"><ph name="NAME" /> po lidhet</translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">Me një klikim me butonin djathtas ose shtypje të gjatë, "Asistenti" shfaq informacione si p.sh. përkufizimi, përkthimi ose konvertimi i njësisë për zgjedhjen tënde.</translation> <translation id="4505050298327493054">Hapësira e punës aktive.</translation> <translation id="4513946894732546136">Komente</translation> +<translation id="4518404433291145981">Për të shkyçur Chromebook-un tënd, shkyç fillimisht telefonin</translation> <translation id="4527045527269911712">Pajisja me Bluetooth "<ph name="DEVICE_NAME" />" kërkon leje për çiftim.</translation> <translation id="453661520163887813"><ph name="TIME" /> derisa të mbushet</translation> <translation id="4538824937723742295">Shkrep një pamje ekrani të plotë</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">Kod i pasaktë PIN</translation> <translation id="5083553833479578423">Shkyç më shumë funksione të "Asistentit".</translation> <translation id="5136175204352732067">Është lidhur një tastierë tjetër</translation> +<translation id="5147567197700016471">Shkyçur</translation> <translation id="5155897006997040331">Shpejtësia e leximit</translation> <translation id="5166918508782100047">Cilësimet e "Përgjigjeve të shpejta"</translation> <translation id="5168181903108465623">Pajisjet e transmetimit janë të disponueshme</translation> <translation id="5170568018924773124">Shfaq në dosje</translation> <translation id="5176318573511391780">Regjistro ekranin e pjesshëm</translation> +<translation id="5199367439331364630">Për t'u identifikuar në Chromebook-un tënd, fut fjalëkalimin</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{1 njoftim tjetër}other{# njoftime të tjera}}</translation> <translation id="5207949376430453814">Thekso kursorin e tekstit</translation> <translation id="5208059991603368177">Aktive</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">Çifto pajisjen e re</translation> <translation id="5322611492012084517">Telefoni yt nuk mund të gjendet</translation> <translation id="5329548388331921293">Po lidhet...</translation> +<translation id="5330201449517439522">Trokit ose kliko për të hyrë</translation> <translation id="5331975486040154427">Pajisja USB-C (porta e pasme, majtas)</translation> <translation id="5352250171825660495">"Tema e errët" është aktive</translation> <translation id="5379115545237091094">Shumë përpjekje</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">Cilësimet e pajisjeve të lidhura</translation> <translation id="583281660410589416">E panjohur</translation> <translation id="5837036133683224804">Ndalo <ph name="ROUTE_TITLE" /> në <ph name="RECEIVER_NAME" /></translation> +<translation id="584525477304726060">Mbaj për të maksimizuar</translation> <translation id="5860033963881614850">Çaktivizuar</translation> <translation id="5860491529813859533">Aktivizo</translation> <translation id="5867217927013474703">Po mblidhet informacioni i rrjetit</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">Lidhu me zonën e qasjes për internet të telefonit tënd, vendos në heshtje dhe lokalizo pajisjen tënde, si dhe shiko skedat e fundit të Chrome të hapura në telefonin tënd</translation> <translation id="6670153871843998651">Tavolina e punës 3</translation> <translation id="6671495933530132209">Kopjo imazhin</translation> +<translation id="6671661918848783005">Nuk mund të shkyçet Chromebook-u yt</translation> <translation id="6692996468359469499">Merr informacion në lidhje me përzgjedhjen tënde</translation> <translation id="6696025732084565524">Tastiera jote e shkëputshme ka nevojë për një përditësim me rëndësi</translation> <translation id="6700713906295497288">Butoni i menysë IME</translation>
diff --git a/ash/strings/ash_strings_sw.xtb b/ash/strings/ash_strings_sw.xtb index cd687e1f..bea1c58 100644 --- a/ash/strings/ash_strings_sw.xtb +++ b/ash/strings/ash_strings_sw.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">Menyu ya vipengee vya ziada</translation> <translation id="1346748346194534595">Kulia</translation> <translation id="1351937230027495976">Kunja menyu</translation> +<translation id="1364382257761975320">Ili ufungue Chromebook yako, tumia alama yako ya kidole</translation> <translation id="1383597849754832576">Imeshindwa kupakua faili za matamshi. Jaribu tena baadaye.</translation> <translation id="1383876407941801731">Tafuta</translation> <translation id="1391102559483454063">Umewashwa</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">Mipangilio ya stylus</translation> <translation id="2354174487190027830">Inaanza kutumia <ph name="NAME" /></translation> <translation id="2359808026110333948">Endelea</translation> +<translation id="2367186422933365202">Imeshindwa kuingia katika akaunti kwenye Chromebook yako</translation> <translation id="2369165858548251131">"Hujambo" kwa Kichina</translation> <translation id="2390318262976603432">Mipangilio ya Lugha</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">Vidhibiti vya maudhui</translation> +<translation id="2402411679569069051">Ili ufungue Chromebook yako, tumia alama yako ya kidole au ufungue simu yako</translation> <translation id="2405664212338326887">Haijaunganishwa</translation> <translation id="2408955596600435184">Weka PIN yako</translation> <translation id="2412593942846481727">Sasisho linapatikana</translation> @@ -290,6 +293,7 @@ <translation id="3226991577105957773">+<ph name="COUNT" /> zaidi</translation> <translation id="324366796737464147">Udhibiti wa kelele</translation> <translation id="3249513730522716925">Dirisha la <ph name="WINDOW_TITLE" /> limehamishwa kutoka Kiolesura cha <ph name="ACTIVE_DESK" /> hadi Kiolesura cha <ph name="TARGET_DESK" /></translation> +<translation id="3252248118006571685">Ili ufungue Chromebook yako, washa Bluetooth kwenye simu yako</translation> <translation id="3255483164551725916">Unaweza kufanya nini?</translation> <translation id="3269597722229482060">Bofya Kulia</translation> <translation id="3289674678944039601">Inachaji kupitia adapta</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control-Shift-Space</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, Uthabiti wa Mtandao <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">ufafanuzi</translation> +<translation id="3509391053705095206">Imeshindwa kupata simu yako. Hakikisha kwamba umewasha Bluetooth ya simu yako.</translation> <translation id="3510164367642747937">Angazia kiteuzi cha kipanya</translation> <translation id="3513798432020909783">Akaunti inasimamiwa na <ph name="MANAGER_EMAIL" /></translation> <translation id="353086728817903341">Imeunganishwa kwenye vifaa <ph name="NUM_DEVICES" /></translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">Maikrofoni ya mbele</translation> <translation id="3713734891607377840">Ifungue ikimaliza kupakuliwa</translation> <translation id="3742055079367172538">Picha ya skrini imepigwa</translation> +<translation id="3744282433224562605">Ili ufungue Chromebook yako, weka nenosiri</translation> <translation id="3771549900096082774">Hali ya Juu ya Utofautishaji</translation> <translation id="3773700760453577392">Msimamizi ameondoa uwezo wa <ph name="USER_EMAIL" /> wa kuingia katika akaunti nyingi kwa wakati mmoja. Watumiaji wote lazima waondoke katika akaunti ili waendelee.</translation> <translation id="3779139509281456663">Inaunganisha <ph name="NAME" /></translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">Ukibofya kulia au ukibonyeza kwa muda mrefu, programu ya Mratibu itaonyesha maelezo kama vile ufafanuzi, ubadilishaji wa vipimo au tafsiri ya chaguo lako.</translation> <translation id="4505050298327493054">Eneokazi linalotumika.</translation> <translation id="4513946894732546136">Mwitiko</translation> +<translation id="4518404433291145981">Ili ufungue Chromebook yako, fungua simu yako kwanza</translation> <translation id="4527045527269911712">Kifaa cha Bluetooth cha "<ph name="DEVICE_NAME" />" kinaomba idhini ya kuoanisha.</translation> <translation id="453661520163887813">Zimesalia <ph name="TIME" /> ili ijae</translation> <translation id="4538824937723742295">Piga picha ya skrini nzima</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">PIN isiyo sahihi</translation> <translation id="5083553833479578423">Fungua vipengele zaidi vya programu yako ya Mratibu.</translation> <translation id="5136175204352732067">Kibodi tofauti imeunganishwa</translation> +<translation id="5147567197700016471">Imefunguliwa</translation> <translation id="5155897006997040331">Kasi ya kusoma</translation> <translation id="5166918508782100047">Mipangilio ya majibu ya haraka</translation> <translation id="5168181903108465623">Vifaa vinavyorusha maudhui vinapatikana</translation> <translation id="5170568018924773124">Onyesha katika folda</translation> <translation id="5176318573511391780">Rekodi sehemu ya skrini</translation> +<translation id="5199367439331364630">Ili uingie katika akaunti kwenye Chromebook yako, weka nenosiri</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{Arifa nyingine moja}other{Arifa zingine #}}</translation> <translation id="5207949376430453814">Angazia kareti ya maandishi</translation> <translation id="5208059991603368177">Yamewashwa</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">Oanisha kifaa kipya</translation> <translation id="5322611492012084517">Imeshindwa kupata simu yako</translation> <translation id="5329548388331921293">Inaunganisha...</translation> +<translation id="5330201449517439522">Gusa au ubofye ili uingie</translation> <translation id="5331975486040154427">Kifaa cha USB-C (mlango wa upande wa kushoto nyuma)</translation> <translation id="5352250171825660495">Mandhari meusi yamewashwa</translation> <translation id="5379115545237091094">Umejaribu mara nyingi mno</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">Mipangilio ya vifaa vilivyounganishwa</translation> <translation id="583281660410589416">Haijulikani</translation> <translation id="5837036133683224804">Komesha <ph name="ROUTE_TITLE" /> kwenye <ph name="RECEIVER_NAME" /></translation> +<translation id="584525477304726060">Shikilia ili upanue dirisha</translation> <translation id="5860033963881614850">Kimezimwa</translation> <translation id="5860491529813859533">Washa</translation> <translation id="5867217927013474703">Inakusanya maelezo ya mtandao</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">Unganisha kwenye mtandao pepe wa simu yako, zima sauti ya kifaa chako na ujue kilipo na uangalie vichupo vya Chrome vilivyofunguliwa kwenye simu yako</translation> <translation id="6670153871843998651">Eneokazi la 3</translation> <translation id="6671495933530132209">Nakili picha</translation> +<translation id="6671661918848783005">Imeshindwa kufungua Chromebook yako</translation> <translation id="6692996468359469499">Pata maelezo yanayohusiana na chaguo lako</translation> <translation id="6696025732084565524">Kibodi unayoweza kutenganisha inahitaji sasisho muhimu</translation> <translation id="6700713906295497288">Kitufe cha menyu ya IME</translation>
diff --git a/ash/strings/ash_strings_ta.xtb b/ash/strings/ash_strings_ta.xtb index 73e6ace..661e328 100644 --- a/ash/strings/ash_strings_ta.xtb +++ b/ash/strings/ash_strings_ta.xtb
@@ -770,6 +770,7 @@ <translation id="6919251195245069855">உங்கள் ஸ்மார்ட் கார்டை அடையாளம் காண முடியவில்லை. மீண்டும் முயலவும்.</translation> <translation id="6921188888306725546">கீபோர்டு ஷார்ட்கட்கள் மேம்படுத்தப்பட்டுள்ளன</translation> <translation id="6929655271276551705">தேதி அமைப்புகள்</translation> +<translation id="6931576957638141829">இதில் சேமி</translation> <translation id="6945221475159498467">தேர்ந்தெடு</translation> <translation id="6961121602502368900">பணிக் கணக்கின் மூலம், மொபைலை நிசப்தமாக்குதல் அம்சத்தைப் பயன்படுத்த முடியாது</translation> <translation id="6961840794482373852">இந்தக் கீபோர்டு ஷார்ட்கட் மாற்றப்பட்டுள்ளது: Alt + மேல்நோக்கிய அம்புக்குறி. Page Up பட்டனைப் பயன்படுத்த, <ph name="LAUNCHER_KEY_NAME" /> பட்டன் + மேல்நோக்கிய அம்புக்குறி பட்டனை அழுத்தவும்.</translation> @@ -906,6 +907,7 @@ <translation id="79341161159229895">கணக்கை நிர்வகிப்பது: <ph name="FIRST_PARENT_EMAIL" /> மற்றும் <ph name="SECOND_PARENT_EMAIL" /></translation> <translation id="793716872548410480">கிளிப்போர்டைப் பார்க்க, <ph name="SHORTCUT_KEY_NAME" /> + V ஆகிய விசைகளைச் சேர்த்து அழுத்தவும். நீங்கள் நகலெடுத்த கடைசி 5 உள்ளடக்கம் கிளிப்போர்டில் சேமிக்கப்பட்டிருக்கும்.</translation> <translation id="7955885781510802139">அதிக ஒளி மாறுபாட்டுப் பயன்முறை</translation> +<translation id="7968693143708939792">ஃபோல்டரைத் தேர்ந்தெடு...</translation> <translation id="7977927628060636163">மொபைல் நெட்வொர்க்குகளைத் தேடுகிறது...</translation> <translation id="7980780401175799550">Chrome OSஸை வழிசெலுத்த புதிய வழிகளைப் பயன்படுத்திப் பாருங்கள்</translation> <translation id="7982789257301363584">நெட்வொர்க்</translation>
diff --git a/ash/strings/ash_strings_te.xtb b/ash/strings/ash_strings_te.xtb index 61564e0..10e58be6 100644 --- a/ash/strings/ash_strings_te.xtb +++ b/ash/strings/ash_strings_te.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">అతివ్యాప్తి అంశాలు</translation> <translation id="1346748346194534595">కుడి</translation> <translation id="1351937230027495976">మెనూను కుదించు</translation> +<translation id="1364382257761975320">మీ Chromebookను అన్లాక్ చేయడానికి, మీ వేలిముద్రను ఉపయోగించండి</translation> <translation id="1383597849754832576">స్పీచ్ ఫైళ్లను డౌన్లోడ్ చేయడం సాధ్యం కాదు. తర్వాత మళ్లీ ట్రై చేయండి.</translation> <translation id="1383876407941801731">సెర్చ్</translation> <translation id="1391102559483454063">ఆన్</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">స్టైలస్ సెట్టింగ్లు</translation> <translation id="2354174487190027830"><ph name="NAME" />ని సక్రియం చేస్తోంది</translation> <translation id="2359808026110333948">కొనసాగించు</translation> +<translation id="2367186422933365202">మీ Chromebookకు సైన్ ఇన్ చేయడం సాధ్యపడలేదు</translation> <translation id="2369165858548251131">చైనీస్లో "హలో"</translation> <translation id="2390318262976603432">లొకేల్ సెట్టింగ్లు</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">మీడియా నియంత్రణలు</translation> +<translation id="2402411679569069051">మీ Chromebookను అన్లాక్ చేయడానికి, మీ వేలిముద్రను ఉపయోగించండి లేదా మీ ఫోన్ను అన్లాక్ చేయండి</translation> <translation id="2405664212338326887">కనెక్ట్ చేయబడలేదు</translation> <translation id="2408955596600435184">మీ PINని నమోదు చేయండి</translation> <translation id="2412593942846481727">అప్డేట్ అందుబాటులో ఉంది</translation> @@ -290,6 +293,7 @@ <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="3252248118006571685">మీ Chromebookను అన్లాక్ చేయడానికి, మీ ఫోన్ బ్లూటూత్ను ఆన్ చేయండి</translation> <translation id="3255483164551725916">నువ్వు ఏమి చేయగలవు?</translation> <translation id="3269597722229482060">కుడి క్లిక్</translation> <translation id="3289674678944039601">అడాప్టర్ ద్వారా ఛార్జ్ అవుతోంది</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control-Shift-Space</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, సిగ్నల్ సామర్థ్యం <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">నిర్వచనం</translation> +<translation id="3509391053705095206">మీ ఫోన్ను కనుగొనడం సాధ్యపడలేదు. మీ ఫోన్లో బ్లూటూత్ ఆన్లో ఉందని నిర్ధారించుకోండి.</translation> <translation id="3510164367642747937">మౌస్ కర్సర్ను హైలైట్ చేయి</translation> <translation id="3513798432020909783"><ph name="MANAGER_EMAIL" /> ద్వారా ఖాతా నిర్వహించబడుతోంది</translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> పరికరాలకు కనెక్ట్ చేయబడింది</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">ముందువైపు మైక్రోఫోన్</translation> <translation id="3713734891607377840">పూర్తయినప్పుడు తెరవండి</translation> <translation id="3742055079367172538">స్క్రీన్షాట్ తీసినప్పుడు</translation> +<translation id="3744282433224562605">మీ Chromebookను అన్లాక్ చేయడానికి, పాస్వర్డ్ను ఎంటర్ చేయండి</translation> <translation id="3771549900096082774">అధిక కాంట్రాస్ట్ మోడ్</translation> <translation id="3773700760453577392"><ph name="USER_EMAIL" /> కోసం బహుళ సైన్-ఇన్ అనుమతిని నిర్వాహకుడు తిరస్కరించారు. కొనసాగడానికి వినియోగదారులందరూ తప్పనిసరిగా సైన్ అవుట్ చేయాలి.</translation> @@ -469,6 +475,7 @@ <translation id="4485060137115666462">కుడి క్లిక్ ద్వారా లేదా ఎక్కువసేపు నొక్కి, ఉంచడం ద్వారా, మీ ఎంపిక కోసం నిర్వచనం, అనువాదం లేదా యూనిట్ మార్పిడి లాంటి సమాచారాన్ని Assistant చూపుతుంది.</translation> <translation id="4505050298327493054">యాక్టివ్ డెస్క్.</translation> <translation id="4513946894732546136">ఫీడ్బ్యాక్</translation> +<translation id="4518404433291145981">మీ Chromebookను అన్లాక్ చేయడానికి, ముందుగా మీ ఫోన్ను అన్లాక్ చేయండి</translation> <translation id="4527045527269911712">బ్లూటూత్ పరికరం "<ph name="DEVICE_NAME" />" జత కావడానికి అనుమతి కోరుతోంది.</translation> <translation id="453661520163887813">పూర్తి కావడానికి <ph name="TIME" /> పడుతుంది</translation> <translation id="4538824937723742295">ఫుల్ స్క్రీన్ స్క్రీన్షాట్ను తీయండి</translation> @@ -552,11 +559,13 @@ <translation id="5078796286268621944"> సరి కానటువంటి PIN</translation> <translation id="5083553833479578423">మరిన్ని Assistant ఫీచర్లను అన్లాక్ చేయండి.</translation> <translation id="5136175204352732067">వేరే కీబోర్డ్ కనెక్ట్ చేయబడింది</translation> +<translation id="5147567197700016471">అన్లాక్ చేయబడింది</translation> <translation id="5155897006997040331">రీడింగ్ వేగం</translation> <translation id="5166918508782100047">క్విక్ ఆన్సర్స్కు సంబంధించిన సెట్టింగ్లు</translation> <translation id="5168181903108465623">Cast పరికరాలు అందుబాటులో ఉన్నాయి</translation> <translation id="5170568018924773124">ఫోల్డర్లో చూపించు</translation> <translation id="5176318573511391780">పాక్షిక స్క్రీన్ను రికార్డ్ చేయండి</translation> +<translation id="5199367439331364630">మీ Chromebookకు సైన్ ఇన్ చేయడానికి, పాస్వర్డ్ను ఎంటర్ చేయండి</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{మరో 1 నోటిఫికేషన్}other{మరో # నోటిఫికేషన్లు}}</translation> <translation id="5207949376430453814">వచన కర్సర్ గుర్తును హైలైట్ చేయి</translation> <translation id="5208059991603368177">ఆన్ చేయి</translation> @@ -577,6 +586,7 @@ <translation id="5319712128756744240">కొత్త పరికరాన్ని పెయిర్ చేయండి</translation> <translation id="5322611492012084517">మీ ఫోన్ను కనుగొనడం సాధ్యపడలేదు</translation> <translation id="5329548388331921293">కనెక్ట్ అవుతోంది...</translation> +<translation id="5330201449517439522">Chromebookకు వెళ్లడానికి ట్యాప్ చేయండి లేదా క్లిక్ చేయండి</translation> <translation id="5331975486040154427">USB-C పరికరం (ఎడమవైపు వెనుక పోర్ట్)</translation> <translation id="5352250171825660495">ముదురు రంగు రూపం ఆన్లో ఉంది</translation> <translation id="5379115545237091094">అనేకసార్లు ప్రయత్నించారు</translation> @@ -634,6 +644,7 @@ <translation id="5825969630400862129">కనెక్ట్ చేయబడిన పరికరాల సెట్టింగ్లు</translation> <translation id="583281660410589416">తెలియని</translation> <translation id="5837036133683224804"><ph name="RECEIVER_NAME" />లో <ph name="ROUTE_TITLE" /> ఆపివేయి</translation> +<translation id="584525477304726060">పెద్దదిగా చేయడానికి నొక్కి, ఉంచండి</translation> <translation id="5860033963881614850">ఆఫ్ అయ్యింది</translation> <translation id="5860491529813859533">ఆన్ చేయండి</translation> <translation id="5867217927013474703">నెట్వర్క్ సమాచారాన్ని సేకరిస్తోంది</translation> @@ -739,6 +750,7 @@ <translation id="6667908387435388584">మీ ఫోన్ హాట్స్పాట్కు కనెక్ట్ చేసి, సైలెంట్లో పెట్టి, మీ పరికరాన్ని కనుగొని, మీ ఫోన్లో ప్రస్తుతం తెరిచి ఉన్న Chrome ట్యాబ్లను చూడండి</translation> <translation id="6670153871843998651">డెస్క్ 3</translation> <translation id="6671495933530132209">చిత్రాన్ని కాపీ చేయి</translation> +<translation id="6671661918848783005">మీ Chromebookను అన్లాక్ చేయడం సాధ్యపడలేదు</translation> <translation id="6692996468359469499">మీ ఎంచుకున్న దానికి సంబంధించిన సమాచారాన్ని పొందండి</translation> <translation id="6696025732084565524">మీ తీసివేయగల కీబోర్డ్కి ఒక ముఖ్యమైన అప్డేట్ అవసరం</translation> <translation id="6700713906295497288">IME మెనూ బటన్</translation>
diff --git a/ash/strings/ash_strings_th.xtb b/ash/strings/ash_strings_th.xtb index 496d35a..643f15b 100644 --- a/ash/strings/ash_strings_th.xtb +++ b/ash/strings/ash_strings_th.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">รายการเพิ่มเติม</translation> <translation id="1346748346194534595">ขวา</translation> <translation id="1351937230027495976">ยุบเมนู</translation> +<translation id="1364382257761975320">ใช้ลายนิ้วมือเพื่อปลดล็อก Chromebook</translation> <translation id="1383597849754832576">ดาวน์โหลดไฟล์คำพูดไม่ได้ โปรดลองอีกครั้งภายหลัง</translation> <translation id="1383876407941801731">ค้นหา</translation> <translation id="1391102559483454063">เปิด</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">การตั้งค่าสไตลัส</translation> <translation id="2354174487190027830">กำลังเปิดใช้งาน <ph name="NAME" /></translation> <translation id="2359808026110333948">ต่อไป</translation> +<translation id="2367186422933365202">ลงชื่อเข้าใช้ Chromebook ไม่ได้</translation> <translation id="2369165858548251131">"สวัสดี" ในภาษาจีน</translation> <translation id="2390318262976603432">การตั้งค่าภาษา</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">การควบคุมสื่อ</translation> +<translation id="2402411679569069051">ใช้ลายนิ้วมือหรือปลดล็อกโทรศัพท์เพื่อปลดล็อก Chromebook</translation> <translation id="2405664212338326887">ไม่เชื่อมต่อ</translation> <translation id="2408955596600435184">ป้อน PIN ของคุณ</translation> <translation id="2412593942846481727">มีเวอร์ชันอัปเดต</translation> @@ -290,6 +293,7 @@ <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="3252248118006571685">เปิดบลูทูธของโทรศัพท์เพื่อปลดล็อก Chromebook</translation> <translation id="3255483164551725916">เธอทำอะไรได้บ้าง</translation> <translation id="3269597722229482060">คลิกขวา</translation> <translation id="3289674678944039601">กำลังชาร์จผ่านอะแดปเตอร์</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control-Shift-Space</translation> <translation id="3485319357743610354"><ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, ความแรงสัญญาณ <ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">คำจำกัดความ</translation> +<translation id="3509391053705095206">ไม่พบโทรศัพท์ ตรวจสอบว่าบลูทูธของโทรศัพท์เปิดอยู่</translation> <translation id="3510164367642747937">ไฮไลต์เคอร์เซอร์เมาส์</translation> <translation id="3513798432020909783">บัญชีที่จัดการโดย <ph name="MANAGER_EMAIL" /></translation> <translation id="353086728817903341">เชื่อมต่ออยู่กับอุปกรณ์ <ph name="NUM_DEVICES" /> เครื่อง</translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">ไมโครโฟนด้านหน้า</translation> <translation id="3713734891607377840">เปิดเมื่อดาวน์โหลดเสร็จ</translation> <translation id="3742055079367172538">ภาพหน้าจอที่บันทึก</translation> +<translation id="3744282433224562605">ป้อนรหัสผ่านเพื่อปลดล็อก Chromebook</translation> <translation id="3771549900096082774">โหมดคอนทราสต์สูง</translation> <translation id="3773700760453577392">ผู้ดูแลระบบไม่อนุญาตให้ <ph name="USER_EMAIL" /> ลงชื่อเข้าสู่ระบบพร้อมกันหลายบัญชี ผู้ใช้ทุกคนต้องออกจากระบบเพื่อดำเนินการต่อ</translation> <translation id="3779139509281456663">กำลังเชื่อมต่อกับ <ph name="NAME" /></translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">เมื่อคลิกขวาหรือกดค้าง Assistant จะแสดงข้อมูล เช่น คำจำกัดความ คำแปล หรือการแปลงหน่วยของรายการที่คุณเลือก</translation> <translation id="4505050298327493054">เดสก์ที่ใช้งานอยู่</translation> <translation id="4513946894732546136">ข้อเสนอแนะ</translation> +<translation id="4518404433291145981">ก่อนอื่นให้ปลดล็อกโทรศัพท์เพื่อปลดล็อก Chromebook</translation> <translation id="4527045527269911712">อุปกรณ์บลูทูธ "<ph name="DEVICE_NAME" />" ต้องการสิทธิ์ในการจับคู่</translation> <translation id="453661520163887813">อีก <ph name="TIME" /> จะเต็ม</translation> <translation id="4538824937723742295">จับภาพแบบเต็มหน้าจอ</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">PIN ไม่ถูกต้อง</translation> <translation id="5083553833479578423">ใช้ฟีเจอร์จาก Assistant ได้มากขึ้น</translation> <translation id="5136175204352732067">เชื่อมต่อกับแป้นพิมพ์อื่นแล้ว</translation> +<translation id="5147567197700016471">ปลดล็อกแล้ว</translation> <translation id="5155897006997040331">ความเร็วในการอ่าน</translation> <translation id="5166918508782100047">การตั้งค่าคำตอบด่วน</translation> <translation id="5168181903108465623">เครื่องส่งพร้อมใช้งาน</translation> <translation id="5170568018924773124">แสดงในโฟลเดอร์</translation> <translation id="5176318573511391780">บันทึกหน้าจอบางส่วน</translation> +<translation id="5199367439331364630">ป้อนรหัสผ่านเพื่อลงชื่อเข้าใช้ Chromebook</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{การแจ้งเตือนอื่น 1 รายการ}other{การแจ้งเตือนอื่น # รายการ}}</translation> <translation id="5207949376430453814">ไฮไลต์เครื่องหมาย Caret ของข้อความ</translation> <translation id="5208059991603368177">เปิด</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">จับคู่อุปกรณ์ใหม่</translation> <translation id="5322611492012084517">ไม่พบโทรศัพท์</translation> <translation id="5329548388331921293">กำลังเชื่อมต่อ...</translation> +<translation id="5330201449517439522">แตะหรือคลิกเพื่อเข้าใช้งาน</translation> <translation id="5331975486040154427">อุปกรณ์ USB-C (พอร์ตด้านหลังซ้าย)</translation> <translation id="5352250171825660495">ธีมมืดเปิดอยู่</translation> <translation id="5379115545237091094">ลองหลายครั้งเกินไป</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">การตั้งค่าอุปกรณ์ที่เชื่อมต่อ</translation> <translation id="583281660410589416">ไม่รู้จัก</translation> <translation id="5837036133683224804">หยุด <ph name="ROUTE_TITLE" /> ใน<ph name="RECEIVER_NAME" /></translation> +<translation id="584525477304726060">กดค้างเพื่อขยายใหญ่สุด</translation> <translation id="5860033963881614850">ปิด</translation> <translation id="5860491529813859533">เปิด</translation> <translation id="5867217927013474703">กำลังรวบรวมข้อมูลเครือข่าย</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">เชื่อมต่อฮอตสปอตของโทรศัพท์ ปิดเสียงและระบุตำแหน่งของอุปกรณ์ ตลอดจนดูแท็บ Chrome ล่าสุดที่เปิดอยู่ในโทรศัพท์</translation> <translation id="6670153871843998651">เดสก์ที่ 3</translation> <translation id="6671495933530132209">คัดลอกรูปภาพ</translation> +<translation id="6671661918848783005">ปลดล็อก Chromebook ไม่ได้</translation> <translation id="6692996468359469499">ดูข้อมูลที่เกี่ยวข้องกับการเลือกของคุณ</translation> <translation id="6696025732084565524">แป้มพิมพ์ที่ถอดได้ต้องได้รับอัปเดตที่สำคัญ</translation> <translation id="6700713906295497288">ปุ่มเมนู IME</translation>
diff --git a/ash/strings/ash_strings_zu.xtb b/ash/strings/ash_strings_zu.xtb index 5b0fcbd2..9b11112 100644 --- a/ash/strings/ash_strings_zu.xtb +++ b/ash/strings/ash_strings_zu.xtb
@@ -64,6 +64,7 @@ <translation id="1341651618736211726">Ukugcwala kakhulu</translation> <translation id="1346748346194534595">Kwesokudla</translation> <translation id="1351937230027495976">Goqa imenyu</translation> +<translation id="1364382257761975320">Ukuze uvule i-Chromebook yakho, sebenzisa isigxivizo somunwe wakho</translation> <translation id="1383597849754832576">Ayikwazi ukulanda amafayela wenkulumo. Zama futhi emuva kwesikhathi.</translation> <translation id="1383876407941801731">Sesha</translation> <translation id="1391102559483454063">Vuliwe</translation> @@ -186,10 +187,12 @@ <translation id="2352467521400612932">Izilungiselelo ze-stylus</translation> <translation id="2354174487190027830">Yenza kusebenze i-<ph name="NAME" /></translation> <translation id="2359808026110333948">Qhubeka</translation> +<translation id="2367186422933365202">Ayikwazi ukungena ngemvume ku-Chromebook yakho</translation> <translation id="2369165858548251131">"Sawubona" ngesi-Chinese</translation> <translation id="2390318262976603432">Izilungiselelo Zesifunda</translation> <translation id="2391579633712104609">180°</translation> <translation id="240006516586367791">Izilawuli zemidiya</translation> +<translation id="2402411679569069051">Ukuze uvule i-Chromebook yakho, sebenzisa isigxivizo somunwe wakho noma uvule ifoni yakho</translation> <translation id="2405664212338326887">Akuxhunyiwe</translation> <translation id="2408955596600435184">Faka iphinikhodi yakho</translation> <translation id="2412593942846481727">Isibuyekezo siyatholakala</translation> @@ -290,6 +293,7 @@ <translation id="3226991577105957773">+<ph name="COUNT" /> okuningi</translation> <translation id="324366796737464147">Ukukhansela umsindo</translation> <translation id="3249513730522716925">Iwindi <ph name="WINDOW_TITLE" /> lihanjisiwe kusuka kudeski <ph name="ACTIVE_DESK" /> kuya kudeski <ph name="TARGET_DESK" /></translation> +<translation id="3252248118006571685">Ukuze uvule i-Chromebook yakho, vula i-Bluetooth yefoni yakho</translation> <translation id="3255483164551725916">Yini ongayenza?</translation> <translation id="3269597722229482060">Ukuchofoza Kwesokudla</translation> <translation id="3289674678944039601">Ishaja nge-adaptha</translation> @@ -323,6 +327,7 @@ <translation id="3477079411857374384">Control-Shift-Space</translation> <translation id="3485319357743610354">I-<ph name="SECURITY_STATUS" />, <ph name="CONNECTION_STATUS" />, amandla esignali angu-<ph name="SIGNAL_STRENGTH" /></translation> <translation id="3486220673238053218">incazelo</translation> +<translation id="3509391053705095206">Ayikwazi ukuthola ifoni yakho. Qiniseka ukuthi i-Bluetooth yefoni yakho ivuliwe.</translation> <translation id="3510164367642747937">Gqamisa isikhombisi semawuzi</translation> <translation id="3513798432020909783">I-akhawunti iphethwe ngu-<ph name="MANAGER_EMAIL" /></translation> <translation id="353086728817903341">Ixhunywe kumadivayisi angu-<ph name="NUM_DEVICES" /></translation> @@ -358,6 +363,7 @@ <translation id="371370241367527062">Imakrofoni yangaphambili</translation> <translation id="3713734891607377840">Vula lapho isiqedile</translation> <translation id="3742055079367172538">Kuthathwe isithombe-skrini</translation> +<translation id="3744282433224562605">Ukuze uvule i-Chromebook yakho, faka iphasiwedi</translation> <translation id="3771549900096082774">Imodi yokugqama okuphezulu</translation> <translation id="3773700760453577392">Umlawuli akazange avumele ukungena ngemvume okuningi kwe-<ph name="USER_EMAIL" />. Bonke abasebenzisi kumele baphume ngemvume ukuze baqhubeke.</translation> <translation id="3779139509281456663">Iyaxhuma ku-<ph name="NAME" /></translation> @@ -468,6 +474,7 @@ <translation id="4485060137115666462">Ngokuchofoza ngakwesokudla noma ngokucindezela isikhathi eside, Umsizi ubonisa ulwazi olunjengencazelo, ukuhumusha noma ukuguqulwa kweyunithi yokhetho lwakho.</translation> <translation id="4505050298327493054">Ideski elisebenzayo.</translation> <translation id="4513946894732546136">Impendulo</translation> +<translation id="4518404433291145981">Ukuze uvule i-Chromebook yakho, qala uvule ifoni yakho</translation> <translation id="4527045527269911712">Idivayisi ye-Bluetooth eyi-"<ph name="DEVICE_NAME" />" ingathanda imvume yokubhanqa.</translation> <translation id="453661520163887813"><ph name="TIME" /> ize igcwale</translation> <translation id="4538824937723742295">Thatha isithombe-skrini sesikrini esigcwele</translation> @@ -551,11 +558,13 @@ <translation id="5078796286268621944">Iphinikhodi engalungile</translation> <translation id="5083553833479578423">Vula izici eziningi zomsizi.</translation> <translation id="5136175204352732067">Ikhibhodi ehlukile ixhunyiwe</translation> +<translation id="5147567197700016471">Kuvuliwe</translation> <translation id="5155897006997040331">Isivinini sokufunda</translation> <translation id="5166918508782100047">Amasethingi wezimpendulo ezisheshayo</translation> <translation id="5168181903108465623">Amadivayisi wabalingisi ayatholakala</translation> <translation id="5170568018924773124">Bonisa kufolda</translation> <translation id="5176318573511391780">Rekhoda ingxenye yesikrini</translation> +<translation id="5199367439331364630">Ukuze ungene ngemvume ku-Chromebook yakho, faka iphasiwedi</translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{esinye isaziso esi-1}one{ezinye izaziso ezi-#}other{ezinye izaziso ezi-#}}</translation> <translation id="5207949376430453814">Gqamisa ikharethi yombhalo</translation> <translation id="5208059991603368177">Vuliwe</translation> @@ -576,6 +585,7 @@ <translation id="5319712128756744240">Bhanqa idivayisi entsha</translation> <translation id="5322611492012084517">Ayikwazi ukuthola ifoni yakho</translation> <translation id="5329548388331921293">Iyaxhuma...</translation> +<translation id="5330201449517439522">Thepha noma uchofoze ukuze ungene</translation> <translation id="5331975486040154427">Idivayisi ye-USB-C (imbobo yasemuva yohlangothi lwesinxele)</translation> <translation id="5352250171825660495">Itimu emnyama ivuliwe</translation> <translation id="5379115545237091094">Imizamo eminingi kakhulu</translation> @@ -633,6 +643,7 @@ <translation id="5825969630400862129">Izilungiselelo zamadivayisi axhunyiwe</translation> <translation id="583281660410589416">Akwaziwa</translation> <translation id="5837036133683224804">Misa i-<ph name="ROUTE_TITLE" /> ku-<ph name="RECEIVER_NAME" /></translation> +<translation id="584525477304726060">Bamba ukuze ukhulise</translation> <translation id="5860033963881614850">Valiwe</translation> <translation id="5860491529813859533">Vula</translation> <translation id="5867217927013474703">Ukuqoqa ulwazi lwenethiwekhi</translation> @@ -738,6 +749,7 @@ <translation id="6667908387435388584">Xhuma ku-hotspot yefoni yakho, thulisa futhi thola idivayisi yakho, bese ubuka amathebhu we-Chrome wamanje avuliwe efonini yakho</translation> <translation id="6670153871843998651">Itafula 3</translation> <translation id="6671495933530132209">Kopisha isithombe</translation> +<translation id="6671661918848783005">Ayikwazi ukuvula i-Chromebook yakho</translation> <translation id="6692996468359469499">Thola ukwaziswa okuhlobene nokhetho lwakho</translation> <translation id="6696025732084565524">Ikhibhodi yakho enqamukayo idinga isibuyekezo esibalulekile</translation> <translation id="6700713906295497288">Inkinobho yemenyu ye-IME</translation>
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_controller.cc b/ash/system/bluetooth/bluetooth_detailed_view_controller.cc index c9ea5f7..9782dd99 100644 --- a/ash/system/bluetooth/bluetooth_detailed_view_controller.cc +++ b/ash/system/bluetooth/bluetooth_detailed_view_controller.cc
@@ -6,9 +6,13 @@ #include "ash/constants/ash_features.h" #include "ash/public/cpp/bluetooth_config_service.h" +#include "ash/public/cpp/system_tray_client.h" +#include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" +#include "ash/system/model/system_tray_model.h" #include "base/check.h" #include "chromeos/services/bluetooth_config/public/cpp/cros_bluetooth_config_util.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/l10n/l10n_util.h" #include "ui/views/view.h" @@ -66,7 +70,10 @@ remote_cros_bluetooth_config_->SetBluetoothEnabledState(new_state); } -void BluetoothDetailedViewController::OnPairNewDeviceRequested() {} +void BluetoothDetailedViewController::OnPairNewDeviceRequested() { + Shell::Get()->system_tray_model()->client()->ShowBluetoothPairingDialog( + /*device_address=*/absl::nullopt); +} void BluetoothDetailedViewController::OnDeviceListItemSelected( const chromeos::bluetooth_config::mojom::PairedBluetoothDevicePropertiesPtr&
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_controller_unittest.cc b/ash/system/bluetooth/bluetooth_detailed_view_controller_unittest.cc index 452e836..5fa4c51 100644 --- a/ash/system/bluetooth/bluetooth_detailed_view_controller_unittest.cc +++ b/ash/system/bluetooth/bluetooth_detailed_view_controller_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/constants/ash_features.h" +#include "ash/public/cpp/test/test_system_tray_client.h" #include "ash/system/bluetooth/bluetooth_detailed_view.h" #include "ash/system/bluetooth/bluetooth_device_list_controller.h" #include "ash/system/bluetooth/fake_bluetooth_detailed_view.h" @@ -192,5 +193,12 @@ EXPECT_EQ(BluetoothSystemState::kEnabling, GetBluetoothAdapterState()); } +TEST_F(BluetoothDetailedViewControllerTest, + OnPairNewDeviceRequestedOpensBluetoothDialog) { + EXPECT_EQ(0, GetSystemTrayClient()->show_bluetooth_pairing_dialog_count()); + bluetooth_detailed_view_delegate()->OnPairNewDeviceRequested(); + EXPECT_EQ(1, GetSystemTrayClient()->show_bluetooth_pairing_dialog_count()); +} + } // namespace tray } // namespace ash
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_impl.cc b/ash/system/bluetooth/bluetooth_detailed_view_impl.cc index 59b196c..bb9362d9 100644 --- a/ash/system/bluetooth/bluetooth_detailed_view_impl.cc +++ b/ash/system/bluetooth/bluetooth_detailed_view_impl.cc
@@ -11,17 +11,24 @@ #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" +#include "ash/style/ash_color_provider.h" #include "ash/system/bluetooth/bluetooth_device_list_item_view.h" #include "ash/system/bluetooth/bluetooth_disabled_detailed_view.h" #include "ash/system/model/system_tray_model.h" +#include "ash/system/tray/detailed_view_delegate.h" #include "ash/system/tray/hover_highlight_view.h" #include "ash/system/tray/tray_popup_utils.h" #include "ash/system/tray/tray_toggle_button.h" #include "ash/system/tray/tri_view.h" +#include "ash/system/unified/top_shortcut_button.h" #include "base/check.h" #include "base/memory/ptr_util.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/gfx/geometry/insets.h" +#include "ui/gfx/paint_vector_icon.h" #include "ui/views/controls/button/button.h" +#include "ui/views/controls/image_view.h" +#include "ui/views/controls/label.h" #include "ui/views/controls/scroll_view.h" #include "ui/views/layout/box_layout.h" #include "ui/views/view.h" @@ -38,9 +45,8 @@ CreateTitleRow(IDS_ASH_STATUS_TRAY_BLUETOOTH); CreateTitleRowButtons(); CreateScrollableList(); - AddScrollListSubHeader(kSystemMenuBluetoothPlusIcon, - IDS_ASH_STATUS_TRAY_BLUETOOTH_PAIR_NEW_DEVICE); CreateDisabledView(); + CreatePairNewDeviceView(); UpdateBluetoothEnabledState(/*enabled=*/false); } @@ -52,6 +58,7 @@ void BluetoothDetailedViewImpl::UpdateBluetoothEnabledState(bool enabled) { disabled_view_->SetVisible(!enabled); + pair_new_device_view_->SetVisible(enabled); scroller()->SetVisible(enabled); const std::u16string toggle_tooltip = @@ -94,6 +101,74 @@ return "BluetoothDetailedViewImpl"; } +void BluetoothDetailedViewImpl::CreateDisabledView() { + DCHECK(!disabled_view_); + + // Check that the views::ScrollView has already been created so that we can + // insert the disabled view before it to avoid the unnecessary bottom border + // spacing of views::ScrollView when it is not the last child. + DCHECK(scroller()); + + disabled_view_ = + AddChildViewAt(new BluetoothDisabledDetailedView, GetIndexOf(scroller())); + disabled_view_->SetID( + static_cast<int>(BluetoothDetailedViewChildId::kDisabledView)); + + // Make |disabled_panel_| fill the entire space below the title row so that + // the inner contents can be placed correctly. + box_layout()->SetFlexForView(disabled_view_, 1); +} + +void BluetoothDetailedViewImpl::CreatePairNewDeviceView() { + DCHECK(!pair_new_device_view_); + + // Check that the views::ScrollView has already been created so that we can + // insert the "pair new device" before it. + DCHECK(scroller()); + + pair_new_device_view_ = + AddChildViewAt(new views::View(), GetIndexOf(scroller())); + pair_new_device_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical)); + pair_new_device_view_->SetID( + static_cast<int>(BluetoothDetailedViewChildId::kPairNewDeviceView)); + + std::unique_ptr<ash::TriView> row_view = + base::WrapUnique(TrayPopupUtils::CreateDefaultRowView()); + + std::unique_ptr<ash::TopShortcutButton> button = + std::make_unique<ash::TopShortcutButton>( + base::BindRepeating( + &BluetoothDetailedViewImpl::OnPairNewDeviceRequested, + weak_factory_.GetWeakPtr()), + kSystemMenuBluetoothPlusIcon, + IDS_ASH_STATUS_TRAY_BLUETOOTH_PAIR_NEW_DEVICE); + button->SetID( + static_cast<int>(BluetoothDetailedViewChildId::kPairNewDeviceButton)); + row_view->AddView(TriView::Container::START, button.release()); + + std::unique_ptr<views::Label> label = + base::WrapUnique(TrayPopupUtils::CreateDefaultLabel()); + label->SetText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_BLUETOOTH_PAIR_NEW_DEVICE)); + label->SetEnabledColor(AshColorProvider::Get()->GetContentLayerColor( + AshColorProvider::ContentLayerType::kTextColorPrimary)); + TrayPopupUtils::SetLabelFontList(label.get(), + TrayPopupUtils::FontStyle::kSubHeader); + row_view->AddView(TriView::Container::CENTER, label.release()); + + const gfx::Insets padding = + pair_new_device_view_->AddChildView(CreateListSubHeaderSeparator()) + ->GetInsets(); + + // The "pair new device" button does not have top padding by default, so add + // top padding equal to the top padding of the following separator so that the + // button becomes centered between the preceding and following separators. + row_view->SetInsets(gfx::Insets(padding.top(), 0, 0, 0)); + + pair_new_device_view_->AddChildViewAt(row_view.release(), 0); +} + void BluetoothDetailedViewImpl::CreateTitleRowButtons() { // TODO(crbug.com/1010321): Once we are able to determine whether we are // authorized to turn Bluetooth on or off using the API we should update this @@ -123,22 +198,8 @@ tri_view()->AddView(TriView::Container::END, settings.release()); } -void BluetoothDetailedViewImpl::CreateDisabledView() { - DCHECK(!disabled_view_); - - // Check that the views::ScrollView has already been created and insert the - // disabled view before it to avoid the unnecessary bottom border spacing of - // views::ScrollView when it is not the last child. - DCHECK(scroller()); - - disabled_view_ = - AddChildViewAt(new BluetoothDisabledDetailedView, GetIndexOf(scroller())); - disabled_view_->SetID( - static_cast<int>(BluetoothDetailedViewChildId::kDisabledView)); - - // Make |disabled_panel_| fill the entire space below the title row so that - // the inner contents can be placed correctly. - box_layout()->SetFlexForView(disabled_view_, 1); +void BluetoothDetailedViewImpl::OnPairNewDeviceRequested() { + delegate()->OnPairNewDeviceRequested(); } void BluetoothDetailedViewImpl::OnSettingsClicked() {
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_impl.h b/ash/system/bluetooth/bluetooth_detailed_view_impl.h index beb78b9..ebd4e1bb 100644 --- a/ash/system/bluetooth/bluetooth_detailed_view_impl.h +++ b/ash/system/bluetooth/bluetooth_detailed_view_impl.h
@@ -45,6 +45,8 @@ kToggleButton = 1, kDisabledView = 2, kSettingsButton = 3, + kPairNewDeviceView = 4, + kPairNewDeviceButton = 5, }; // BluetoothDetailedView: @@ -59,11 +61,18 @@ // views::View: const char* GetClassName() const override; + // Creates and configures the Bluetooth disabled view. + void CreateDisabledView(); + + // Creates and configures the pair new device view containing the button and + // the following separator line. + void CreatePairNewDeviceView(); + // Creates and configures the Bluetooth toggle button and the settings button. void CreateTitleRowButtons(); - // Creates and configures the Bluetooth disabled view. - void CreateDisabledView(); + // Propagates user interaction with the "pair new device" button. + void OnPairNewDeviceRequested(); // Attempts to close the quick settings and open the Bluetooth settings. void OnSettingsClicked(); @@ -73,6 +82,7 @@ views::Button* settings_button_ = nullptr; views::ToggleButton* toggle_button_ = nullptr; + views::View* pair_new_device_view_ = nullptr; BluetoothDisabledDetailedView* disabled_view_ = nullptr; base::WeakPtrFactory<BluetoothDetailedViewImpl> weak_factory_{this};
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_unittest.cc b/ash/system/bluetooth/bluetooth_detailed_view_unittest.cc index 76a2b0f4..6271baf50 100644 --- a/ash/system/bluetooth/bluetooth_detailed_view_unittest.cc +++ b/ash/system/bluetooth/bluetooth_detailed_view_unittest.cc
@@ -12,13 +12,19 @@ #include "ash/system/bluetooth/bluetooth_detailed_view_impl.h" #include "ash/system/bluetooth/bluetooth_disabled_detailed_view.h" #include "ash/system/tray/detailed_view_delegate.h" +#include "ash/system/unified/top_shortcut_button.h" #include "ash/test/ash_test_base.h" #include "base/run_loop.h" #include "base/test/scoped_feature_list.h" #include "mojo/public/cpp/bindings/clone_traits.h" #include "ui/base/l10n/l10n_util.h" #include "ui/events/test/event_generator.h" +#include "ui/gfx/geometry/insets.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/rect.h" #include "ui/views/controls/button/toggle_button.h" +#include "ui/views/controls/separator.h" +#include "ui/views/layout/box_layout.h" #include "ui/views/widget/widget.h" namespace views { @@ -104,8 +110,8 @@ bluetooth_detailed_view_ = bluetooth_detailed_view.get(); widget_ = CreateFramelessTestWidget(); - widget_->SetContentsView(bluetooth_detailed_view.release()->GetAsView()); widget_->SetFullscreen(true); + widget_->SetContentsView(bluetooth_detailed_view.release()->GetAsView()); base::RunLoop().RunUntilIdle(); } @@ -126,22 +132,34 @@ base::RunLoop().RunUntilIdle(); } + ash::TopShortcutButton* FindPairNewDeviceButton() { + return FindViewById<ash::TopShortcutButton*>( + BluetoothDetailedViewImpl::BluetoothDetailedViewChildId:: + kPairNewDeviceButton); + } + views::ToggleButton* FindBluetoothToggleButton() { return FindViewById<views::ToggleButton*>( BluetoothDetailedViewImpl::BluetoothDetailedViewChildId::kToggleButton); } - BluetoothDisabledDetailedView* FindBluetoothDisabledView() { - return FindViewById<BluetoothDisabledDetailedView*>( - BluetoothDetailedViewImpl::BluetoothDetailedViewChildId::kDisabledView); - } - views::Button* FindSettingsButton() { return FindViewById<views::Button*>( BluetoothDetailedViewImpl::BluetoothDetailedViewChildId:: kSettingsButton); } + views::View* FindPairNewDeviceView() { + return FindViewById<views::View*>( + BluetoothDetailedViewImpl::BluetoothDetailedViewChildId:: + kPairNewDeviceView); + } + + BluetoothDisabledDetailedView* FindBluetoothDisabledView() { + return FindViewById<BluetoothDisabledDetailedView*>( + BluetoothDetailedViewImpl::BluetoothDetailedViewChildId::kDisabledView); + } + BluetoothDetailedView* bluetooth_detailed_view() { return bluetooth_detailed_view_; } @@ -187,19 +205,23 @@ TEST_F(BluetoothDetailedViewTest, BluetoothEnabledStateChangesUpdateChildrenViewState) { views::ToggleButton* toggle_button = FindBluetoothToggleButton(); + views::View* pair_new_device_view = FindPairNewDeviceView(); BluetoothDisabledDetailedView* disabled_view = FindBluetoothDisabledView(); EXPECT_FALSE(toggle_button->GetIsOn()); + EXPECT_FALSE(pair_new_device_view->GetVisible()); EXPECT_TRUE(disabled_view->GetVisible()); bluetooth_detailed_view()->UpdateBluetoothEnabledState(true); EXPECT_TRUE(toggle_button->GetIsOn()); + EXPECT_TRUE(pair_new_device_view->GetVisible()); EXPECT_FALSE(disabled_view->GetVisible()); bluetooth_detailed_view()->UpdateBluetoothEnabledState(false); EXPECT_FALSE(toggle_button->GetIsOn()); + EXPECT_FALSE(pair_new_device_view->GetVisible()); EXPECT_TRUE(disabled_view->GetVisible()); } @@ -233,5 +255,44 @@ toggle_button->GetTooltipText()); } +TEST_F(BluetoothDetailedViewTest, PressingPairNewDeviceNotifiesDelegate) { + ash::TopShortcutButton* pair_new_device_button = FindPairNewDeviceButton(); + views::View* pair_new_device_view = FindPairNewDeviceView(); + + EXPECT_FALSE(pair_new_device_view->GetVisible()); + EXPECT_EQ(0u, bluetooth_detailed_view_delegate() + ->on_pair_new_device_requested_call_count()); + + bluetooth_detailed_view()->UpdateBluetoothEnabledState(true); + ClickOnAndWait(pair_new_device_button); + EXPECT_EQ(1u, bluetooth_detailed_view_delegate() + ->on_pair_new_device_requested_call_count()); +} + +TEST_F(BluetoothDetailedViewTest, PairNewDeviceButtonIsCentered) { + ash::TopShortcutButton* pair_new_device_button = FindPairNewDeviceButton(); + views::View* pair_new_device_view = FindPairNewDeviceView(); + + bluetooth_detailed_view()->UpdateBluetoothEnabledState(true); + + EXPECT_EQ(2u, pair_new_device_view->children().size()); + EXPECT_STREQ("Separator", + pair_new_device_view->children().at(1)->GetClassName()); + + views::View* separator = pair_new_device_view->children().at(1); + + const gfx::Point button_center = + pair_new_device_button->GetBoundsInScreen().CenterPoint(); + const gfx::Rect& view_bounds = pair_new_device_view->GetBoundsInScreen(); + const int separator_height = separator->GetContentsBounds().height(); + + // When determining the center of the view we should not consider the content + // of the following separator, and only its top padding. + const int view_center = + view_bounds.y() + (view_bounds.height() - separator_height + 1) / 2; + + EXPECT_EQ(view_center, button_center.y()); +} + } // namespace tray } // namespace ash
diff --git a/ash/webui/common/resources/navigation_view_panel.html b/ash/webui/common/resources/navigation_view_panel.html index 5d9a87ee..53f0a4b 100644 --- a/ash/webui/common/resources/navigation_view_panel.html +++ b/ash/webui/common/resources/navigation_view_panel.html
@@ -1,5 +1,6 @@ <style include="cr-shared-style"> - ::slotted([slot=bottom-nav-content]) { + ::slotted([slot=bottom-nav-content-drawer]), + ::slotted([slot=bottom-nav-content-panel]) { bottom: 24px; inset-inline-start: 16px; position: fixed; @@ -86,7 +87,7 @@ <navigation-selector selector-items={{selectorItems_}} selected-item={{selectedItem}}> </navigation-selector> - <slot name="bottom-nav-content"></slot> + <slot name="bottom-nav-content-drawer"></slot> </div> </cr-drawer> <template is="dom-if" if="[[showNav]]"> @@ -95,7 +96,7 @@ <navigation-selector selector-items={{selectorItems_}} selected-item={{selectedItem}}> </navigation-selector> - <slot name="bottom-nav-content"></slot> + <slot name="bottom-nav-content-panel"></slot> </div> </div> </template>
diff --git a/ash/webui/diagnostics_ui/diagnostics_ui.cc b/ash/webui/diagnostics_ui/diagnostics_ui.cc index 973f60f..40d70557 100644 --- a/ash/webui/diagnostics_ui/diagnostics_ui.cc +++ b/ash/webui/diagnostics_ui/diagnostics_ui.cc
@@ -171,7 +171,6 @@ {"networkEthernetAuthenticationNoneLabel", IDS_ONC_WIFI_SECURITY_NONE}, {"networkIccidLabel", IDS_ONC_CELLULAR_ICCID}, {"networkIpAddressLabel", IDS_NETWORK_DIAGNOSTICS_IP_ADDRESS}, - {"networkLinkSpeedLabel", IDS_NETWORK_DIAGNOSTICS_LINK_SPEED}, {"networkRoamingOff", IDS_DIAGNOSTICS_ROAMING_OFF}, {"networkRoamingStateHome", IDS_ONC_CELLULAR_ROAMING_STATE_HOME}, {"networkRoamingStateLabel", IDS_ONC_CELLULAR_ROAMING_STATE}, @@ -211,7 +210,6 @@ {"networkTechnologyUmtsLabel", IDS_NETWORK_DIAGNOSTICS_CELLULAR_UMTS}, {"notEnoughAvailableMemoryMessage", IDS_DIAGNOSTICS_NOT_ENOUGH_AVAILABLE_MEMORY}, - {"overviewText", IDS_DIAGNOSTICS_OVERVIEW}, {"percentageLabel", IDS_DIAGNOSTICS_PERCENTAGE_LABEL}, {"reconnectLinkText", IDS_DIAGNOSTICS_RECONNECT_LINK_TEXT}, {"remainingCharge", IDS_DIAGNOSTICS_REMAINING_CHARGE_LABEL}, @@ -237,6 +235,7 @@ IDS_DIAGNOSTICS_SESSION_LOG_TOAST_TEXT_SUCCESS}, {"signalStrengthRoutineText", IDS_NETWORK_DIAGNOSTICS_SIGNAL_STRENGTH}, {"stopTestButtonText", IDS_DIAGNOSTICS_STOP_TEST_BUTTON_TEXT}, + {"systemText", IDS_DIAGNOSTICS_SYSTEM}, {"testCancelledText", IDS_DIAGNOSTICS_CANCELLED_TEST_TEXT}, {"testFailure", IDS_DIAGNOSTICS_TEST_FAILURE_TEXT}, {"testFailedBadgeText", IDS_DIAGNOSTICS_TEST_FAILURE_BADGE_TEXT},
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_app.html b/ash/webui/diagnostics_ui/resources/diagnostics_app.html index 5db2e438..d5bbe11 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_app.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_app.html
@@ -20,7 +20,14 @@ <div hidden$="[[!showNavPanel_]]"> <navigation-view-panel id="navigationPanel" title="[[i18n('diagnosticsTitle')]]" show-tool-bar> - <div slot="bottom-nav-content" class="session-log-container"> + <div slot="bottom-nav-content-panel" class="session-log-container"> + <cr-button on-click="onSessionLogClick_" class="session-log-button" + hidden="[[!isLoggedIn_]]"> + <iron-icon icon="diagnostics:download" id="download-icon"></iron-icon> + <span>[[i18n('sessionLog')]]</span> + </cr-button> + </div> + <div slot="bottom-nav-content-drawer" class="session-log-container"> <cr-button on-click="onSessionLogClick_" class="session-log-button" hidden="[[!isLoggedIn_]]"> <iron-icon icon="diagnostics:download" id="download-icon"></iron-icon>
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_app.js b/ash/webui/diagnostics_ui/resources/diagnostics_app.js index 74fc946..cfaad7d 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_app.js +++ b/ash/webui/diagnostics_ui/resources/diagnostics_app.js
@@ -77,8 +77,8 @@ // Note: When adding a new page, update the DiagnosticsPage enum located // in chrome/browser/ui/webui/chromeos/diagnostics_dialog.h. const pages = [navPanel.createSelectorItem( - loadTimeData.getString('overviewText'), 'system-page', - getNavigationIcon('laptop-chromebook'), 'overview')]; + loadTimeData.getString('systemText'), 'system-page', + getNavigationIcon('laptop-chromebook'), 'system')]; if (this.isNetworkingEnabled_) { pages.push(navPanel.createSelectorItem(
diff --git a/ash/webui/diagnostics_ui/resources/ethernet_info.html b/ash/webui/diagnostics_ui/resources/ethernet_info.html index c40e89e..be09fed 100644 --- a/ash/webui/diagnostics_ui/resources/ethernet_info.html +++ b/ash/webui/diagnostics_ui/resources/ethernet_info.html
@@ -6,17 +6,12 @@ value="[[ipAddress_]]" orientation="horizontal"> </data-point> - <data-point id="authentication" - header="[[i18n('networkAuthenticationLabel')]]" - value="[[authentication_]]" - orientation="horizontal"> - </data-point> </div> <div class="divider-horizontal"></div> <div class="data-point-container"> - <!-- TODO(ashleydp): Update data point when link speed data added. --> - <data-point id="linkSpeed" header="[[i18n('networkLinkSpeedLabel')]]" - value="" + <data-point id="authentication" + header="[[i18n('networkAuthenticationLabel')]]" + value="[[authentication_]]" orientation="horizontal"> </data-point> </div>
diff --git a/base/allocator/partition_allocator/partition_alloc_constants.h b/base/allocator/partition_allocator/partition_alloc_constants.h index 38d147fd..64ce0db 100644 --- a/base/allocator/partition_allocator/partition_alloc_constants.h +++ b/base/allocator/partition_allocator/partition_alloc_constants.h
@@ -306,40 +306,8 @@ constexpr size_t kBitsPerSizeT = sizeof(void*) * CHAR_BIT; -// When a SlotSpan becomes empty, the allocator tries to avoid re-using it -// immediately, to help with fragmentation. At this point, it becomes dirty -// committed memory, which we want to minimize. This could be decommitted -// immediately, but that would imply doing a lot of system calls. In particular, -// for single-slot SlotSpans, a malloc() / free() loop would cause a *lot* of -// system calls. -// -// As an intermediate step, empty SlotSpans are placed into a per-partition -// global ring buffer, giving the newly-empty SlotSpan a chance to be re-used -// before getting decommitted. A new entry (i.e. a newly empty SlotSpan) taking -// the place used by a previous one will lead the previous SlotSpan to be -// decommitted immediately, provided that it is still empty. -// -// Setting this value higher means giving more time for reuse to happen, at the -// cost of possibly increasing peak committed memory usage (and increasing the -// size of PartitionRoot a bit, since the ring buffer is there). Note that the -// ring buffer doesn't necessarily contain an empty SlotSpan, as SlotSpans are -// *not* removed from it when re-used. So the ring buffer really is a buffer of -// *possibly* empty SlotSpans. -// -// In all cases, PartitionRoot::PurgeMemory() with the -// PartitionPurgeDecommitEmptySlotSpans flag will eagerly decommit all entries -// in the ring buffer, so with periodic purge enabled, this typically happens -// every few seconds. -#if defined(OS_LINUX) -// Set to a higher value on Linux, to assess impact on performance bots. This -// roughly halves the number of syscalls done during a speedometer 2.0 run on -// this platform. -constexpr size_t kMaxFreeableSpans = std::numeric_limits<int8_t>::max(); -#else +// Constant for the memory reclaim logic. constexpr size_t kMaxFreeableSpans = 16; -#endif -// Has to fit into SlotSpanMetadata::empty_cache_index. -static_assert(kMaxFreeableSpans <= std::numeric_limits<int8_t>::max(), ""); // If the total size in bytes of allocated but not committed pages exceeds this // value (probably it is a "out of virtual address space" crash), a special
diff --git a/base/allocator/partition_allocator/partition_page.h b/base/allocator/partition_allocator/partition_page.h index 897bd04..2dc6f5d 100644 --- a/base/allocator/partition_allocator/partition_page.h +++ b/base/allocator/partition_allocator/partition_page.h
@@ -114,7 +114,7 @@ struct __attribute__((packed)) SlotSpanMetadata { PartitionFreelistEntry* freelist_head = nullptr; SlotSpanMetadata<thread_safe>* next_slot_span = nullptr; - PartitionBucket<thread_safe>* const bucket = nullptr; + PartitionBucket<thread_safe>* const bucket; // Deliberately signed, 0 for empty or decommitted slot spans, -n for full // slot spans: @@ -122,8 +122,8 @@ uint16_t num_unprovisioned_slots = 0; int8_t empty_cache_index = 0; // -1 if not in the empty cache. // < kMaxFreeableSpans. - static_assert(kMaxFreeableSpans <= std::numeric_limits<int8_t>::max(), ""); - const bool can_store_raw_size = false; + static_assert(kMaxFreeableSpans < std::numeric_limits<int8_t>::max(), ""); + const bool can_store_raw_size; explicit SlotSpanMetadata(PartitionBucket<thread_safe>* bucket); @@ -236,7 +236,8 @@ // namespace so the getter can be fully inlined. static SlotSpanMetadata sentinel_slot_span_; // For the sentinel. - constexpr SlotSpanMetadata() noexcept = default; + constexpr SlotSpanMetadata() noexcept + : bucket(nullptr), can_store_raw_size(false) {} }; static_assert(sizeof(SlotSpanMetadata<ThreadSafe>) <= kPageMetadataSize, "SlotSpanMetadata must fit into a Page Metadata slot.");
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h index fee7b27..74a62a6e 100644 --- a/base/allocator/partition_allocator/partition_root.h +++ b/base/allocator/partition_allocator/partition_root.h
@@ -342,7 +342,14 @@ ALWAYS_INLINE static bool IsValidSlotSpan(SlotSpan* slot_span); ALWAYS_INLINE static PartitionRoot* FromSlotSpan(SlotSpan* slot_span); ALWAYS_INLINE static PartitionRoot* FromSuperPage(char* super_page); - ALWAYS_INLINE static PartitionRoot* FromPointerInNormalBuckets(char* ptr); + // Works for any pointer inside a normal bucket allocation. + // + // For direct-mapped allocations, only works for a pointer which is inside the + // first SuperPage of a given allocation, that is the first "2MiB minus a + // bit". In particular always works for a pointer at the start of an + // allocation. See partition_alloc_constants.h to see the layout of a + // direct-mapped allocation. + ALWAYS_INLINE static PartitionRoot* FromPointerInFirstSuperpage(char* ptr); ALWAYS_INLINE void IncreaseCommittedPages(size_t len); ALWAYS_INLINE void DecreaseCommittedPages(size_t len); @@ -1013,6 +1020,16 @@ PA_CHECK(IsManagedByPartitionAlloc(ptr)); #endif + // Fetch the root from the pointer, and not the SlotSpan. This is important, + // as getting to the SlotSpan is a slow operation (looking into the metadata + // area, and following a pointer), and SlotSpans can induce cache coherency + // traffic (since they're read on every free(), and written to on any + // malloc()/free() that is not a hit in the thread cache). This way we change + // the critical path from ptr -> slot_span -> root into two *parallel* ones: + // 1. ptr -> root + // 2. ptr -> slot_span + auto* root = FromPointerInFirstSuperpage(reinterpret_cast<char*>(ptr)); + // Call FromSlotInnerPtr instead of FromSlotStartPtr because the pointer // hasn't been adjusted yet. SlotSpan* slot_span = SlotSpan::FromSlotInnerPtr(ptr); @@ -1029,7 +1046,7 @@ // TODO(palmer): See if we can afford to make this a CHECK. PA_DCHECK(IsValidSlotSpan(slot_span)); - auto* root = FromSlotSpan(slot_span); + PA_DCHECK(FromSlotSpan(slot_span) == root); // TODO(bikineev): Change the condition to LIKELY once PCScan is enabled by // default. @@ -1259,10 +1276,10 @@ template <bool thread_safe> ALWAYS_INLINE PartitionRoot<thread_safe>* -PartitionRoot<thread_safe>::FromPointerInNormalBuckets(char* ptr) { - PA_DCHECK(internal::IsManagedByNormalBuckets(ptr)); +PartitionRoot<thread_safe>::FromPointerInFirstSuperpage(char* ptr) { char* super_page = reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(ptr) & kSuperPageBaseMask); + PA_DCHECK(internal::IsReservationStart(super_page)); return FromSuperPage(super_page); }
diff --git a/base/allocator/partition_allocator/starscan/pcscan_internal.cc b/base/allocator/partition_allocator/starscan/pcscan_internal.cc index 84f3ca3..b1427fc 100644 --- a/base/allocator/partition_allocator/starscan/pcscan_internal.cc +++ b/base/allocator/partition_allocator/starscan/pcscan_internal.cc
@@ -633,8 +633,9 @@ // Beyond this point, we know that |maybe_ptr| is a pointer within a // normal-bucket super page. PA_SCAN_DCHECK(IsManagedByNormalBuckets(reinterpret_cast<void*>(maybe_ptr))); + // Pointer from a normal bucket is always in the first superpage. auto* root = - Root::FromPointerInNormalBuckets(reinterpret_cast<char*>(maybe_ptr)); + Root::FromPointerInFirstSuperpage(reinterpret_cast<char*>(maybe_ptr)); #if !PA_STARSCAN_USE_CARD_TABLE // Without the card table, we must make sure that |maybe_ptr| doesn't point to
diff --git a/base/allocator/partition_allocator/starscan/pcscan_unittest.cc b/base/allocator/partition_allocator/starscan/pcscan_unittest.cc index adc6806..28ee083f 100644 --- a/base/allocator/partition_allocator/starscan/pcscan_unittest.cc +++ b/base/allocator/partition_allocator/starscan/pcscan_unittest.cc
@@ -213,7 +213,7 @@ void TestDanglingReference(PartitionAllocPCScanTest& test, SourceList* source, ValueList* value) { - auto* value_root = ThreadSafePartitionRoot::FromPointerInNormalBuckets( + auto* value_root = ThreadSafePartitionRoot::FromPointerInFirstSuperpage( reinterpret_cast<char*>(value)); { // Free |value| and leave the dangling reference in |source|. @@ -241,7 +241,7 @@ void TestDanglingReferenceNotVisited(PartitionAllocPCScanTest& test, void* value) { - auto* value_root = ThreadSafePartitionRoot::FromPointerInNormalBuckets( + auto* value_root = ThreadSafePartitionRoot::FromPointerInFirstSuperpage( reinterpret_cast<char*>(value)); value_root->Free(value); // Check that |value| is in the quarantine now. @@ -294,7 +294,7 @@ // Double check the setup -- make sure that exactly two slot spans were // allocated, within the same super page, with a gap in between. { - auto* value_root = ThreadSafePartitionRoot::FromPointerInNormalBuckets( + auto* value_root = ThreadSafePartitionRoot::FromPointerInFirstSuperpage( reinterpret_cast<char*>(value)); ScopedGuard<ThreadSafe> guard{value_root->lock_}; @@ -537,7 +537,7 @@ void TestDanglingReferenceWithSafepoint(PartitionAllocPCScanTest& test, SourceList* source, ValueList* value) { - auto* value_root = ThreadSafePartitionRoot::FromPointerInNormalBuckets( + auto* value_root = ThreadSafePartitionRoot::FromPointerInFirstSuperpage( reinterpret_cast<char*>(value)); { // Free |value| and leave the dangling reference in |source|.
diff --git a/cc/paint/BUILD.gn b/cc/paint/BUILD.gn index 3c750b5..cf3b44a 100644 --- a/cc/paint/BUILD.gn +++ b/cc/paint/BUILD.gn
@@ -110,6 +110,7 @@ deps = [ "//base", + "//components/crash/core/common:crash_key", "//gpu/command_buffer/common:mailbox", "//ui/gfx/animation", "//ui/gfx/ipc/color",
diff --git a/cc/paint/DEPS b/cc/paint/DEPS index 844d096..2dffad4 100644 --- a/cc/paint/DEPS +++ b/cc/paint/DEPS
@@ -15,6 +15,9 @@ "+components/viz/test", "+gpu/command_buffer", ], + "paint_op_reader.cc": [ + "+components/crash/core/common", + ], "transfer_cache_fuzzer.cc": [ "+components/viz/test", ],
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc index c382ee15..74f8029a 100644 --- a/cc/paint/paint_op_buffer.cc +++ b/cc/paint/paint_op_buffer.cc
@@ -2968,7 +2968,6 @@ bool PaintOpBuffer::Deserialize(const volatile void* input, size_t input_size, const PaintOp::DeserializeOptions& options) { - Reset(); size_t total_bytes_read = 0u; while (total_bytes_read < input_size) { const volatile void* next_op =
diff --git a/cc/paint/paint_op_reader.cc b/cc/paint/paint_op_reader.cc index b9b20e17..37dc646 100644 --- a/cc/paint/paint_op_reader.cc +++ b/cc/paint/paint_op_reader.cc
@@ -17,6 +17,7 @@ #include "base/metrics/histogram_functions.h" #include "base/rand_util.h" #include "base/stl_util.h" +#include "base/strings/string_number_conversions.h" #include "cc/paint/image_transfer_cache_entry.h" #include "cc/paint/paint_cache.h" #include "cc/paint/paint_flags.h" @@ -25,6 +26,7 @@ #include "cc/paint/paint_shader.h" #include "cc/paint/shader_transfer_cache_entry.h" #include "cc/paint/transfer_cache_deserialize_helper.h" +#include "components/crash/core/common/crash_key.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkRRect.h" #include "third_party/skia/include/core/SkSerialProcs.h" @@ -808,9 +810,14 @@ // Don't inline this function so that crash reports can show the caller. NOINLINE void PaintOpReader::SetInvalid(DeserializationError error) { + static crash_reporter::CrashKeyString<4> deserialization_error_crash_key( + "PaintOpReader deserialization error"); base::UmaHistogramEnumeration("GPU.PaintOpReader.DeserializationError", error); if (valid_ && options_.crash_dump_on_failure && base::RandInt(1, 10) == 1) { + crash_reporter::ScopedCrashKeyString crash_key_scope( + &deserialization_error_crash_key, + base::NumberToString(static_cast<int>(error))); base::debug::DumpWithoutCrashing(); } valid_ = false;
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java index dbcbee6f..839ba089 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceTest.java
@@ -113,6 +113,7 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeApplicationTestUtils; import org.chromium.chrome.test.util.ChromeTabUtils; +import org.chromium.chrome.test.util.MenuUtils; import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule; @@ -1986,6 +1987,38 @@ onViewWaiting(withId(R.id.new_tab_incognito_container)).check(matches(isDisplayed())); } + @Test + @MediumTest + @Feature({"StartSurface"}) + // clang-format off + @CommandLineFlags.Add({BASE_PARAMS + "/single"}) + public void testOpenRecentTabOnStartAndTapBackButtonReturnToStartSurface() + throws ExecutionException { + // clang-format on + ChromeTabbedActivity cta = mActivityTestRule.getActivity(); + if (!mImmediateReturn) StartSurfaceTestUtils.pressHomePageButton(cta); + StartSurfaceTestUtils.waitForOverviewVisible( + mLayoutChangedCallbackHelper, mCurrentlyActiveLayout); + StartSurfaceTestUtils.waitForTabModel(cta); + TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0); + + // Taps on the "Recent tabs" menu item. + MenuUtils.invokeCustomMenuActionSync(InstrumentationRegistry.getInstrumentation(), cta, + org.chromium.chrome.R.id.recent_tabs_menu_id); + Assert.assertEquals("The launched tab should have the launch type FROM_START_SURFACE", + TabLaunchType.FROM_START_SURFACE, + cta.getActivityTabProvider().get().getLaunchType()); + TabUiTestHelper.verifyTabModelTabCount(cta, 2, 0); + + pressBack(); + + // Tap the back on the "Recent tabs" should take us back to the start surface homepage, and + // the Tab should be deleted. + StartSurfaceTestUtils.waitForOverviewVisible( + mLayoutChangedCallbackHelper, mCurrentlyActiveLayout); + TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0); + } + private void backActionDeleteBlankTabForOmniboxFocusedOnNewTabSingleSurface( Runnable backAction) { if (!mImmediateReturn) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index cbe6a15..1939304 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -2010,15 +2010,22 @@ } else if (id == R.id.recent_tabs_menu_id) { LoadUrlParams params = new LoadUrlParams(UrlConstants.RECENT_TABS_URL, PageTransition.AUTO_BOOKMARK); - if (currentTab != null) { + boolean isInOverviewMode = isInOverviewMode(); + if (isInOverviewMode && !isTablet() + && ReturnToChromeExperimentsUtil.isStartSurfaceHomepageEnabled()) { + // When tapping the "Recent tabs" menu item from the overview page (Start surface or + // GTS), we will create the tab with the launch type FROM_START_SURFACE. Thus, if + // the back button is tapped on this "Recent tabs" page, it can go back to the + // overview page. + ReturnToChromeExperimentsUtil.handleLoadUrlFromStartSurface( + params, getCurrentTabModel().isIncognito(), null); + } else if (currentTab != null) { currentTab.loadUrl(params); } else { - // Note that 'currentTab' could be null in overview mode when start surface is - // enabled. getTabCreator(getCurrentTabModel().isIncognito()) .createNewTab(params, TabLaunchType.FROM_CHROME_UI, null); } - if (isInOverviewMode() && !isTablet()) { + if (isInOverviewMode) { mOverviewModeController.hideOverview(true); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java index aa0b25a..4be647e0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/SigninFirstRunFragment.java
@@ -23,7 +23,7 @@ import org.chromium.chrome.browser.firstrun.FirstRunFragment; import org.chromium.chrome.browser.signin.ui.SigninUtils; import org.chromium.chrome.browser.signin.ui.fre.FreUMADialogCoordinator; -import org.chromium.chrome.browser.signin.ui.frebottomgroup.FREBottomGroupCoordinator; +import org.chromium.chrome.browser.signin.ui.fre.SigninFirstRunCoordinator; import org.chromium.components.signin.AccountManagerFacadeProvider; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogManagerHolder; @@ -35,7 +35,7 @@ * This fragment handles the sign-in without sync consent during the FRE. */ public class SigninFirstRunFragment - extends Fragment implements FirstRunFragment, FREBottomGroupCoordinator.Listener { + extends Fragment implements FirstRunFragment, SigninFirstRunCoordinator.Listener { private static final String FOOTER_LINK_OPEN = "<LINK>"; private static final String FOOTER_LINK_CLOSE = "</LINK>"; @@ -43,8 +43,7 @@ static final int ADD_ACCOUNT_REQUEST_CODE = 1; private ModalDialogManager mModalDialogManager; - // TODO(crbug/1186595): Rename the class FREBottomGroupCoordinator to FreBottomGroupCoordinator - private @Nullable FREBottomGroupCoordinator mFREBottomGroupCoordinator; + private @Nullable SigninFirstRunCoordinator mSigninFirstRunCoordinator; private @Nullable FreUMADialogCoordinator mFreUMADialogCoordinator; private boolean mNativeInitialized; @@ -62,8 +61,8 @@ public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final View view = inflater.inflate(R.layout.signin_first_run_view, container, false); - mFREBottomGroupCoordinator = - new FREBottomGroupCoordinator(requireContext(), view, mModalDialogManager, this); + mSigninFirstRunCoordinator = + new SigninFirstRunCoordinator(requireContext(), view, mModalDialogManager, this); final NoUnderlineClickableSpan footerLinkSpan = new NoUnderlineClickableSpan(getResources(), this::onFooterLinkClicked); final SpannableString footerString = SpanApplier.applySpans( @@ -79,7 +78,7 @@ @Override public void onDestroy() { super.onDestroy(); - mFREBottomGroupCoordinator.destroy(); + mSigninFirstRunCoordinator.destroy(); } /** @@ -98,7 +97,7 @@ } /** - * Implements {@link FREBottomGroupCoordinator.Listener}. + * Implements {@link SigninFirstRunCoordinator.Listener}. */ @Override public void addAccount() { @@ -121,23 +120,21 @@ && data != null) { String addedAccountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME); if (addedAccountName != null) { - mFREBottomGroupCoordinator.onAccountSelected(addedAccountName); + mSigninFirstRunCoordinator.onAccountSelected(addedAccountName); } } } - /** - * Implements {@link FREBottomGroupCoordinator.Listener}. - */ + /** Implements {@link SigninFirstRunCoordinator.Listener}. */ @Override public void advanceToNextPage() { getPageDelegate().acceptTermsOfService(true); } private void notifyCoordinatorWhenNativeAndPolicyAreLoaded() { - if (mFREBottomGroupCoordinator != null && mNativeInitialized + if (mSigninFirstRunCoordinator != null && mNativeInitialized && getPageDelegate().getPolicyLoadListener().get() != null) { - mFREBottomGroupCoordinator.onNativeAndPolicyLoaded( + mSigninFirstRunCoordinator.onNativeAndPolicyLoaded( getPageDelegate().getPolicyLoadListener().get()); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java index 080e3654..8ef52b5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java
@@ -45,6 +45,7 @@ import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; import org.chromium.chrome.features.start_surface.StartSurfaceUserData; +import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.embedder_support.util.UrlUtilities; import org.chromium.components.signin.identitymanager.ConsentLevel; import org.chromium.content_public.browser.LoadUrlParams; @@ -322,7 +323,8 @@ } if (params.getTransitionType() == PageTransition.AUTO_BOOKMARK) { - if (params.getReferrer() == null) { + if (!TextUtils.equals(UrlConstants.RECENT_TABS_URL, params.getUrl()) + && params.getReferrer() == null) { RecordUserAction.record("Suggestions.Tile.Tapped.StartSurface"); } } else if (url == null) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java index 08bb405..6fc008e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninFirstRunFragmentTest.java
@@ -180,6 +180,24 @@ @Test @MediumTest + public void testFragmentWhenRemovingChildAccountDynamically() { + mAccountManagerTestRule.addAccount( + CHILD_EMAIL, CHILD_FULL_NAME, /* givenName= */ null, /* avatar= */ null); + TestThreadUtils.runOnUiThreadBlocking(() -> { mFragment.onNativeInitialized(); }); + launchActivityWithFragment(); + + mAccountManagerTestRule.removeAccount(CHILD_EMAIL); + + CriteriaHelper.pollUiThread(() -> { + return !mFragment.getView().findViewById(R.id.signin_fre_selected_account).isShown(); + }); + onView(withText(R.string.signin_add_account_to_device)).check(matches(isDisplayed())); + onView(withText(R.string.signin_fre_dismiss_button)).check(matches(isDisplayed())); + onView(withId(R.id.signin_fre_footer)).check(matches(isDisplayed())); + } + + @Test + @MediumTest public void testFragmentWithDefaultAccount() { TestThreadUtils.runOnUiThreadBlocking(() -> { mFragment.onNativeInitialized(); }); mAccountManagerTestRule.addAccount(TEST_EMAIL1, FULL_NAME1, GIVEN_NAME1, null);
diff --git a/chrome/app/resources/chromium_strings_my.xtb b/chrome/app/resources/chromium_strings_my.xtb index 5f78ef9..45843b23 100644 --- a/chrome/app/resources/chromium_strings_my.xtb +++ b/chrome/app/resources/chromium_strings_my.xtb
@@ -114,7 +114,7 @@ <translation id="4407044323746248786">မည်သို့ပင်ဖြစ်စေ Chromium မှ ထွက်လိုပါသလား။</translation> <translation id="4415566066719264597">Chromium ကို နောက်ခံတွင် ဖွင့်ခွင့်ပေးပါ</translation> <translation id="4423735387467980091">Chromium ကို စိတ်ကြိုက် ပြုပြင်ရန် နှင့် ထိန်းချုပ်ရန်</translation> -<translation id="452711251841752011">Chromium မှ ကြိုဆိုပါသည်၊ ဘရောင်ဇာဝင်းဒိုးအသစ် ဖွင့်လိုက်ပါပြီ</translation> +<translation id="452711251841752011">Chromium က ကြိုဆိုပါသည်၊ ဘရောင်ဇာဝင်းဒိုးအသစ် ဖွင့်လိုက်ပါပြီ</translation> <translation id="4544142686420020088">Chromium အပ်ဒိတ်လုပ်၍ မရပါ၊ တစ်ခုခု မှားသွားသည်။ <ph name="BEGIN_LINK" />Chromium အပ်ဒိတ်ပြဿနာများနှင့် လုပ်၍မရသော အပ်ဒိတ်များကို ပြင်ဆင်ပါ။<ph name="END_LINK" /></translation> <translation id="454579500955453258">Chromium ပရိုဖိုင်အသစ်တွင် ဆက်လုပ်မလား။</translation> <translation id="4567424176335768812">သင်သည် <ph name="USER_EMAIL_ADDRESS" /> အဖြစ် လက်မှတ်ထိုး ဝင်ထားသည်။ သင်သည် ယခုတော့ သင် လက်မှတ်ထိုး ဝင်ထားသည့် ကိရိယာ အားလုံးတို့မှာ သင်၏ စာညှပ်များ၊ မှတ်တမ်း၊ နှင့် အခြား ဆက်တင်များကို ရယူသုံးနိုင်ပါပြီ။</translation> @@ -155,7 +155,7 @@ <translation id="5698481217667032250">Chromium ကို ဤဘာသာစကားဖြင့် ပြသပါ</translation> <translation id="5820394555380036790">Chromium OS</translation> <translation id="5854740544000584380"><ph name="BEGIN_LINK_LINUX_OSS" />Linux ဆော့ဖ်ဝဲရေးဆွဲမှု ပတ်ဝန်းကျင်<ph name="END_LINK_LINUX_OSS" /> တွင် <ph name="BEGIN_LINK_CROS_OSS" />အခမဲ့ ရင်းမြစ်ဆော့ဖ်ဝဲ<ph name="END_LINK_CROS_OSS" /> ထပ်ဆောင်းဖြည့်ခြင်းဖြင့် Chromium OS ကို ရေးဆွဲထားသည်။</translation> -<translation id="5862307444128926510">Chromium မှ ကြိုဆိုပါ၏</translation> +<translation id="5862307444128926510">Chromium က ကြိုဆိုပါ၏</translation> <translation id="5883558403894052917">ဤအရာများတွင် မဲလ်ဝဲပါဝင်သည်ကို Chromium ကတွေ့ထားသည်-</translation> <translation id="5895138241574237353">ပြန်စတင်မည</translation> <translation id="5903106910045431592"><ph name="PAGE_TITLE" /> - ကွန်ရက် လက်မှတ်ထိုးဝင်ခြင်း</translation>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb index d4ffbff6..c380e2f 100644 --- a/chrome/app/resources/generated_resources_am.xtb +++ b/chrome/app/resources/generated_resources_am.xtb
@@ -4234,6 +4234,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{<ph name="ATTACHMENTS" />ን ከ<ph name="DEVICE_NAME" /> መቀበል አልተሳካም}one{<ph name="ATTACHMENTS" />ን ከ<ph name="DEVICE_NAME" /> መቀበል አልተሳካም}other{<ph name="ATTACHMENTS" />ን ከ<ph name="DEVICE_NAME" /> መቀበል አልተሳካም}}</translation> <translation id="5502500733115278303">ከFirefox የመጣ</translation> <translation id="5502915260472117187">ልጅ</translation> +<translation id="5503356662318814623">መልዕክት ላክ</translation> <translation id="5503982651688210506"><ph name="HOST" /> የእርስዎን ካሜራ እንዲጠቀም እና እንዲያንቀሳቅስ መፍቀዱን ይቀጥሉ እና የእርስዎን ማይክሮፎን ይጠቀሙ</translation> <translation id="5504909642107847870">የግላዊነት እና የደህንነት ግምገማ</translation> <translation id="5505264765875738116">ጣቢያዎች ማሳወቂያዎችን ለመላክ መጠየቅ አይችሉም</translation> @@ -4490,6 +4491,7 @@ <translation id="5794414402486823030">ሁልጊዜ ከስርዓት ተመልካች ጋር ይክፈቱ</translation> <translation id="5794700615121138172">የተጋሩ የLinux አቃፊዎች</translation> <translation id="5794786537412027208">ከሁሉም የChrome መተግበሪያዎች ውጣ</translation> +<translation id="5796485699458186843">አዲስ ማንነት የማያሳውቅ እና ትር</translation> <translation id="5797521893972859201">በፍለጋ ሳጥኑ ውስጥ ጨምሮ ታሪክን ያጸዳል</translation> <translation id="5798079537501238810">ጣቢያዎች የክፍያ ተቆጣጣሪዎችን መጫን ይችላሉ</translation> <translation id="579915268381781820">የእርስዎ የደህንነት ቁልፍ ተወግዷል።</translation> @@ -6511,10 +6513,12 @@ <translation id="7952904276017482715">የተጠበቀው መታወቂያ «<ph name="EXPECTED_ID" />» ነበር፣ ነገር ግን መታወቂያው «<ph name="NEW_ID" />» ነበር</translation> <translation id="7953669802889559161">ግቤቶች</translation> <translation id="7953955868932471628">አቋራጮችን ያቀናብሩ</translation> +<translation id="7955105108888461311">በአካል ጠይቅ</translation> <translation id="7956373551960864128">የእርስዎ የተቀመጡ አታሚዎች</translation> <translation id="7957074856830851026">እንደ የመለያ ቁጥሩ ወይም የእሴት መታወቂያ ያለ የመሣሪያ መረጃን ይመልከቱ</translation> <translation id="7957615753207896812">የሰሌዳ ቁልፍ የመሣሪያ ቅንብሮችን ክፈት</translation> <translation id="7959074893852789871">ፋይሉ አንዳንዶቹ እንዲገቡ ያልተደረጉ በርካታ የእውቅና ማረጋገጫዎችን ይዟል፦</translation> +<translation id="7959665254555683862">አዲስ ማንነት የማያሳውቅ እና ትር</translation> <translation id="7961015016161918242">በፍጹም</translation> <translation id="7963001036288347286">የመዳሰሻ ሰሌዳ ማፍጠኛ</translation> <translation id="7963608432878156675">ይህ ስም ለሌሎች መሳሪያዎች ለብሉቱዝ እና ለአውታረ መረብ ግንኙነቶች ይታያል</translation>
diff --git a/chrome/app/resources/generated_resources_as.xtb b/chrome/app/resources/generated_resources_as.xtb index 7eff019..57e3af0 100644 --- a/chrome/app/resources/generated_resources_as.xtb +++ b/chrome/app/resources/generated_resources_as.xtb
@@ -4239,6 +4239,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{<ph name="DEVICE_NAME" />ৰ পৰা <ph name="ATTACHMENTS" /> লাভ কৰিব পৰা নগ’ল}one{<ph name="DEVICE_NAME" />ৰ পৰা <ph name="ATTACHMENTS" /> লাভ কৰিব পৰা নগ’ল}other{<ph name="DEVICE_NAME" />ৰ পৰা <ph name="ATTACHMENTS" /> লাভ কৰিব পৰা নগ’ল}}</translation> <translation id="5502500733115278303">Firefoxৰ পৰা আমদানি কৰা হৈছে</translation> <translation id="5502915260472117187">এটি শিশু</translation> +<translation id="5503356662318814623">এটা বাৰ্তা পঠিয়াওক</translation> <translation id="5503982651688210506"><ph name="HOST" />ক আপোনাৰ কেমেৰা ব্যৱহাৰ আৰু লৰচৰ কৰিবলৈ আৰু আপোনাৰ মাইক্ৰ’ফ’ন ব্যৱহাৰ কৰিবলৈ দিয়াটো অব্যাহত ৰাখক</translation> <translation id="5504909642107847870">গোপনীয়তা আৰু সুৰক্ষাৰ পৰ্যালোচনা</translation> <translation id="5505264765875738116">ছাইটসমূহে জাননী পঠিয়াবলৈ ক’ব নোৱাৰে</translation> @@ -4495,6 +4496,7 @@ <translation id="5794414402486823030">সদায় ছিষ্টেম ভিউৱাৰৰ জৰিয়তে খোলক</translation> <translation id="5794700615121138172">Linuxৰ শ্বেয়াৰ কৰা ফ’ল্ডাৰসমূহ</translation> <translation id="5794786537412027208">সকলো Chrome এপৰ পৰা বাহিৰ হওঁক</translation> +<translation id="5796485699458186843">নতুন ইনক’গ্নিট’ টেব</translation> <translation id="5797521893972859201">সন্ধানৰ বাকচটোত থকাসমূহকে ধৰি ব্ৰাউজিঙৰ ইতিহাস মচে</translation> <translation id="5798079537501238810">ছাইটে পৰিশোধ নিয়ন্ত্ৰক ইনষ্টল কৰিব পাৰে</translation> <translation id="579915268381781820">আপোনাৰ সুৰক্ষাৰ চাবিটো আঁতৰোৱা হৈছিল।</translation> @@ -6515,10 +6517,12 @@ <translation id="7952904276017482715">প্ৰত্যাশিত আইডি "<ph name="EXPECTED_ID" />", কিন্তু আইডিটো "<ph name="NEW_ID" />" আছিল</translation> <translation id="7953669802889559161">ইনপুট</translation> <translation id="7953955868932471628">শ্বৰ্টকাট পৰিচালনা কৰক</translation> +<translation id="7955105108888461311">ব্যক্তিগতভাৱে সোধক</translation> <translation id="7956373551960864128">আপুনি ছেভ কৰি থোৱা প্ৰিণ্টাৰবোৰ</translation> <translation id="7957074856830851026">ক্ৰমিক নম্বৰ অথবা সম্পদৰ আইডিৰ দৰে ডিভাইচৰ তথ্য চাওক</translation> <translation id="7957615753207896812">কীব’র্ড ডিভাইচৰ ছেটিংসমূহ খোলক</translation> <translation id="7959074893852789871">ফাইলটোত একাধিক প্ৰমাণপত্ৰ আছে আৰু তাৰে কেইখনমান আমদানি কৰা হোৱা নাই:</translation> +<translation id="7959665254555683862">নতুন ইনক’গ্নিট’ টেব</translation> <translation id="7961015016161918242">কেতিয়াও নহয়</translation> <translation id="7963001036288347286">টাচ্পেডৰ এক্সিলাৰেশ্বন</translation> <translation id="7963608432878156675">ব্লুটুথ আৰু নেটৱৰ্ক সংযোগৰ বাবে এই নামটো অন্য ডিভাইচসমূহে দেখা পায়</translation>
diff --git a/chrome/app/resources/generated_resources_az.xtb b/chrome/app/resources/generated_resources_az.xtb index 8d520e1..c91d11e 100644 --- a/chrome/app/resources/generated_resources_az.xtb +++ b/chrome/app/resources/generated_resources_az.xtb
@@ -4223,6 +4223,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{<ph name="DEVICE_NAME" /> cihazından <ph name="ATTACHMENTS" /> almaq alınmadı}other{<ph name="DEVICE_NAME" /> cihazından <ph name="ATTACHMENTS" /> almaq alınmadı}}</translation> <translation id="5502500733115278303">Firefox'dan import edilib</translation> <translation id="5502915260472117187">Uşaq</translation> +<translation id="5503356662318814623">Mesaj göndərin</translation> <translation id="5503982651688210506"><ph name="HOST" /> hostuna kameranızı istifadə etmək və hərəkət etdirmək və mikrofonunuzu istifadə etmək icazəsi verməyə davam edin</translation> <translation id="5504909642107847870">Məxfilik və təhlükəsizliyin nəzərdən keçirilməsi</translation> <translation id="5505264765875738116">Saytlar bildiriş göndərilməsini tələb edə bilməz</translation> @@ -4479,6 +4480,7 @@ <translation id="5794414402486823030">Həmişə sistem izləyici ilə açın</translation> <translation id="5794700615121138172">Linux'un paylaşılan qovluqları</translation> <translation id="5794786537412027208">Bütün Chrome Tətbiqlərindən çıxın</translation> +<translation id="5796485699458186843">Yeni Anonim &tab</translation> <translation id="5797521893972859201">Axtarış bölməsindəki daxil olmaqla, tarixçəni silir</translation> <translation id="5798079537501238810">Saytlar ödəniş emalçılarını quraşdıra bilər</translation> <translation id="579915268381781820">Təhlükəsizlik açarınız silindi.</translation> @@ -6497,10 +6499,12 @@ <translation id="7952904276017482715">Gözlənilən ID "<ph name="EXPECTED_ID" />"olsa da, artırmanın ID-si "<ph name="NEW_ID" />" idi</translation> <translation id="7953669802889559161">Daxiletmələr</translation> <translation id="7953955868932471628">Qısayolları idarə edin</translation> +<translation id="7955105108888461311">Şəxsən soruşun</translation> <translation id="7956373551960864128">Yadda saxlanılmış printerlər</translation> <translation id="7957074856830851026">Seriya nömrəsi və aktiv ID-si kimi cihaz məlumatlarına baxın</translation> <translation id="7957615753207896812">Klaviatura cihaz ayarlarını açın</translation> <translation id="7959074893852789871">Fayl bəziləri import olunmayan çoxsaylı sertifikatlardan ibarətdir:</translation> +<translation id="7959665254555683862">Yeni Anonim &Tab</translation> <translation id="7961015016161918242">Heç vaxt</translation> <translation id="7963001036288347286">Taçpedin sürəti</translation> <translation id="7963608432878156675">Bu ad Bluetooth və şəbəkə bağlantıları olan digər cihazlara görünür</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb index fa7539b..5b6adfc 100644 --- a/chrome/app/resources/generated_resources_cs.xtb +++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -4227,6 +4227,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{Přijetí dat (<ph name="ATTACHMENTS" />) ze zařízení <ph name="DEVICE_NAME" /> se nezdařilo}few{Přijetí dat (<ph name="ATTACHMENTS" />) ze zařízení <ph name="DEVICE_NAME" /> se nezdařilo}many{Přijetí dat (<ph name="ATTACHMENTS" />) ze zařízení <ph name="DEVICE_NAME" /> se nezdařilo}other{Přijetí dat (<ph name="ATTACHMENTS" />) ze zařízení <ph name="DEVICE_NAME" /> se nezdařilo}}</translation> <translation id="5502500733115278303">Importováno z Firefoxu</translation> <translation id="5502915260472117187">Dítě</translation> +<translation id="5503356662318814623">Poslat zprávu</translation> <translation id="5503982651688210506">Povolit webu <ph name="HOST" /> používat a natáčet kameru a používat mikrofon i nadále</translation> <translation id="5504909642107847870">Shrnutí ochrany soukromí a zabezpečení</translation> <translation id="5505264765875738116">Weby nemohou žádat o oprávnění zasílat vám oznámení</translation> @@ -4483,6 +4484,7 @@ <translation id="5794414402486823030">Vždy otevřít pomocí systémového prohlížeče</translation> <translation id="5794700615121138172">Sdílené složky Linuxu</translation> <translation id="5794786537412027208">Ukončit všechny aplikace Chrome</translation> +<translation id="5796485699458186843">Nová anonymní kar&ta</translation> <translation id="5797521893972859201">Vymaže historii, včetně vyhledávacího pole</translation> <translation id="5798079537501238810">Weby mohou instalovat obslužné nástroje plateb</translation> <translation id="579915268381781820">Bezpečnostní klíč byl odpojen.</translation> @@ -6503,10 +6505,12 @@ <translation id="7952904276017482715">Bylo očekáváno ID <ph name="EXPECTED_ID" />, ale bylo použito ID <ph name="NEW_ID" /></translation> <translation id="7953669802889559161">Metody zadávání</translation> <translation id="7953955868932471628">Spravovat zástupce</translation> +<translation id="7955105108888461311">Zeptat se osobně</translation> <translation id="7956373551960864128">Vaše uložené tiskárny</translation> <translation id="7957074856830851026">Zobrazit informace o zařízení, například sériové či evidenční číslo</translation> <translation id="7957615753207896812">Otevřít nastavení klávesnice</translation> <translation id="7959074893852789871">Soubor obsahoval více certifikátů, z nichž některé nebyly importovány:</translation> +<translation id="7959665254555683862">Nová anonymní kar&ta</translation> <translation id="7961015016161918242">Nikdy</translation> <translation id="7963001036288347286">Zrychlení touchpadu</translation> <translation id="7963608432878156675">Název je viditelný pro ostatní zařízení při připojení Bluetooth a připojení k síti</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb index bc53c92b..588b40f 100644 --- a/chrome/app/resources/generated_resources_de.xtb +++ b/chrome/app/resources/generated_resources_de.xtb
@@ -4222,6 +4222,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{Fehler beim Empfangen von <ph name="ATTACHMENTS" /> von <ph name="DEVICE_NAME" />}other{Fehler beim Empfangen von <ph name="ATTACHMENTS" /> von <ph name="DEVICE_NAME" />}}</translation> <translation id="5502500733115278303">Aus Firefox importiert</translation> <translation id="5502915260472117187">Ein Kind</translation> +<translation id="5503356662318814623">Nachricht senden</translation> <translation id="5503982651688210506"><ph name="HOST" /> weiterhin erlauben, meine Kamera zu verwenden und zu bewegen sowie mein Mikrofon zu benutzen</translation> <translation id="5504909642107847870">Datenschutz und Sicherheit prüfen</translation> <translation id="5505264765875738116">Websites können nicht fragen, ob Sie Benachrichtigungen erhalten möchten</translation> @@ -4478,6 +4479,7 @@ <translation id="5794414402486823030">Immer mit System Viewer öffnen</translation> <translation id="5794700615121138172">Freigegebene Linux-Ordner</translation> <translation id="5794786537412027208">Alle Chrome-Apps beenden</translation> +<translation id="5796485699458186843">Neuer Inkognito&tab</translation> <translation id="5797521893972859201">Löscht den Verlauf, auch im Suchfeld</translation> <translation id="5798079537501238810">Websites dürfen Zahlungs-Handler installieren</translation> <translation id="579915268381781820">Ihr Sicherheitsschlüssel wurde entfernt.</translation> @@ -6498,10 +6500,12 @@ <translation id="7952904276017482715">Erwartete ID: "<ph name="EXPECTED_ID" />", tatsächliche ID: "<ph name="NEW_ID" />"</translation> <translation id="7953669802889559161">Eingaben</translation> <translation id="7953955868932471628">Verknüpfungen verwalten</translation> +<translation id="7955105108888461311">Persönlich fragen</translation> <translation id="7956373551960864128">Ihre gespeicherten Drucker</translation> <translation id="7957074856830851026">Geräteinformationen wie Seriennummer oder Asset-ID abrufen</translation> <translation id="7957615753207896812">Tastatureinstellungen öffnen</translation> <translation id="7959074893852789871">Die Datei enthielt mehrere Zertifikate, von denen einige nicht importiert wurden:</translation> +<translation id="7959665254555683862">Neuer Inkognito&tab</translation> <translation id="7961015016161918242">Nie</translation> <translation id="7963001036288347286">Touchpad-Beschleunigung</translation> <translation id="7963608432878156675">Dieser Name ist für andere Geräte als Bluetooth- und Netzwerkverbindung sichtbar</translation>
diff --git a/chrome/app/resources/generated_resources_eu.xtb b/chrome/app/resources/generated_resources_eu.xtb index 5be0618..2035487a 100644 --- a/chrome/app/resources/generated_resources_eu.xtb +++ b/chrome/app/resources/generated_resources_eu.xtb
@@ -5805,7 +5805,7 @@ <translation id="7250616558727237648">Edukia partekatzeko erabiltzen ari zaren gailuak ez dio erantzun fitxategia onartu edo baztertzeko eskaerari. Saiatu berriro.</translation> <translation id="725109152065019550">Administratzaileak kanpoko memoria kontu honetan erabiltzeko aukera desgaitu du.</translation> <translation id="7251346854160851420">Horma-paper lehenetsia</translation> -<translation id="7251635775446614726">Administratzaileak hau dio: "<ph name="CUSTOM_MESSAGE" />"</translation> +<translation id="7251635775446614726">Administratzaileak hau dio: "<ph name="CUSTOM_MESSAGE" />".</translation> <translation id="7251979364707973467"><ph name="WEBSITE" /> webguneak segurtasun-giltza jaulki du eta haren ID zenbakia jakin nahi du. Horrela, zer segurtasun-giltza darabilzun jakingo du zehatz-mehatz.</translation> <translation id="7253521419891527137">&Lortu informazio gehiago</translation> <translation id="7254951428499890870">Ziur "<ph name="APP_NAME" />" diagnostiko moduan abiarazi nahi duzula?</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb index 499b6ac..f359190 100644 --- a/chrome/app/resources/generated_resources_fa.xtb +++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -4240,6 +4240,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{دریافت <ph name="ATTACHMENTS" /> از <ph name="DEVICE_NAME" /> ناموفق بود}one{دریافت <ph name="ATTACHMENTS" /> از <ph name="DEVICE_NAME" /> ناموفق بود}other{دریافت <ph name="ATTACHMENTS" /> از <ph name="DEVICE_NAME" /> ناموفق بود}}</translation> <translation id="5502500733115278303">وارد شده از Firefox</translation> <translation id="5502915260472117187">کودک</translation> +<translation id="5503356662318814623">ارسال پیام</translation> <translation id="5503982651688210506">ادامه دهید به <ph name="HOST" /> اجازه دهید از دوربینتان استفاده کند و آن را حرکت دهد، و از میکروفونتان استفاده کند</translation> <translation id="5504909642107847870">مرور امنیتی و حریمخصوصی</translation> <translation id="5505264765875738116">سایتها نمیتوانند برای ارسال اعلان درخواست دهند</translation> @@ -4496,6 +4497,7 @@ <translation id="5794414402486823030">همیشه با نظارهگر سیستم باز شود</translation> <translation id="5794700615121138172">پوشههای همرسانیشده Linux</translation> <translation id="5794786537412027208">خروج از همه برنامههای Chrome</translation> +<translation id="5796485699458186843">برگه ناشناس جدید</translation> <translation id="5797521893972859201">سابقهها، ازجمله سابقه موجود در چارگوش جستجو پاک میشود</translation> <translation id="5798079537501238810">سایتها میتوانند کنترلکننده پرداخت نصب کنند</translation> <translation id="579915268381781820">کلید امنیتیتان برداشته شد.</translation> @@ -6517,10 +6519,12 @@ <translation id="7952904276017482715">شناسه موردانتظار «<ph name="EXPECTED_ID" />» است، اما شناسه «<ph name="NEW_ID" />» بود</translation> <translation id="7953669802889559161">ورودیها</translation> <translation id="7953955868932471628">مدیریت میانبرها</translation> +<translation id="7955105108888461311">درخواست حضوری</translation> <translation id="7956373551960864128">چاپگرهای ذخیرهشده شما</translation> <translation id="7957074856830851026">دیدن اطلاعات دستگاه، مانند شماره سریال یا شناسه دارایی آن</translation> <translation id="7957615753207896812">باز کردن تنظیمات دستگاه صفحه کلید</translation> <translation id="7959074893852789871">این فایل دارای چندین مجوز است، برخی از آنها وارد نشدهاند:</translation> +<translation id="7959665254555683862">برگه ناشناس جدید</translation> <translation id="7961015016161918242">هرگز</translation> <translation id="7963001036288347286">شتاب صفحه لمسی</translation> <translation id="7963608432878156675">برای اتصالات شبکه و بلوتوث، این نام به دستگاههای دیگر نشان داده میشود</translation>
diff --git a/chrome/app/resources/generated_resources_fr-CA.xtb b/chrome/app/resources/generated_resources_fr-CA.xtb index 1604751..c32940d 100644 --- a/chrome/app/resources/generated_resources_fr-CA.xtb +++ b/chrome/app/resources/generated_resources_fr-CA.xtb
@@ -4229,6 +4229,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{Échec de réception de <ph name="ATTACHMENTS" /> de l'appareil <ph name="DEVICE_NAME" />}one{Échec de réception de <ph name="ATTACHMENTS" /> de l'appareil <ph name="DEVICE_NAME" />}other{Échec de réception de <ph name="ATTACHMENTS" /> de l'appareil <ph name="DEVICE_NAME" />}}</translation> <translation id="5502500733115278303">Importés de Firefox</translation> <translation id="5502915260472117187">Un enfant</translation> +<translation id="5503356662318814623">Envoyer un message</translation> <translation id="5503982651688210506">Continuer d'autoriser <ph name="HOST" /> à utiliser et à déplacer votre caméra et à utiliser votre microphone</translation> <translation id="5504909642107847870">Vérification de la confidentialité et de la sécurité</translation> <translation id="5505264765875738116">Les sites ne peuvent pas vous demander l'autorisation d'envoyer des notifications</translation> @@ -4485,6 +4486,7 @@ <translation id="5794414402486823030">Toujours ouvrir avec System Viewer</translation> <translation id="5794700615121138172">Dossiers partagés Linux</translation> <translation id="5794786537412027208">Quitter toutes les applications Chrome</translation> +<translation id="5796485699458186843">&Nouvel onglet de navigation privée</translation> <translation id="5797521893972859201">Efface l'historique, y compris le contenu du champ de recherche</translation> <translation id="5798079537501238810">Les sites peuvent installer des modules de traitement de paiement</translation> <translation id="579915268381781820">Votre clé de sécurité a été retirée.</translation> @@ -6506,10 +6508,12 @@ <translation id="7952904276017482715">Identifiant « <ph name="NEW_ID" /> » reçu au lieu de l'identifiant « <ph name="EXPECTED_ID" /> » attendu</translation> <translation id="7953669802889559161">Entrées</translation> <translation id="7953955868932471628">Gérer les raccourcis</translation> +<translation id="7955105108888461311">Demander en personne</translation> <translation id="7956373551960864128">Vos imprimantes enregistrées</translation> <translation id="7957074856830851026">Consulter des renseignements sur l'appareil, comme son numéro de série ou son identifiant d'appareil</translation> <translation id="7957615753207896812">Ouvrir les paramètres du clavier de l'appareil</translation> <translation id="7959074893852789871">Le fichier contenait plusieurs certificats, dont certains n'ont pas été importés :</translation> +<translation id="7959665254555683862">&Nouvel onglet de navigation privée</translation> <translation id="7961015016161918242">Jamais</translation> <translation id="7963001036288347286">Accélération du pavé tactile</translation> <translation id="7963608432878156675">Ce nom est visible pour d'autres appareils lors des connexions Bluetooth et réseau</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb index c8b176d..99b4a1d 100644 --- a/chrome/app/resources/generated_resources_gu.xtb +++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -100,6 +100,7 @@ <translation id="1103523840287552314"><ph name="LANGUAGE" /> નો હંમેશાં અનુવાદ કરો</translation> <translation id="1108600514891325577">&Stop</translation> <translation id="1110155001042129815">રાહ જુઓ</translation> +<translation id="1110965959145884739">આ ડિવાઇસ પર કઈ ભાષાઓ ઇન્સ્ટૉલ કરવી છે, તે પસંદ કરો. ડિસ્ક સ્પેસ સાચવવા માટે, વપરાશકર્તાઓમાં ભાષાની ફાઇલો શેર કરવામાં આવે છે. <ph name="BEGIN_LINK_LEARN_MORE" />વધુ જાણો<ph name="END_LINK_LEARN_MORE" /></translation> <translation id="1111781754511998498">પ્રોજેક્ટર</translation> <translation id="1112420131909513020">બૅકગ્રાઉન્ડ ટૅબ બ્લૂટૂથનો ઉપયોગ કરી રહ્યું છે</translation> <translation id="1113892970288677790">ક્યુરેટ કરેલા આર્ટવર્ક અને છબીઓ પસંદ કરો</translation> @@ -543,6 +544,7 @@ <translation id="1580772913177567930">તમારા વ્યવસ્થાપકનો સંપર્ક કરો</translation> <translation id="1581962803218266616">ફાઇન્ડર માં બતાવો</translation> <translation id="1582955169539260415">[<ph name="FINGERPRINT_NAME" />] ડિલીટ કરો</translation> +<translation id="1583127975413389276"><ph name="LANGUAGE" /> ભાષા પર ડિવાઇસમાં જ પ્રક્રિયા કરવામાં આવે છે અને તે ઑફલાઇન કામ કરે છે</translation> <translation id="1584990664401018068">તમે ઉપયોગમાં લઈ રહ્યા છો તે વાઇ-ફાઇ (<ph name="NETWORK_ID" />) માટે, પ્રમાણીકરણની જરૂર હોઈ શકે છે.</translation> <translation id="1585717515139318619">તમારા કમ્પ્યુટર પરના બીજા પ્રોગ્રામે કોઇ થીમ ઉમેરી છે જે Chrome ની કાર્યપદ્ધતિમાં ફેરફાર કરી શકે છે. <ph name="EXTENSION_NAME" /></translation> @@ -752,6 +754,7 @@ <translation id="177989070088644880">ઍપ (<ph name="ANDROID_PACKAGE_NAME" />)</translation> <translation id="1780152987505130652">ગ્રૂપ બંધ કરો</translation> <translation id="1780273119488802839">બુકમાર્ક આયાત કરી રહ્યાં છીએ…</translation> +<translation id="178092663238929451">તમારી આસપાસના લોકો પાસેથી ફાઇલો મેળવવા અને મોકલવા માટે, 'નજીકના શેર'ની સુવિધાનું સેટઅપ કરો</translation> <translation id="1781291988450150470">વર્તમાન પિન</translation> <translation id="1781398670452016618"><ph name="DOMAIN" /> માટે જરૂરી છે કે તમે હમણાં વાઇ-ફાઇથી કનેક્ટ થાઓ અને અપડેટ ડાઉનલોડ કરો.</translation> <translation id="1781502536226964113">નવું ટૅબ પૃષ્ઠ ખોલો</translation> @@ -1585,6 +1588,7 @@ <translation id="265390580714150011">ફીલ્ડ મૂલ્ય</translation> <translation id="2654166010170466751">સાઇટોને ચુકવણી હૅન્ડલર ઇન્સ્ટૉલ કરવાની મંજૂરી આપે છે</translation> <translation id="2654553774144920065">પ્રિન્ટ કરવાની વિનંતી</translation> +<translation id="2658941648214598230">ઑરિજિનલ કન્ટેન્ટ બતાવીએ?</translation> <translation id="2659381484350128933"><ph name="FOOTNOTE_POINTER" />ઉપકરણ અનુસાર સુવિધાઓ બદલાય છે</translation> <translation id="2659971421398561408">Crostini ડિસ્કનું કદ બદલો</translation> <translation id="2660779039299703961">ઇવેન્ટ</translation> @@ -2450,6 +2454,7 @@ <translation id="3564848315152754834">USB સુરક્ષા કોડ</translation> <translation id="3566325075220776093">આ ડિવાઇસમાંથી</translation> <translation id="3566721612727112615">કોઈ સાઇટ્સ ઉમેરી નથી</translation> +<translation id="3567284462585300767">તમારી આસપાસના લોકો પાસેથી ફાઇલો મેળવવા અને સ્વીકારવા માટે, દૃશ્યક્ષમ બનો</translation> <translation id="3569382839528428029">શું તમે ઇચ્છો છો કે <ph name="APP_NAME" /> તમારી સ્ક્રીનને શેર કરે?</translation> <translation id="3569407787324516067">સ્ક્રીન સેવર</translation> <translation id="3569682580018832495"><ph name="ORIGIN" /> નીચે આપેલી ફાઇલો અને ફોલ્ડરો જોઈ શકે છે</translation> @@ -3540,6 +3545,7 @@ <translation id="475088594373173692">પ્રથમ વપરાશકર્તા</translation> <translation id="4756378406049221019">રોકો/ફરીથી લોડ કરો</translation> <translation id="4756388243121344051">&ઇતિહાસ</translation> +<translation id="4759126501639448579">યાદગીરીઓ ક્યારેય બતાવશો નહીં</translation> <translation id="4759238208242260848">ડાઉનલોડ્સ</translation> <translation id="4761104368405085019">તમારા માઇક્રોફોનનો ઉપયોગ કરો</translation> <translation id="4762718786438001384">ઉપકરણ ડિસ્ક સ્થાન અત્યંત ઓછું છે</translation> @@ -3864,6 +3870,7 @@ <translation id="51143538739122961">તમારો સુરક્ષા કોડ શામેલ કરો અને તેને સ્પર્શ કરો</translation> <translation id="5115309401544567011">કૃપા કરીને તમારા <ph name="DEVICE_TYPE" />નો પ્લગ કોઈ પાવર સ્રોતમાં જોડો.</translation> <translation id="5115338116365931134">SSO</translation> +<translation id="511632863918093828">બધી યાદગીરીઓ છુપાવેલી છે</translation> <translation id="5116628073786783676">ઑડિયો આ રૂપે સા&ચવો...</translation> <translation id="5117139026559873716">તમારા ફોનને તમારા <ph name="DEVICE_TYPE" />થી ડિસ્કનેક્ટ કરો. તેઓ હવે ઑટોમૅટિક રીતે કનેક્ટ થશે નહીં.</translation> <translation id="5117930984404104619">મુલાકાત લીધેલ URL સહિત, અન્ય એક્સ્ટેન્શન્સની વર્તણૂકનું નિરીક્ષણ કરો</translation> @@ -5009,6 +5016,7 @@ <translation id="6374469231428023295">ફરી પ્રયાસ કરો</translation> <translation id="6377268785556383139">'<ph name="SEARCH_TEXT" />' માટે 1 પરિણામ</translation> <translation id="6380143666419481200">સ્વીકારો અને ચાલુ રાખો</translation> +<translation id="6382958439467370461">કોઈ નિષ્ક્રિય શૉર્ટકટ નથી</translation> <translation id="638418309848716977">સપોર્ટ કરવામાં આવતી લિંક</translation> <translation id="6384275966486438344">આના પર તમારા શોધ સેટિંગ બદલો: <ph name="SEARCH_HOST" /></translation> <translation id="63849924261838903">{NUM_TABS,plural, =1{અનામાંકિત ગ્રૂપ - 1 ટૅબ}one{અનામાંકિત ગ્રૂપ - # ટૅબ}other{અનામાંકિત ગ્રૂપ - # ટૅબ}}</translation> @@ -5885,6 +5893,7 @@ <translation id="7354341762311560488">ફિંગરપ્રિન્ટ સેન્સર એ તમારા કીબોર્ડ પર સૌથી નીચે ડાબી બાજુ સ્થિત કી છે. તેને કોઈપણ આંગળી વડે હળવેથી સ્પર્શ કરો.</translation> <translation id="7356908624372060336">નેટવર્ક લૉગ</translation> <translation id="735745346212279324">VPN ડિસ્કનેક્ટ કર્યું છે</translation> +<translation id="7358324924540718595">આજના માટે યાદગીરીઓ છુપાવેલી છે</translation> <translation id="7360233684753165754"><ph name="PAGE_NUMBER" /> પેજને <ph name="PRINTER_NAME" /> પર મોકલ્યાં</translation> <translation id="7361297102842600584"><ph name="PLUGIN_NAME" /> ચલાવવા માટે રાઇટ-ક્લિક કરો</translation> <translation id="7362387053578559123">સાઇટ બ્લૂટૂથ ડિવાઇસ સાથે કનેક્ટ કરવાનું પૂછી શકે છે</translation> @@ -6285,6 +6294,7 @@ <translation id="7757787379047923882"><ph name="DEVICE_NAME" />માંથી ટેક્સ્ટ શેર કરી</translation> <translation id="7758143121000533418">Family Link</translation> <translation id="7758450972308449809">તમારા ડિસ્પ્લેની સીમાઓને ગોઠવો</translation> +<translation id="7759276754544429366">આજના માટે યાદગીરીઓ છુપાવો</translation> <translation id="7760004034676677601">શું આ તમારી અપેક્ષા મુજબનું સ્ટાર્ટઅપ પૃષ્ઠ છે?</translation> <translation id="7764225426217299476">સરનામું ઉમેરો</translation> <translation id="7764256770584298012"><ph name="DOWNLOAD_DOMAIN" /> પરથી <ph name="DOWNLOAD_RECEIVED" /> પ્રાપ્ત કર્યું</translation> @@ -6948,6 +6958,7 @@ <translation id="8457451314607652708">બુકમાર્ક્સ આયાત કરો</translation> <translation id="8458341576712814616">શૉર્ટકટ</translation> <translation id="8458627787104127436">બધી (<ph name="URL_COUNT" />) URL નવી વિન્ડોમાં ખોલો</translation> +<translation id="8460490661223303637">મેમરી સાચવવા માટે, Chrome દ્વારા અમુક કન્ટેન્ટ કાઢી નાખવામાં આવ્યું છે</translation> <translation id="8460932807646981183">શોધ એન્જિન અને સાઇટમાં શોધવાની સુવિધા મેનેજ કરો</translation> <translation id="84613761564611563">નેટવર્ક કોન્ફિગર UIની વિનંતી કરી, કૃપા કરીને રાહ જુઓ...</translation> <translation id="8461914792118322307">પ્રૉક્સી</translation>
diff --git a/chrome/app/resources/generated_resources_hy.xtb b/chrome/app/resources/generated_resources_hy.xtb index 8d8bebe5..9c4d220 100644 --- a/chrome/app/resources/generated_resources_hy.xtb +++ b/chrome/app/resources/generated_resources_hy.xtb
@@ -4231,6 +4231,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{Չհաջողվեց <ph name="ATTACHMENTS" /> ստանալ <ph name="DEVICE_NAME" /> սարքից}one{Չհաջողվեց <ph name="ATTACHMENTS" /> ստանալ <ph name="DEVICE_NAME" /> սարքից}other{Չհաջողվեց <ph name="ATTACHMENTS" /> ստանալ <ph name="DEVICE_NAME" /> սարքից}}</translation> <translation id="5502500733115278303">Firefox-ից ներմուծված</translation> <translation id="5502915260472117187">Երեխա</translation> +<translation id="5503356662318814623">Ուղարկել SMS</translation> <translation id="5503982651688210506">Թույլատրել <ph name="HOST" /> կայքին օգտագործել և տեղաշարժել տեսախցիկը և օգտագործել խոսափողը</translation> <translation id="5504909642107847870">Ստուգել գաղտնիության և անվտանգության կարգավորումները</translation> <translation id="5505264765875738116">Կայքերը չեն կարող խնդրել ծանուցումներ ուղարկել</translation> @@ -4487,6 +4488,7 @@ <translation id="5794414402486823030">Միշտ բացել համակարգի դիտման ծրագրի միջոցով</translation> <translation id="5794700615121138172">Լինուքսի ընդհանուր պանակներ</translation> <translation id="5794786537412027208">Դուրս գալ Chrome-ի բոլոր հավելվածներից</translation> +<translation id="5796485699458186843">Նոր ինկոգնիտո ներդիր</translation> <translation id="5797521893972859201">Մաքրում է պատմությունը, այդ թվում որոնման դաշտում</translation> <translation id="5798079537501238810">Կայքերը կարող են տեղադրել վճարումների մշակիչներ</translation> <translation id="579915268381781820">Անվտանգության բանալին հեռացվել է:</translation> @@ -6506,10 +6508,12 @@ <translation id="7952904276017482715">Սպասված ID-ն՝ «<ph name="EXPECTED_ID" />», ստացված ID-ն՝ «<ph name="NEW_ID" />»</translation> <translation id="7953669802889559161">Ներածման մեթոդներ</translation> <translation id="7953955868932471628">Կառավարել դյուրանցումները</translation> +<translation id="7955105108888461311">Հարցնել անձամբ</translation> <translation id="7956373551960864128">Ձեր պահված տպիչները</translation> <translation id="7957074856830851026">Տեսնել սարքի մասին տեղեկություններ, օրինակ՝ սերիական համարը և օբյեկտի ID-ն</translation> <translation id="7957615753207896812">Բացել ստեղնաշարի կարգավորումները</translation> <translation id="7959074893852789871">Ֆայլը մի քանի վկայագիր ունի, որոնցից մի քանիսը չեն ներմուծվել՝</translation> +<translation id="7959665254555683862">Նոր ինկոգնիտո ներդիր</translation> <translation id="7961015016161918242">Երբեք</translation> <translation id="7963001036288347286">Հպահարթակի արագացում</translation> <translation id="7963608432878156675">Այս անվանումը կցուցադրվի այլ սարքերում ցանցային և Bluetooth միացումների ժամանակ</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb index 043cb36..664d0ea 100644 --- a/chrome/app/resources/generated_resources_iw.xtb +++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -4243,6 +4243,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{לא ניתן היה לקבל <ph name="ATTACHMENTS" /> מהמכשיר <ph name="DEVICE_NAME" />}two{לא ניתן היה לקבל <ph name="ATTACHMENTS" /> מהמכשיר <ph name="DEVICE_NAME" />}many{לא ניתן היה לקבל <ph name="ATTACHMENTS" /> מהמכשיר <ph name="DEVICE_NAME" />}other{לא ניתן היה לקבל <ph name="ATTACHMENTS" /> מהמכשיר <ph name="DEVICE_NAME" />}}</translation> <translation id="5502500733115278303">ייבוא מ-Firefox</translation> <translation id="5502915260472117187">ילד או ילדה</translation> +<translation id="5503356662318814623">שליחת הודעה</translation> <translation id="5503982651688210506">זה בסדר, אפשר להמשיך להרשות לאתר <ph name="HOST" /> להשתמש במצלמה ולהזיז אותה, ולהשתמש במיקרופון</translation> <translation id="5504909642107847870">בדיקה של הפרטיות והאבטחה</translation> <translation id="5505264765875738116">אתרים לא יכולים לבקש לשלוח התראות</translation> @@ -4499,6 +4500,7 @@ <translation id="5794414402486823030">תמיד לפתוח באמצעות מציג המערכת</translation> <translation id="5794700615121138172">תיקיות משותפות של Linux</translation> <translation id="5794786537412027208">יציאה מכל אפליקציות Chrome</translation> +<translation id="5796485699458186843">&כרטיסיית מצב אנונימי חדשה</translation> <translation id="5797521893972859201">יתבצע ניקוי של ההיסטוריה שבתיבת החיפוש</translation> <translation id="5798079537501238810">אתרים מורשים להתקין רכיבי handler של תשלומים</translation> <translation id="579915268381781820">מפתח האבטחה שלך הוסר.</translation> @@ -6519,10 +6521,12 @@ <translation id="7952904276017482715">המזהה הצפוי הוא "<ph name="EXPECTED_ID" />", אך המזהה היה "<ph name="NEW_ID" />"</translation> <translation id="7953669802889559161">שיטות קלט</translation> <translation id="7953955868932471628">ניהול קיצורי דרך</translation> +<translation id="7955105108888461311">ביצוע בקשה פנים-אל-פנים</translation> <translation id="7956373551960864128">מדפסות שמורות</translation> <translation id="7957074856830851026">הצגה של פרטי המכשיר, כמו המספר הסידורי או מזהה הנכס שלו</translation> <translation id="7957615753207896812">פתיחת הגדרות המכשיר של המקלדת</translation> <translation id="7959074893852789871">הקובץ הכיל אישורים מרובים, חלקם לא יובאו:</translation> +<translation id="7959665254555683862">&כרטיסיית מצב אנונימי חדשה</translation> <translation id="7961015016161918242">אף פעם</translation> <translation id="7963001036288347286">האצת לוח מגע</translation> <translation id="7963608432878156675">השם הזה יוצג למכשירים אחרים בזמן החיבור לרשת או ל-Bluetooth</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb index 18c557a..ddcddea 100644 --- a/chrome/app/resources/generated_resources_ja.xtb +++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -100,6 +100,7 @@ <translation id="1103523840287552314"><ph name="LANGUAGE" />を常に翻訳</translation> <translation id="1108600514891325577">停止(&S)</translation> <translation id="1110155001042129815">待機</translation> +<translation id="1110965959145884739">このデバイスにインストールする言語を選択してください。ディスク領域を節約するため、言語ファイルはユーザー間で共有されます。<ph name="BEGIN_LINK_LEARN_MORE" />詳細<ph name="END_LINK_LEARN_MORE" /></translation> <translation id="1111781754511998498">プロジェクター</translation> <translation id="1112420131909513020">バックグラウンドのタブで Bluetooth が使用されています</translation> <translation id="1113892970288677790">アートワークや画像のライブラリから選択してください</translation> @@ -545,6 +546,7 @@ <translation id="1580772913177567930">管理者にお問い合わせください</translation> <translation id="1581962803218266616">Finder で表示</translation> <translation id="1582955169539260415">[<ph name="FINGERPRINT_NAME" />] を削除</translation> +<translation id="1583127975413389276"><ph name="LANGUAGE" /> はローカルで処理され、オフラインで使用できます</translation> <translation id="1584990664401018068">ご利用の Wi-Fi(<ph name="NETWORK_ID" />)では、認証が必要になる可能性があります。</translation> <translation id="1585717515139318619">パソコン上の別のプログラムにより、Chrome の動作に影響を及ぼす可能性のあるテーマが追加されました。 @@ -755,6 +757,7 @@ <translation id="177989070088644880">アプリ(<ph name="ANDROID_PACKAGE_NAME" />)</translation> <translation id="1780152987505130652">グループを閉じる</translation> <translation id="1780273119488802839">ブックマークをインポートしています...</translation> +<translation id="178092663238929451">近くのユーザーとファイルを送受信するには、ニアバイシェアを設定してください</translation> <translation id="1781291988450150470">現在の PIN</translation> <translation id="1781398670452016618"><ph name="DOMAIN" /> が、Wi-Fi に接続して、今すぐアップデートをダウンロードするよう求めています。</translation> <translation id="1781502536226964113">新しいタブ ページを開く</translation> @@ -1586,6 +1589,7 @@ <translation id="265390580714150011">フィールド値</translation> <translation id="2654166010170466751">サイトに支払いハンドラのインストールを許可する</translation> <translation id="2654553774144920065">印刷リクエスト</translation> +<translation id="2658941648214598230">元のコンテンツを表示しますか?</translation> <translation id="2659381484350128933"><ph name="FOOTNOTE_POINTER" />機能はデバイスによって異なります</translation> <translation id="2659971421398561408">Crostini のディスクサイズ変更</translation> <translation id="2660779039299703961">イベント</translation> @@ -2451,6 +2455,7 @@ <translation id="3564848315152754834">USB セキュリティ キー</translation> <translation id="3566325075220776093">このデバイスから削除</translation> <translation id="3566721612727112615">サイトが追加されていません</translation> +<translation id="3567284462585300767">近くのユーザーとファイルを送受信するには、デバイスを公開してください</translation> <translation id="3569382839528428029"><ph name="APP_NAME" /> と画面を共有しますか?</translation> <translation id="3569407787324516067">スクリーンセーバー</translation> <translation id="3569682580018832495"><ph name="ORIGIN" /> は次のファイルとフォルダを表示できます</translation> @@ -3541,6 +3546,7 @@ <translation id="475088594373173692">最初のユーザー</translation> <translation id="4756378406049221019">停止 / 再読み込み</translation> <translation id="4756388243121344051">履歴(&H)</translation> +<translation id="4759126501639448579">思い出を表示しない</translation> <translation id="4759238208242260848">ダウンロード</translation> <translation id="4761104368405085019">マイクを使用する</translation> <translation id="4762718786438001384">デバイスのディスク空き領域が非常に少なくなっています</translation> @@ -3865,6 +3871,7 @@ <translation id="51143538739122961">セキュリティ キーを挿入し、タップしてください</translation> <translation id="5115309401544567011"><ph name="DEVICE_TYPE" /> を電源に接続してください。</translation> <translation id="5115338116365931134">SSO</translation> +<translation id="511632863918093828">すべての思い出を非表示にしました</translation> <translation id="5116628073786783676">名前を付けてオーディオを保存(&V)...</translation> <translation id="5117139026559873716"><ph name="DEVICE_TYPE" /> からスマートフォンを切断します。以降、自動接続は行われなくなります。</translation> <translation id="5117930984404104619">他の拡張機能の動作を監視(アクセスした URL を含む)</translation> @@ -4219,6 +4226,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{<ph name="DEVICE_NAME" /> から <ph name="ATTACHMENTS" />を受け取れませんでした}other{<ph name="DEVICE_NAME" /> から <ph name="ATTACHMENTS" />を受け取れませんでした}}</translation> <translation id="5502500733115278303">Firefox ブックマーク</translation> <translation id="5502915260472117187">お子様</translation> +<translation id="5503356662318814623">メッセージを送信する</translation> <translation id="5503982651688210506"><ph name="HOST" /> によるカメラの使用と移動、およびマイクの使用を引き続き許可する</translation> <translation id="5504909642107847870">プライバシーとセキュリティの確認</translation> <translation id="5505264765875738116">通知を送信するかどうかの確認をサイトに許可しない</translation> @@ -4475,6 +4483,7 @@ <translation id="5794414402486823030">常にシステム ビューアで開く</translation> <translation id="5794700615121138172">Linux の共有フォルダ</translation> <translation id="5794786537412027208">すべての Chrome アプリを終了</translation> +<translation id="5796485699458186843">新しいシークレット タブ(&T)</translation> <translation id="5797521893972859201">検索ボックスなどの履歴を削除します</translation> <translation id="5798079537501238810">サイトが支払いハンドラをインストールできるようにする</translation> <translation id="579915268381781820">セキュリティ キーは削除されています。</translation> @@ -5008,6 +5017,7 @@ <translation id="6374469231428023295">再試行</translation> <translation id="6377268785556383139">「<ph name="SEARCH_TEXT" />」に対する 1 件の検索結果</translation> <translation id="6380143666419481200">同意して続行</translation> +<translation id="6382958439467370461">無効なショートカットは見つかりませんでした</translation> <translation id="638418309848716977">対応リンク</translation> <translation id="6384275966486438344">検索設定を次に変更します: <ph name="SEARCH_HOST" /></translation> <translation id="63849924261838903">{NUM_TABS,plural, =1{名前のないグループ - 1 個のタブ}other{名前のないグループ - # 個のタブ}}</translation> @@ -5884,6 +5894,7 @@ <translation id="7354341762311560488">指紋認証センサーはキーボードの左下のキーに搭載されています。いずれかの指で軽く触れてください。</translation> <translation id="7356908624372060336">ネットワーク ログ</translation> <translation id="735745346212279324">VPN が切断されました</translation> +<translation id="7358324924540718595">今日の思い出を非表示にしました</translation> <translation id="7360233684753165754"><ph name="PAGE_NUMBER" /> ページを <ph name="PRINTER_NAME" /> に送信しました</translation> <translation id="7361297102842600584">右クリックして <ph name="PLUGIN_NAME" /> を実行します</translation> <translation id="7362387053578559123">サイトが Bluetooth デバイスへの接続を要求できるようにする</translation> @@ -6284,6 +6295,7 @@ <translation id="7757787379047923882"><ph name="DEVICE_NAME" /> からテキストが共有されました</translation> <translation id="7758143121000533418">ファミリー リンク</translation> <translation id="7758450972308449809">ディスプレイの外枠を調整します</translation> +<translation id="7759276754544429366">今日の思い出を非表示にする</translation> <translation id="7760004034676677601">この起動ページでよろしいですか?</translation> <translation id="7764225426217299476">住所を追加</translation> <translation id="7764256770584298012"><ph name="DOWNLOAD_RECEIVED" />(<ph name="DOWNLOAD_DOMAIN" /> から)</translation> @@ -6492,10 +6504,12 @@ <translation id="7952904276017482715">ID「<ph name="EXPECTED_ID" />」が必要ですが、ID「<ph name="NEW_ID" />」が検出されました</translation> <translation id="7953669802889559161">入力方法</translation> <translation id="7953955868932471628">ショートカットの管理</translation> +<translation id="7955105108888461311">直接リクエストする</translation> <translation id="7956373551960864128">保存されているプリンタ</translation> <translation id="7957074856830851026">シリアル番号やアセット ID などのデバイス情報を読み取る</translation> <translation id="7957615753207896812">キーボードのデバイス設定を開く</translation> <translation id="7959074893852789871">ファイルに含まれる複数の証明書のうち、一部をインポートできませんでした:</translation> +<translation id="7959665254555683862">新しいシークレット タブ(&T)</translation> <translation id="7961015016161918242">使用しない</translation> <translation id="7963001036288347286">タッチパッド アクセラレーション</translation> <translation id="7963608432878156675">この名前は、他のデバイスの Bluetooth やネットワーク接続で表示されます</translation> @@ -6952,6 +6966,7 @@ <translation id="8457451314607652708">ブックマークをインポート</translation> <translation id="8458341576712814616">ショートカット</translation> <translation id="8458627787104127436">新しいウィンドウですべて開く(<ph name="URL_COUNT" /> 件の URL)</translation> +<translation id="8460490661223303637">メモリを節約するため、Chrome により一部のコンテンツが削除されました</translation> <translation id="8460932807646981183">検索エンジンとサイト内検索を管理する</translation> <translation id="84613761564611563">ネットワーク設定画面を呼び出しています。しばらくお待ちください...</translation> <translation id="8461914792118322307">プロキシ</translation>
diff --git a/chrome/app/resources/generated_resources_kk.xtb b/chrome/app/resources/generated_resources_kk.xtb index 5b32816df..180d970 100644 --- a/chrome/app/resources/generated_resources_kk.xtb +++ b/chrome/app/resources/generated_resources_kk.xtb
@@ -4223,6 +4223,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{<ph name="DEVICE_NAME" /> құрылғысынан <ph name="ATTACHMENTS" /> алынбады.}other{<ph name="DEVICE_NAME" /> құрылғысынан <ph name="ATTACHMENTS" /> алынбады.}}</translation> <translation id="5502500733115278303">Firefox браузерінен импортталған</translation> <translation id="5502915260472117187">Бала</translation> +<translation id="5503356662318814623">Хабар жіберу</translation> <translation id="5503982651688210506"><ph name="HOST" /> сайтына камераны пайдалануға және жылжытуға, микрофонды пайдалануға рұқсат ету</translation> <translation id="5504909642107847870">Құпиялылық және қауіпсіздік параметрлерін тексеру</translation> <translation id="5505264765875738116">Сайттар хабарландырулар жіберу рұқсатын сұрай алмайды</translation> @@ -4479,6 +4480,7 @@ <translation id="5794414402486823030">Әрқашан жүйе көру құралымен ашу</translation> <translation id="5794700615121138172">Linux ортақ қалталары</translation> <translation id="5794786537412027208">Барлық Chrome қолданбаларынан шығу</translation> +<translation id="5796485699458186843">Жаңа инкогнито қойындысы</translation> <translation id="5797521893972859201">Тарих және іздеу өрісіндегі дерек өшіріледі.</translation> <translation id="5798079537501238810">Сайттар төлем өңдегіштерін орната алады.</translation> <translation id="579915268381781820">Қауіпсіздік кілтіңіз өшірілді.</translation> @@ -6499,10 +6501,12 @@ <translation id="7952904276017482715">"<ph name="NEW_ID" />" идентификаторы күтілген "<ph name="EXPECTED_ID" />" идентификаторына сәйкес келмейді</translation> <translation id="7953669802889559161">Енгізу әдістері</translation> <translation id="7953955868932471628">Таңбашаларды басқару</translation> +<translation id="7955105108888461311">Жеке сұрау</translation> <translation id="7956373551960864128">Сақталған принтерлер</translation> <translation id="7957074856830851026">Сериялық нөмір және актив идентификаторы сияқты құрылғы ақпаратын көру</translation> <translation id="7957615753207896812">Пернетақта құрылғысының параметрлерін ашу</translation> <translation id="7959074893852789871">Файлда кейбіреулері импортталмаған көптеген сертификаттар бар:</translation> +<translation id="7959665254555683862">Жаңа инкогнито қойындысы</translation> <translation id="7961015016161918242">Ешқашан</translation> <translation id="7963001036288347286">Сенсорлық тақтаны жылдамдату</translation> <translation id="7963608432878156675">Бұл атау Bluetooth және желі байланыстары үшін басқа құрылғыларға көрінеді.</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb index 187bb59..6611828 100644 --- a/chrome/app/resources/generated_resources_ko.xtb +++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -4240,6 +4240,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{<ph name="DEVICE_NAME" />에서 <ph name="ATTACHMENTS" /> 수신 실패}other{<ph name="DEVICE_NAME" />에서 <ph name="ATTACHMENTS" /> 수신 실패}}</translation> <translation id="5502500733115278303">Firefox에서 가져온 북마크</translation> <translation id="5502915260472117187">자녀</translation> +<translation id="5503356662318814623">메시지 보내기</translation> <translation id="5503982651688210506"><ph name="HOST" />의 카메라 사용 및 이동과 마이크 사용을 계속 허용</translation> <translation id="5504909642107847870">개인 정보 보호 및 보안 검토</translation> <translation id="5505264765875738116">사이트에서 알림 전송 허용을 요청할 수 없음</translation> @@ -4496,6 +4497,7 @@ <translation id="5794414402486823030">항상 시스템 뷰어로 열기</translation> <translation id="5794700615121138172">Linux 공유 폴더</translation> <translation id="5794786537412027208">모든 Chrome 앱 종료</translation> +<translation id="5796485699458186843">새 시크릿 탭(&T)</translation> <translation id="5797521893972859201">검색창에 입력한 내용을 비롯한 기록 삭제</translation> <translation id="5798079537501238810">사이트에서 결제 핸들러를 설치할 수 있음</translation> <translation id="579915268381781820">보안 키가 삭제되었습니다.</translation> @@ -6517,10 +6519,12 @@ <translation id="7952904276017482715">ID로 '<ph name="EXPECTED_ID" />'을(를) 예상했으나 '<ph name="NEW_ID" />'이(가) 표시되었습니다</translation> <translation id="7953669802889559161">입력</translation> <translation id="7953955868932471628">단축키 관리</translation> +<translation id="7955105108888461311">직접 요청</translation> <translation id="7956373551960864128">저장한 프린터</translation> <translation id="7957074856830851026">일련번호 또는 기기 ID와 같은 기기 정보 보기</translation> <translation id="7957615753207896812">키보드 기기 설정 열기</translation> <translation id="7959074893852789871">파일에 여러 인증서가 있지만 그 중 일부를 가져올 수 없습니다.</translation> +<translation id="7959665254555683862">새 시크릿 탭(&T)</translation> <translation id="7961015016161918242">사용하지 않음</translation> <translation id="7963001036288347286">터치패드 가속</translation> <translation id="7963608432878156675">블루투스와 네트워크 연결 시 다른 기기에 표시되는 이름입니다.</translation>
diff --git a/chrome/app/resources/generated_resources_sq.xtb b/chrome/app/resources/generated_resources_sq.xtb index 467c36e3..4eeb3e8c 100644 --- a/chrome/app/resources/generated_resources_sq.xtb +++ b/chrome/app/resources/generated_resources_sq.xtb
@@ -4224,6 +4224,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{Marrja nga <ph name="DEVICE_NAME" /> dështoi: <ph name="ATTACHMENTS" />}other{Marrja nga <ph name="DEVICE_NAME" /> dështoi: <ph name="ATTACHMENTS" />}}</translation> <translation id="5502500733115278303">Importuar nga Firefox</translation> <translation id="5502915260472117187">Një fëmijë</translation> +<translation id="5503356662318814623">Dërgo një mesazh</translation> <translation id="5503982651688210506">Vazhdo të lejosh që <ph name="HOST" /> të përdorë dhe të lëvizë kamerën dhe të përdorë mikrofonin</translation> <translation id="5504909642107847870">Shqyrtimi i privatësisë dhe sigurisë</translation> <translation id="5505264765875738116">Sajtet nuk mund të kërkojnë të dërgojnë njoftime</translation> @@ -4480,6 +4481,7 @@ <translation id="5794414402486823030">Gjithmonë hape me shikuesin e sistemit</translation> <translation id="5794700615121138172">Skedarët e ndarë të Linux</translation> <translation id="5794786537412027208">Dil nga të gjitha aplikacionet e Chrome</translation> +<translation id="5796485699458186843">Skedë &e re "e fshehtë"</translation> <translation id="5797521893972859201">Pastron historikun, duke përfshirë dhe në kutinë e kërkimit</translation> <translation id="5798079537501238810">Sajtet mund të instalojnë përpunuesit e pagesave</translation> <translation id="579915268381781820">Çelësi yt i sigurisë është hequr.</translation> @@ -6499,10 +6501,12 @@ <translation id="7952904276017482715">ID-ja e pritshme ishte "<ph name="EXPECTED_ID" />", por rezultoi "<ph name="NEW_ID" />"</translation> <translation id="7953669802889559161">Hyrjet</translation> <translation id="7953955868932471628">Menaxho shkurtoret</translation> +<translation id="7955105108888461311">Kërkoja personalisht</translation> <translation id="7956373551960864128">Printerët e tu të ruajtur</translation> <translation id="7957074856830851026">Të shikojë informacionet e pajisjes, të tilla si numri i serisë ose ID-ja e punës</translation> <translation id="7957615753207896812">Hap cilësimet e tastierës së pajisjes</translation> <translation id="7959074893852789871">Skedari përmbante shumë certifikata, disa prej të cilave nuk u importuan:</translation> +<translation id="7959665254555683862">Skedë &e re "e fshehtë"</translation> <translation id="7961015016161918242">Asnjëherë</translation> <translation id="7963001036288347286">Përshpejtimi i bllokut të prekjes</translation> <translation id="7963608432878156675">Ky emër është i dukshëm për pajisjet e tjera për lidhjet me Bluetooth dhe të rrjetit</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb index 10af323..99967f7 100644 --- a/chrome/app/resources/generated_resources_sw.xtb +++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -4237,6 +4237,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{Imeshindwa kupokea <ph name="ATTACHMENTS" /> kutoka kwenye <ph name="DEVICE_NAME" />}other{Imeshindwa kupokea <ph name="ATTACHMENTS" /> kutoka kwenye <ph name="DEVICE_NAME" />}}</translation> <translation id="5502500733115278303">Zilizoingizwa Kutoka Firefox</translation> <translation id="5502915260472117187">Mtoto</translation> +<translation id="5503356662318814623">Tuma ujumbe</translation> <translation id="5503982651688210506">Endelea kuruhusu <ph name="HOST" /> itumie na isogeze kamera na itumie maikrofoni yako</translation> <translation id="5504909642107847870">Ukaguzi wa faragha na usalama</translation> <translation id="5505264765875738116">Tovuti haziwezi kukuuliza kutuma arifa</translation> @@ -4493,6 +4494,7 @@ <translation id="5794414402486823030">Fungua ukitumia kitazamaji cha mfumo wakati wowote</translation> <translation id="5794700615121138172">Folda zinazoshirikiwa za Linux</translation> <translation id="5794786537412027208">Ondoka kwenye Programu zote za Chrome</translation> +<translation id="5796485699458186843">Kichupo kipya &fiche</translation> <translation id="5797521893972859201">Hufuta historia, ikiwa ni pamoja na iliyo kwenye kisanduku cha kutafutia</translation> <translation id="5798079537501238810">Tovuti zinaweza kusakinisha vidhibiti vya malipo</translation> <translation id="579915268381781820">Ufunguo wako wa usalama umeondolewa.</translation> @@ -6516,10 +6518,12 @@ <translation id="7952904276017482715">Ilitarajia kitambulisho cha "<ph name="EXPECTED_ID" />", lakini ikapata "<ph name="NEW_ID" />"</translation> <translation id="7953669802889559161">Mbinu za kuingiza data</translation> <translation id="7953955868932471628">Dhibiti mikato</translation> +<translation id="7955105108888461311">Omba idhini mwenyewe</translation> <translation id="7956373551960864128">Printa ulizohifadhi</translation> <translation id="7957074856830851026">Kuona maelezo ya kifaa, kama vile nambari ya ufuatiliaji au kitambulisho cha kipengee</translation> <translation id="7957615753207896812">Fungua mipangilio ya kifaa ya kibodi</translation> <translation id="7959074893852789871">Faili ina vyeti anuwai, badhii ya vingine ambavyo havikuletwa:</translation> +<translation id="7959665254555683862">Kichupo Kipya &Fiche</translation> <translation id="7961015016161918242">Katu</translation> <translation id="7963001036288347286">Kuongeza kasi ya padi ya kugusa</translation> <translation id="7963608432878156675">Jina hili linaonekana kwenye vifaa vingine kwa ajili ya miunganisho ya Bluetooth na mtandao</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb index ffb299f..0bd9d37 100644 --- a/chrome/app/resources/generated_resources_ta.xtb +++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -102,6 +102,7 @@ <translation id="1103523840287552314">எப்போதும் இந்த மொழியை மொழிபெயர் <ph name="LANGUAGE" /></translation> <translation id="1108600514891325577">&Stop</translation> <translation id="1110155001042129815">காத்திருங்கள்</translation> +<translation id="1110965959145884739">இந்தச் சாதனத்தில் எந்தெந்த மொழிகளை நிறுவ வேண்டும் என்பதைத் தேர்வுசெய்யுங்கள். டிஸ்க் சேமிப்பிடத்தை மிச்சப்படுத்தும் வகையில் மொழி ஃபைல்கள் பயனர்களுடன் பகிரப்படும். <ph name="BEGIN_LINK_LEARN_MORE" />மேலும் அறிக<ph name="END_LINK_LEARN_MORE" /></translation> <translation id="1111781754511998498">Projector</translation> <translation id="1112420131909513020">பின்னணித் தாவல் புளூடூத்தைப் பயன்படுத்துகிறது</translation> <translation id="1113892970288677790">தேர்ந்தெடுக்கப்பட்ட கலைப்படைப்புகளையும் படங்களையும் தேர்வுசெய்க</translation> @@ -548,6 +549,7 @@ <translation id="1580772913177567930">உங்கள் நிர்வாகியைத் தொடர்புகொள்ளவும்</translation> <translation id="1581962803218266616">&கண்டுபிடிப்பானில் காண்பி</translation> <translation id="1582955169539260415">[<ph name="FINGERPRINT_NAME" />] கைரேகையை நீக்கு</translation> +<translation id="1583127975413389276">சாதனம் ஆஃப்லைனில் இருந்தாலும் நீங்கள் <ph name="LANGUAGE" /> மொழியில் பேசுபவை செயலாக்கப்பட்டு அந்த மொழியிலேயே எழுதப்படும்</translation> <translation id="1584990664401018068">பயன்படுத்திக் கொண்டிருக்கும் வைஃபை நெட்வொர்க்குக்கு (<ph name="NETWORK_ID" />) அங்கீகரிப்பு தேவைப்படலாம்.</translation> <translation id="1585717515139318619">உங்கள் கம்ப்யூட்டரில் உள்ள மற்றொரு நிரல் Chrome செயல்படும் முறையை மாற்றக்கூடிய தீம் ஒன்றைச் சேர்த்துள்ளது. @@ -766,6 +768,7 @@ <translation id="177989070088644880">ஆப்ஸ் (<ph name="ANDROID_PACKAGE_NAME" />)</translation> <translation id="1780152987505130652">குழுவை மூடுக</translation> <translation id="1780273119488802839">புக்மார்க்குகளை இறக்குகிறது...</translation> +<translation id="178092663238929451">உங்களைச் சுற்றியுள்ளவர்களிடம் இருந்து ஃபைல்களைப் பெறுவதற்கும் அனுப்புவதற்கும் அருகிலுள்ளவற்றுடன் பகிர்தல் அம்சத்தை அமைத்திடுங்கள்</translation> <translation id="1781291988450150470">தற்போதைய பின்</translation> <translation id="1781398670452016618">இப்போதே வைஃபையுடன் இணைத்து புதுப்பிப்பைப் பதிவிறக்குமாறு <ph name="DOMAIN" /> கோருகிறது.</translation> <translation id="1781502536226964113">புதிய தாவல் பக்கத்தைத் திற</translation> @@ -1602,6 +1605,7 @@ <translation id="265390580714150011">புல மதிப்பு</translation> <translation id="2654166010170466751">பேமண்ட் ஹேண்ட்லர்களை நிறுவுவதற்குத் தளங்களை அனுமதிக்கும்</translation> <translation id="2654553774144920065">பிரிண்ட் செய்வதற்கான கோரிக்கை</translation> +<translation id="2658941648214598230">அசல் உள்ளடக்கத்தைக் காட்டவா?</translation> <translation id="2659381484350128933"><ph name="FOOTNOTE_POINTER" />சாதனத்திற்கேற்ப அம்சங்கள் மாறுபடலாம்</translation> <translation id="2659971421398561408">Crostini டிஸ்க் அளவை மாற்று</translation> <translation id="2660779039299703961">நிகழ்வு</translation> @@ -2467,6 +2471,7 @@ <translation id="3564848315152754834">USB பாதுகாப்பு விசை</translation> <translation id="3566325075220776093">இந்தச் சாதனத்திலிருந்து</translation> <translation id="3566721612727112615">தளங்கள் எதுவும் சேர்க்கப்படவில்லை</translation> +<translation id="3567284462585300767">உங்களைச் சுற்றியுள்ளவர்களிடம் இருந்து ஃபைல்களைப் பெறுவதற்கும் ஏற்பதற்கும் தெரிவுநிலையை ஆன் செய்யுங்கள்</translation> <translation id="3569382839528428029">உங்கள் திரையை <ph name="APP_NAME" /> பகிர்வதற்கு விரும்புகிறீர்களா?</translation> <translation id="3569407787324516067">ஸ்கிரீன் சேவர்</translation> <translation id="3569682580018832495"><ph name="ORIGIN" /> தளத்தால் பின்வரும் கோப்புகளையும் ஃபோல்டர்களையும் பார்க்க முடியும்</translation> @@ -3558,6 +3563,7 @@ <translation id="475088594373173692">முதல் பயனர்</translation> <translation id="4756378406049221019">நிறுத்து/ரெஃப்ரெஷ் செய்</translation> <translation id="4756388243121344051">&வரலாறு</translation> +<translation id="4759126501639448579">நினைவுகளை ஒருபோதும் காட்டாதே</translation> <translation id="4759238208242260848">பதிவிறக்கங்கள்</translation> <translation id="4761104368405085019">உங்கள் மைக்ரோஃபோனைப் பயன்படுத்தலாம்</translation> <translation id="4762718786438001384">சாதனத்தின் வட்டில் காலியிடம் மிகவும் குறைவாக உள்ளது</translation> @@ -3882,6 +3888,7 @@ <translation id="51143538739122961">பாதுகாப்பு விசையைச் செருகி அதைத் தட்டவும்</translation> <translation id="5115309401544567011"><ph name="DEVICE_TYPE" /> சாதனத்தைச் சார்ஜ் செய்யவும்.</translation> <translation id="5115338116365931134">SSO</translation> +<translation id="511632863918093828">அனைத்து நினைவுகளும் மறைக்கப்பட்டன</translation> <translation id="5116628073786783676">ஆடியோவை இவ்வாறு சே&மி...</translation> <translation id="5117139026559873716"><ph name="DEVICE_TYPE" /> சாதனத்திலிருந்து உங்கள் மொபைலின் இணைப்பை நீக்கும். இனி அவை தானாக இணைக்கப்படாது.</translation> <translation id="5117930984404104619">பார்வையிட்ட URLகள் உள்ளிட்ட பிற நீட்டிப்புகளின் செயல்பாட்டைக் கண்காணி</translation> @@ -5026,6 +5033,7 @@ <translation id="6374469231428023295">மீண்டும் முயலவும்</translation> <translation id="6377268785556383139">'<ph name="SEARCH_TEXT" />'க்கு 1 முடிவு உள்ளது</translation> <translation id="6380143666419481200">ஏற்றுக்கொண்டு தொடர்க</translation> +<translation id="6382958439467370461">செயலில் இல்லாத ஷார்ட்கட்கள் இல்லை</translation> <translation id="638418309848716977">ஆதரிக்கப்படும் இணைப்புகள்</translation> <translation id="6384275966486438344">உங்கள் தேடல் அமைப்புகளை இதற்கு மாற்றவும்: <ph name="SEARCH_HOST" /></translation> <translation id="63849924261838903">{NUM_TABS,plural, =1{பெயரிடப்படாத குழு - ஒரு தாவல்}other{பெயரிடப்படாத குழு - # தாவல்கள்}}</translation> @@ -5902,6 +5910,7 @@ <translation id="7354341762311560488">உங்கள் கீபோர்டின் கீழே இடது ஓரத்தில் கைரேகை சென்சார் உள்ளது. அதை ஏதேனும் ஒரு விரலால் மெதுவாகத் தொடவும்.</translation> <translation id="7356908624372060336">நெட்வொர்க் பதிவுகள்</translation> <translation id="735745346212279324">VPN துண்டிக்கப்பட்டது</translation> +<translation id="7358324924540718595">இன்றைக்கான நினைவுகள் மறைக்கப்பட்டன</translation> <translation id="7360233684753165754"><ph name="PAGE_NUMBER" /> பக்கங்கள் - <ph name="PRINTER_NAME" /></translation> <translation id="7361297102842600584"><ph name="PLUGIN_NAME" />ஐ இயக்க, வலது கிளிக் செய்யவும்</translation> <translation id="7362387053578559123">புளூடூத் சாதனங்களுடன் தளங்கள் இணைய முயலும்போது அனுமதி கேட்க வேண்டும்</translation> @@ -6302,6 +6311,7 @@ <translation id="7757787379047923882">உரை <ph name="DEVICE_NAME" /> இலிருந்து பகிரப்பட்டுள்ளது</translation> <translation id="7758143121000533418">Family Link</translation> <translation id="7758450972308449809">திரையின் எல்லைகளைச் சரிசெய்யவும்</translation> +<translation id="7759276754544429366">இன்றைக்கான நினைவுகளை மறை</translation> <translation id="7760004034676677601">இந்தத் துவக்கப் பக்கத்தைத்தான் எதிர்பார்த்தீர்களா?</translation> <translation id="7764225426217299476">முகவரியைச் சேர்</translation> <translation id="7764256770584298012"><ph name="DOWNLOAD_DOMAIN" /> இலிருந்து <ph name="DOWNLOAD_RECEIVED" /></translation> @@ -6971,6 +6981,7 @@ <translation id="8457451314607652708">புத்தகக்குறிகளை இறக்குமதி செய்</translation> <translation id="8458341576712814616">ஷார்ட்கட்</translation> <translation id="8458627787104127436">அனைத்தையும் (<ph name="URL_COUNT" />) புதிய சாளரத்தில் திற</translation> +<translation id="8460490661223303637">நினைவகத்தில் இடத்தை மிச்சப்படுத்த சில உள்ளடக்கத்தை Chrome அகற்றியது</translation> <translation id="8460932807646981183">தேடல் இன்ஜின்களையும் தளத்தில் தேடியவற்றையும் நிர்வகித்தல்</translation> <translation id="84613761564611563">நெட்வொர்க் உள்ளமைவு UI கோரப்பட்டுள்ளது, காத்திருக்கவும்...</translation> <translation id="8461914792118322307">ப்ராக்ஸி</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb index dbff74e..7d1c7d4 100644 --- a/chrome/app/resources/generated_resources_te.xtb +++ b/chrome/app/resources/generated_resources_te.xtb
@@ -4242,6 +4242,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{<ph name="DEVICE_NAME" /> నుండి <ph name="ATTACHMENTS" />ని అందుకోవడం విఫలమైంది}other{<ph name="DEVICE_NAME" /> నుండి <ph name="ATTACHMENTS" />ని అందుకోవడం విఫలమైంది}}</translation> <translation id="5502500733115278303">Firefox నుండి దిగుమతి చెయ్యబడింది</translation> <translation id="5502915260472117187">చిన్నారి</translation> +<translation id="5503356662318814623">మెసేజ్ను పంపండి</translation> <translation id="5503982651688210506">మీ కెమెరా, మైక్రోఫోన్ను ఉపయోగించడానికి, తరలించడానికి <ph name="HOST" />ను అనుమతించడాన్ని కొనసాగించండి</translation> <translation id="5504909642107847870">గోప్యత, సెక్యూరిటీ రివ్యూ</translation> <translation id="5505264765875738116">నోటిఫికేషన్లను పంపడానికి సైట్లు అడగవు</translation> @@ -4498,6 +4499,7 @@ <translation id="5794414402486823030">ఎల్లప్పుడూ సిస్టమ్ వ్యూయర్తో తెరువు</translation> <translation id="5794700615121138172">Linux షేర్ చేసిన ఫోల్డర్లు</translation> <translation id="5794786537412027208">అన్ని Chrome యాప్ల నుండి నిష్క్రమించు</translation> +<translation id="5796485699458186843">కొత్త అజ్ఞాత ట్యాబ్</translation> <translation id="5797521893972859201">సెర్చ్ బాక్స్లోని హిస్టరీతో సహా క్లియర్ చేస్తుంది</translation> <translation id="5798079537501238810">సైట్లు పేమెంట్ హ్యాండ్లర్లను ఇన్స్టాల్ చేయగలవు</translation> <translation id="579915268381781820">మీ 'సెక్యూరిటీ కీ' తీసివేయబడింది.</translation> @@ -6518,10 +6520,12 @@ <translation id="7952904276017482715">ఆశించిన ID "<ph name="EXPECTED_ID" />", కానీ ఉన్న ID "<ph name="NEW_ID" />"</translation> <translation id="7953669802889559161">ఇన్పుట్లు</translation> <translation id="7953955868932471628">షార్ట్కట్లను నిర్వహించండి</translation> +<translation id="7955105108888461311">స్వయంగా అడగండి</translation> <translation id="7956373551960864128">మీరు సేవ్ చేసిన ప్రింటర్లు</translation> <translation id="7957074856830851026">పరికరం క్రమ సంఖ్య లేదా అస్సెట్ ID వంటి పరికర సమాచారాన్ని చూడండి</translation> <translation id="7957615753207896812">కీబోర్డ్ పరికర సెట్టింగ్లను తెరవండి</translation> <translation id="7959074893852789871">ఫైల్ దిగుమతి చెయ్యని కొన్ని బహుళ ప్రమాణపత్రాలను కలిగి ఉంది:</translation> +<translation id="7959665254555683862">కొత్త అజ్ఞాత ట్యాబ్</translation> <translation id="7961015016161918242">ఎప్పుడూ లేదు</translation> <translation id="7963001036288347286">టచ్ప్యాడ్ యాక్సిలరేషన్</translation> <translation id="7963608432878156675">ఇతర పరికరాల బ్లూటూత్, నెట్వర్క్ కనెక్షన్లలో ఈ పేరు కనిపిస్తుంది</translation>
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb index 9b5e9bf..763e317 100644 --- a/chrome/app/resources/generated_resources_th.xtb +++ b/chrome/app/resources/generated_resources_th.xtb
@@ -4226,6 +4226,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{รับ <ph name="ATTACHMENTS" />จาก <ph name="DEVICE_NAME" /> ไม่สำเร็จ}other{รับ <ph name="ATTACHMENTS" />จาก <ph name="DEVICE_NAME" /> ไม่สำเร็จ}}</translation> <translation id="5502500733115278303">นำเข้าจาก Firefox</translation> <translation id="5502915260472117187">บุตรหลาน</translation> +<translation id="5503356662318814623">ส่งข้อความ</translation> <translation id="5503982651688210506">อนุญาตให้ <ph name="HOST" /> ใช้และเคลื่อนย้ายกล้อง รวมถึงใช้ไมโครโฟนของคุณต่อไป</translation> <translation id="5504909642107847870">ดูความเป็นส่วนตัวและความปลอดภัย</translation> <translation id="5505264765875738116">เว็บไซต์ขออนุญาตเพื่อส่งการแจ้งเตือนไม่ได้</translation> @@ -4482,6 +4483,7 @@ <translation id="5794414402486823030">เปิดด้วยโปรแกรมดูของระบบทุกครั้ง</translation> <translation id="5794700615121138172">โฟลเดอร์ที่แชร์ใน Linux</translation> <translation id="5794786537412027208">ปิดแอป Chrome ทั้งหมด</translation> +<translation id="5796485699458186843">แท็บที่ไม่ระบุตัวตนใหม่</translation> <translation id="5797521893972859201">ล้างประวัติการเข้าชม รวมถึงสิ่งที่อยู่ในช่องค้นหา</translation> <translation id="5798079537501238810">เว็บไซต์ติดตั้งเครื่องจัดการการชำระเงินได้</translation> <translation id="579915268381781820">นำคีย์ความปลอดภัยออกแล้ว</translation> @@ -6501,10 +6503,12 @@ <translation id="7952904276017482715">คาดการณ์ ID "<ph name="EXPECTED_ID" />" แต่ ID ที่แจ้งคือ "<ph name="NEW_ID" />"</translation> <translation id="7953669802889559161">การป้อนข้อมูล</translation> <translation id="7953955868932471628">จัดการทางลัด</translation> +<translation id="7955105108888461311">ถามด้วยตนเอง</translation> <translation id="7956373551960864128">เครื่องพิมพ์ที่คุณบันทึกไว้</translation> <translation id="7957074856830851026">ดูข้อมูลอุปกรณ์ เช่น หมายเลขซีเรียลหรือรหัสเนื้อหา</translation> <translation id="7957615753207896812">เปิดการตั้งค่าอุปกรณ์แป้นพิมพ์</translation> <translation id="7959074893852789871">ไฟล์มีใบรับรองหลายใบ แต่มีบางรายการที่ไม่ได้นำเข้า:</translation> +<translation id="7959665254555683862">แท็บที่ไม่ระบุตัวตนใหม่</translation> <translation id="7961015016161918242">ไม่ต้องเลย</translation> <translation id="7963001036288347286">การเร่งความเร็วของทัชแพด</translation> <translation id="7963608432878156675">อุปกรณ์อื่นๆ จะเห็นชื่อนี้เมื่อมีการเชื่อมต่อบลูทูธและเครือข่าย</translation>
diff --git a/chrome/app/resources/generated_resources_zu.xtb b/chrome/app/resources/generated_resources_zu.xtb index 6a56c938..248dc63 100644 --- a/chrome/app/resources/generated_resources_zu.xtb +++ b/chrome/app/resources/generated_resources_zu.xtb
@@ -4243,6 +4243,7 @@ <translation id="5501809658163361512">{COUNT,plural, =1{Yehlulekile ukuthola i-<ph name="ATTACHMENTS" /> ku-<ph name="DEVICE_NAME" />}one{Yehlulekile ukuthola i-<ph name="ATTACHMENTS" /> ku-<ph name="DEVICE_NAME" />}other{Yehlulekile ukuthola i-<ph name="ATTACHMENTS" /> ku-<ph name="DEVICE_NAME" />}}</translation> <translation id="5502500733115278303">Kungeniswe kusuka ku-Firefox</translation> <translation id="5502915260472117187">Ingane</translation> +<translation id="5503356662318814623">Thumela umlayezo</translation> <translation id="5503982651688210506">Qhubeka nokuvumela u-<ph name="HOST" /> ukusebenzisa nokuhambisa ikhamera yakho, nokusebenzisa imakrofoni yakho</translation> <translation id="5504909642107847870">Ukubuyekeza ubumfihlo nokuvikeleka</translation> <translation id="5505264765875738116">Amasayithi awakwazi ukuthumela izaziso</translation> @@ -4500,6 +4501,7 @@ <translation id="5794414402486823030">Ihlala ivuliwe ngesibukeli sesistimu</translation> <translation id="5794700615121138172">I-Linux yabelane ngamafolda</translation> <translation id="5794786537412027208">Yeka zonke izinhlelo zokusebenza ze-Chrome</translation> +<translation id="5796485699458186843">I-Incognito entsha nethebhu</translation> <translation id="5797521893972859201">Kusula umlando, okufaka phakathi ibhokisi losesho</translation> <translation id="5798079537501238810">Amasayithi angafaka izibambi zenkokhelo</translation> <translation id="579915268381781820">Ukhiye wakho wokuqinisekisa ubunikazi ususiwe.</translation> @@ -6521,10 +6523,12 @@ <translation id="7952904276017482715">I-ID elindelwe ngu-"<ph name="EXPECTED_ID" />", kodwa i-ID kube ngu-"<ph name="NEW_ID" />"</translation> <translation id="7953669802889559161">Okokufaka</translation> <translation id="7953955868932471628">Phatha izinqamuleli</translation> +<translation id="7955105108888461311">Zibuzele mathupha</translation> <translation id="7956373551960864128">Amaphrinta akho alondoloziwe</translation> <translation id="7957074856830851026">Bona ulwazi lwedivayisi, njengenombolo yomkhiqizo noma i-ID yefa</translation> <translation id="7957615753207896812">Vula izilungiselelo zedivayisi yekhibhodi</translation> <translation id="7959074893852789871">Ifayela beliqukethe izitifiketi eziningi, ezinye zazo ezingazange zingeniswe:</translation> +<translation id="7959665254555683862">I-Incognito Entsha Nethebhu</translation> <translation id="7961015016161918242">Ngeke</translation> <translation id="7963001036288347286">Ukusheshisa iphedi yokuthinta</translation> <translation id="7963608432878156675">Leli gama libonakala kwamanye amadivayisi e-Bluetooth kanye nakumaxhumo enethiwekhi</translation>
diff --git a/chrome/app/resources/google_chrome_strings_my.xtb b/chrome/app/resources/google_chrome_strings_my.xtb index 5a6a5e7..0cb65e10 100644 --- a/chrome/app/resources/google_chrome_strings_my.xtb +++ b/chrome/app/resources/google_chrome_strings_my.xtb
@@ -169,7 +169,7 @@ <translation id="5062123544085870375">Chrome OS ကို ပြန်လည်စတင်ပါ</translation> <translation id="5132929315877954718">Google Chrome အတွက် ဧရာမ အက်ပ်များ၊ ဂိမ်းများ၊ တိုးချဲ့မှုများ နှင့် အပြင်အဆင်များကို ရှာကြည့်ပါ</translation> <translation id="5139423532931106058">သင့် Chrome ပရိုဖိုင်ကို စိတ်ကြိုက်လုပ်ရန်</translation> -<translation id="5163087008893166964">Chrome မှ ကြိုဆိုပါသည်၊ ဘရောင်ဇာဝင်းဒိုးအသစ် ဖွင့်လိုက်ပါပြီ</translation> +<translation id="5163087008893166964">Chrome က ကြိုဆိုပါသည်၊ ဘရောင်ဇာဝင်းဒိုးအသစ် ဖွင့်လိုက်ပါပြီ</translation> <translation id="5170938038195470297">သင်၏ ပရိုဖိုင်မှာ ပိုသစ်သော Google Chrome ဗားရှင်း ထဲမှ ဖြစ်နေ၍ ၎င်းကို သုံးမရနိုင်ပါ။ အချို့သော အင်္ဂါရပ်များကို ရချင်မှ ရပါမည်။ ကျေးဇူးပြုပြီး အခြား ပရိုဖိုင် ဒါရိုက်ထရီ တစ်ခုကို ဖေါ်ပြပေးပါ သို့မဟုတ် Chrome ၏ ပိုသစ်သော ဗားရှင်းကို အသုံးပြုပါ။</translation> @@ -236,7 +236,7 @@ <translation id="7106741999175697885">တာဝန် မန်နေဂျာ - Google Chrome</translation> <translation id="7140653346177713799">{COUNT,plural, =0{Chrome အတွက် အပ်ဒိတ်အသစ်ရနိုင်ပြီဖြစ်ပြီး ပြန်ဖွင့်လိုက်သည်နှင့် ထည့်သွင်းသွားပါမည်။}=1{Chrome အတွက် အပ်ဒိတ်အသစ်ရနိုင်ပြီဖြစ်ပြီး ပြန်ဖွင့်လိုက်သည်နှင့် ထည့်သွင်းသွားပါမည်။ သင်၏ရုပ်ဖျက် ဝင်ဒိုးကို ပြန်ဖွင့်မည် မဟုတ်ပါ။}other{Chrome အတွက် အပ်ဒိတ်အသစ်ရနိုင်ပြီဖြစ်ပြီး ပြန်ဖွင့်လိုက်သည်နှင့် ထည့်သွင်းသွားပါမည်။ သင်၏ရုပ်ဖျက် ဝင်ဒိုး # ခုကို ပြန်ဖွင့်မည် မဟုတ်ပါ။}}</translation> <translation id="7155997830309522122">ထိုသို့ဆိုလျှင် Chrome တွင် သိမ်းထားသော စကားဝှက်ကို သင်၏စကားဝှက်အသစ်နှင့် တူညီစေရန် တည်းဖြတ်ပါ။</translation> -<translation id="7161904924553537242">Google Chrome မှ ကြိုဆိုပါ၏</translation> +<translation id="7161904924553537242">Google Chrome က ကြိုဆိုပါ၏</translation> <translation id="7242029209006116544">သင်သည် စီမံခြင်းအကောင့်ဖြင့် ဝင်ရောက်နေခြင်း ဖြစ်ပြီး ၎င်း၏ကြီးကြပ်သူကို Google Chrome ပရိုဖိုင်အား ထိန်းချုပ်ခွင့်ပေးသည်။ အက်ပ်များ၊ စာညှပ်များ၊ မှတ်တမ်း၊ လျှို့ဝှက်စကားလုံးများ၊ နှင့် အခြား ကြိုတင်ချိန်ညှိချက်များကဲ့သို့ Chrome ဒေတာများသည် <ph name="USER_NAME" /> သို့အမြဲတမ်း ချည်နှောင်ထားပါသည်။ ဤဒေတာများကို သင် Google အကောင့်များ ဒိုင်ခွက်မှ တစ်ဆင့် ဖျက်နိုင်သည်၊ သို့သော် ဤဒေတာများကို အခြားအကောင့်ဖြင့် ချိတ်ဆက်၍ရမည် မဟုတ်ပါ။ <ph name="LEARN_MORE" /></translation> <translation id="7275165473619697274">Chrome OS ထည့်သွင်းနေပါသည်</translation> <translation id="7295052994004373688">Google Chrome UI ပြသရန် ဤဘာသာစကားကို အသုံးပြုထားသည်</translation> @@ -250,7 +250,7 @@ <translation id="7535429826459677826">Google Chrome Dev</translation> <translation id="7573289029918943991">သင်၏စက် အပ်ဒိတ်ဖြစ်မဖြစ် ကြည့်ရန် <ph name="LINK_BEGIN" />Chrome OS ဆက်တင်များ<ph name="LINK_END" /> သို့သွားပါ</translation> <translation id="7592736734348559088">သင်၏ လက်မှတ်ထိုးရေး အသေးစိတ်များမှာ ဟောင်းသွားကြပြီ ဖြစ်၍ Google Chrome သည် သင်၏ ဒေတာကို စင့်က် မလုပ်နိုင်ခဲ့ပါ။</translation> -<translation id="7626032353295482388">Chrome မှ ကြိုဆိုပါသည်</translation> +<translation id="7626032353295482388">Chrome က ကြိုဆိုပါသည်</translation> <translation id="7629695634924605473">သင့်စကားဝှက်များ ကျိုးပေါက်ထားခြင်း ရှိမရှိ Chrome က သင့်အား အသိပေးပါမည်</translation> <translation id="7641148173327520642">သင့်စနစ်စီမံခန့်ခွဲသူသည် <ph name="TARGET_URL_HOSTNAME" /> သို့ ဝင်ကြည့်ရန်အတွက် <ph name="ALTERNATIVE_BROWSER_NAME" /> ဖွင့်ရန် Google Chrome ကို စီစဉ်သတ်မှတ်ထားသည်။</translation> <translation id="7651907282515937834">Chrome လုပ်ငန်းသုံး သင်္ကေတ</translation>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 3413175..3a1bd36ad 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -2530,6 +2530,12 @@ <message name="IDS_SETTINGS_COOKIES_BLOCK_EXCEPTIONS" desc="Title of the list containing site exceptions always blocking them from using cookies"> Sites that can never use cookies </message> + <message name="IDS_SETTINGS_SITE_SETTINGS_APP_PROTOCOL_HANDLERS" desc="Label for the app protocol handlers (e.g. mailto) in site settings."> + Apps + </message> + <message name="IDS_SETTINGS_SITE_SETTINGS_APP_APPROVED_PROTOCOL_HANDLERS_DESCRIPTION" desc="Description of the approved protocol handlers list registered with the OS, where the user has previously permitted the app to handle the protocol."> + Apps listed below can handle protocol links as well. Other apps will ask for permission. + </message> <message name="IDS_SETTINGS_SITE_SETTINGS_HID_DEVICES_ASK" desc="The ask label for HID devices in site settings."> Ask when a site wants to access HID devices </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 58d98f7..d9f6692 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4984,6 +4984,11 @@ "lacros/lacros_url_handling.h", "lacros/metrics_reporting_observer.cc", "lacros/metrics_reporting_observer.h", + "lacros/net/network_settings_translation.h", + "lacros/net/proxy_config_service_lacros.cc", + "lacros/net/proxy_config_service_lacros.h", + "lacros/net/network_settings_translation_crosapi.cc", + "lacros/net/network_settings_translation_net_proxy.cc", "lacros/prefs_ash_observer.cc", "lacros/prefs_ash_observer.h", "lacros/snap_controller_lacros.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 8b170811..4f2708a 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -4238,6 +4238,10 @@ flag_descriptions::kWebPaymentsExperimentalFeaturesName, flag_descriptions::kWebPaymentsExperimentalFeaturesDescription, kOsAll, FEATURE_VALUE_TYPE(payments::features::kWebPaymentsExperimentalFeatures)}, + {"enable-payment-request-basic-card", + flag_descriptions::kPaymentRequestBasicCardName, + flag_descriptions::kPaymentRequestBasicCardDescription, kOsAll, + FEATURE_VALUE_TYPE(features::kPaymentRequestBasicCard)}, {"enable-debug-for-store-billing", flag_descriptions::kAppStoreBillingDebugName, flag_descriptions::kAppStoreBillingDebugDescription, kOsAll,
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.cc b/chrome/browser/apps/app_service/app_service_proxy_base.cc index 6ffe1c9..1afdbd1b 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_base.cc +++ b/chrome/browser/apps/app_service/app_service_proxy_base.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/apps/app_service/app_service_metrics.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/launch_utils.h" -#include "chrome/browser/ash/file_manager/app_id.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/web_app_id_constants.h" #include "components/services/app_service/app_service_impl.h" @@ -377,31 +376,6 @@ return app_ids; } -bool ShouldIgnoreApp(const apps::AppUpdate& update) { - bool is_ready = apps_util::IsInstalled(update.Readiness()); - bool show_in_launcher = - update.ShowInLauncher() == apps::mojom::OptionalBool::kTrue; - // TODO(1240906): Find a way to properly filter in/out apps that should - // participate in intent handling. - bool is_exempt = web_app::IsSystemAppIdWithFileHandlers(update.AppId()) || - update.AppId() == file_manager::kAudioPlayerAppId; - return !is_ready || (!show_in_launcher && !is_exempt); -} - -std::string GetActivityLabel(const apps::mojom::IntentFilterPtr& filter, - const apps::AppUpdate& update) { - if (filter->activity_label && !filter->activity_label->empty()) { - return filter->activity_label.value(); - } else { - return update.Name(); - } -} - -struct IndexAndGeneric { - size_t index; - bool is_generic; -}; - std::vector<IntentLaunchInfo> AppServiceProxyBase::GetAppsForIntent( const apps::mojom::IntentPtr& intent, bool exclude_browsers, @@ -417,53 +391,42 @@ &exclude_browsers, &exclude_browser_tab_apps]( const apps::AppUpdate& update) { - if (ShouldIgnoreApp(update)) { + // TODO(1240906): Find a way to properly filter in/out apps that should + // participate in intent handling. + if (!apps_util::IsInstalled(update.Readiness()) || + (update.ShowInLauncher() != apps::mojom::OptionalBool::kTrue && + !web_app::IsSystemAppIdWithFileHandlers(update.AppId()))) { return; } if (exclude_browser_tab_apps && update.WindowMode() == mojom::WindowMode::kBrowser) { return; } - // |activity_label| -> {index, is_generic} - std::map<std::string, IndexAndGeneric> best_handler_map; - bool is_file_handling_intent = - intent->files.has_value() && intent->files->size() > 0; - size_t index = 0; + std::set<std::string> existing_activities; for (const auto& filter : update.IntentFilters()) { if (exclude_browsers && apps_util::IsBrowserFilter(filter)) { continue; } if (apps_util::IntentMatchesFilter(intent, filter)) { - // Return the first non-generic match if it exists, otherwise the - // first generic match. - bool generic = false; - if (is_file_handling_intent) { - generic = apps_util::IsGenericFileHandler(intent, filter); + IntentLaunchInfo entry; + entry.app_id = update.AppId(); + std::string activity_label; + if (filter->activity_label && + !filter->activity_label.value().empty()) { + activity_label = filter->activity_label.value(); + } else { + activity_label = update.Name(); } - std::string activity_label = GetActivityLabel(filter, update); - // Replace the best handler if it is generic and we have a non-generic - // one. - auto it = best_handler_map.find(activity_label); - if (it == best_handler_map.end() || - (it->second.is_generic && !generic)) { - best_handler_map[activity_label] = IndexAndGeneric{index, generic}; + if (base::Contains(existing_activities, activity_label)) { + continue; } + existing_activities.insert(activity_label); + entry.activity_label = activity_label; + entry.activity_name = filter->activity_name.value_or(""); + entry.is_file_extension_match = + apps_util::FilterIsForFileExtensions(filter); + intent_launch_info.push_back(entry); } - index++; - } - const auto& filters = update.IntentFilters(); - for (const auto& handler_entry : best_handler_map) { - const mojom::IntentFilterPtr& filter = - filters[handler_entry.second.index]; - IntentLaunchInfo entry; - entry.app_id = update.AppId(); - entry.activity_label = GetActivityLabel(filter, update); - entry.activity_name = filter->activity_name.value_or(""); - entry.is_generic_file_handler = - apps_util::IsGenericFileHandler(intent, filter); - entry.is_file_extension_match = - apps_util::FilterIsForFileExtensions(filter); - intent_launch_info.push_back(entry); } }); } @@ -471,9 +434,11 @@ } std::vector<IntentLaunchInfo> AppServiceProxyBase::GetAppsForFiles( - std::vector<apps::mojom::IntentFilePtr> files) { + const std::vector<GURL>& filesystem_urls, + const std::vector<std::string>& mime_types) { return GetAppsForIntent( - apps_util::CreateViewIntentFromFiles(std::move(files)), false, false); + apps_util::CreateViewIntentFromFiles(filesystem_urls, mime_types), false, + false); } void AppServiceProxyBase::AddPreferredApp(const std::string& app_id,
diff --git a/chrome/browser/apps/app_service/app_service_proxy_base.h b/chrome/browser/apps/app_service/app_service_proxy_base.h index b430fbe8..66df3a4 100644 --- a/chrome/browser/apps/app_service/app_service_proxy_base.h +++ b/chrome/browser/apps/app_service/app_service_proxy_base.h
@@ -41,7 +41,6 @@ std::string app_id; std::string activity_name; std::string activity_label; - bool is_generic_file_handler; bool is_file_extension_match; }; @@ -206,9 +205,10 @@ bool exclude_browser_tab_apps = true); // Returns a list of apps (represented by their ids) and activities (if - // applied) which can handle |files|. + // applied) which can handle |filesystem_urls| and |mime_types|. std::vector<IntentLaunchInfo> GetAppsForFiles( - std::vector<apps::mojom::IntentFilePtr> files); + const std::vector<GURL>& filesystem_urls, + const std::vector<std::string>& mime_types); // Adds a preferred app for |url|. void AddPreferredApp(const std::string& app_id, const GURL& url);
diff --git a/chrome/browser/apps/app_service/intent_util.cc b/chrome/browser/apps/app_service/intent_util.cc index c83433d..6f441c47 100644 --- a/chrome/browser/apps/app_service/intent_util.cc +++ b/chrome/browser/apps/app_service/intent_util.cc
@@ -13,11 +13,9 @@ #include "base/strings/stringprintf.h" #include "chrome/browser/apps/app_service/file_utils.h" #include "chrome/browser/web_applications/web_app.h" -#include "components/services/app_service/public/cpp/file_handler_info.h" #include "components/services/app_service/public/cpp/intent_filter_util.h" #include "components/services/app_service/public/cpp/intent_util.h" #include "components/services/app_service/public/mojom/types.mojom.h" -#include "extensions/common/manifest_handlers/file_handler_info.h" #include "third_party/blink/public/common/features.h" #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -36,8 +34,7 @@ const std::vector<std::string>& intent_actions, const std::vector<std::string>& mime_types, const std::vector<std::string>& file_extensions, - const std::string& activity_name = "", - bool include_directories = false) { + const std::string& activity_name = "") { DCHECK(!mime_types.empty() || !file_extensions.empty()); auto intent_filter = apps::mojom::IntentFilter::New(); @@ -65,10 +62,6 @@ condition_values.push_back(apps_util::MakeConditionValue( extension, apps::mojom::PatternMatchType::kFileExtension)); } - if (include_directories) { - condition_values.push_back(apps_util::MakeConditionValue( - "", apps::mojom::PatternMatchType::kIsDirectory)); - } DCHECK(!condition_values.empty()); if (!condition_values.empty()) { @@ -241,32 +234,6 @@ return filters; } -std::vector<apps::mojom::IntentFilterPtr> CreateChromeAppIntentFilters( - const extensions::Extension* extension) { - const extensions::FileHandlersInfo* file_handlers = - extensions::FileHandlers::GetFileHandlers(extension); - if (!file_handlers) - return {}; - - std::vector<apps::mojom::IntentFilterPtr> filters; - for (const apps::FileHandlerInfo& handler : *file_handlers) { - // "share_with", "add_to" and "pack_with" are ignored in the Files app - // frontend. - if (handler.verb != apps::file_handler_verbs::kOpenWith) - continue; - std::vector<std::string> mime_types(handler.types.begin(), - handler.types.end()); - std::vector<std::string> file_extensions(handler.extensions.begin(), - handler.extensions.end()); - filters.push_back(CreateFileFilter({apps_util::kIntentActionView}, - mime_types, file_extensions, handler.id, - handler.include_directories)); - filters.back()->activity_label = extension->name(); - } - - return filters; -} - #if BUILDFLAG(IS_CHROMEOS_ASH) // TODO(crbug.com/853604): Make this not link to file manager extension if // possible. Added support to not link with file manager extension but still @@ -498,7 +465,6 @@ case apps::mojom::PatternMatchType::kNone: case apps::mojom::PatternMatchType::kMimeType: case apps::mojom::PatternMatchType::kFileExtension: - case apps::mojom::PatternMatchType::kIsDirectory: NOTREACHED(); return arc::IntentFilter(); }
diff --git a/chrome/browser/apps/app_service/intent_util.h b/chrome/browser/apps/app_service/intent_util.h index 47835fc1..1db1132 100644 --- a/chrome/browser/apps/app_service/intent_util.h +++ b/chrome/browser/apps/app_service/intent_util.h
@@ -10,7 +10,6 @@ #include "base/containers/flat_map.h" #include "build/chromeos_buildflags.h" #include "components/services/app_service/public/mojom/types.mojom.h" -#include "extensions/common/extension.h" #if BUILDFLAG(IS_CHROMEOS_ASH) #include "components/arc/mojom/intent_common.mojom.h" @@ -39,11 +38,6 @@ const web_app::WebApp& web_app, const GURL& scope); -// Create intent filters for a Chrome app (extension-based) e.g. for -// file_handlers. -std::vector<apps::mojom::IntentFilterPtr> CreateChromeAppIntentFilters( - const extensions::Extension* extension); - #if BUILDFLAG(IS_CHROMEOS_ASH) // Create an intent struct with filesystem:// or file:// type URLs from the // file paths and mime types of a list of files.
diff --git a/chrome/browser/apps/app_service/intent_util_unittest.cc b/chrome/browser/apps/app_service/intent_util_unittest.cc index 9da9caf..acf0359 100644 --- a/chrome/browser/apps/app_service/intent_util_unittest.cc +++ b/chrome/browser/apps/app_service/intent_util_unittest.cc
@@ -17,8 +17,6 @@ #include "components/arc/intent_helper/intent_constants.h" #include "components/arc/mojom/intent_helper.mojom.h" #include "components/services/app_service/public/cpp/intent_util.h" -#include "extensions/common/extension_builder.h" -#include "extensions/common/value_builder.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features.h" @@ -336,86 +334,3 @@ apps_util::CreateLaunchIntent("com.android.vending", intent_with_text_and_title)); } - -TEST_F(IntentUtilsTest, CreateChromeAppIntentFilters_FileHandlers) { - // Foo app provides file handler for text/plain and all file types. - extensions::ExtensionBuilder foo_app; - foo_app.SetManifest( - extensions::DictionaryBuilder() - .Set("name", "Foo") - .Set("version", "1.0.0") - .Set("manifest_version", 2) - .Set("app", extensions::DictionaryBuilder() - .Set("background", - extensions::DictionaryBuilder() - .Set("scripts", extensions::ListBuilder() - .Append("background.js") - .Build()) - .Build()) - .Build()) - .Set( - "file_handlers", - extensions::DictionaryBuilder() - .Set("any", - extensions::DictionaryBuilder() - .Set("types", - extensions::ListBuilder().Append("*/*").Build()) - .Build()) - .Set("text", - extensions::DictionaryBuilder() - .Set("types", extensions::ListBuilder() - .Append("text/plain") - .Build()) - .Set("extensions", - extensions::ListBuilder().Append("txt").Build()) - .Set("verb", "open_with") - .Build()) - .Build()) - .Build()); - foo_app.SetID("abcdzxcv"); - scoped_refptr<const extensions::Extension> foo = foo_app.Build(); - - std::vector<IntentFilterPtr> filters = - apps_util::CreateChromeAppIntentFilters(foo.get()); - - ASSERT_EQ(filters.size(), 2); - - // "any" filter - View action - const IntentFilterPtr& mime_filter = filters[0]; - ASSERT_EQ(mime_filter->conditions.size(), 2); - const Condition& view_cond = *mime_filter->conditions[0]; - EXPECT_EQ(view_cond.condition_type, ConditionType::kAction); - ASSERT_EQ(view_cond.condition_values.size(), 1); - EXPECT_EQ(view_cond.condition_values[0]->value, apps_util::kIntentActionView); - - // "any" filter - mime type match - const Condition& file_cond = *mime_filter->conditions[1]; - EXPECT_EQ(file_cond.condition_type, ConditionType::kFile); - ASSERT_EQ(file_cond.condition_values.size(), 1); - EXPECT_EQ(file_cond.condition_values[0]->match_type, - PatternMatchType::kMimeType); - EXPECT_EQ(file_cond.condition_values[0]->value, "*/*"); - - // Text filter - View action - const IntentFilterPtr& mime_filter2 = filters[1]; - ASSERT_EQ(mime_filter2->conditions.size(), 2); - const Condition& view_cond2 = *mime_filter2->conditions[0]; - EXPECT_EQ(view_cond2.condition_type, ConditionType::kAction); - ASSERT_EQ(view_cond2.condition_values.size(), 1); - EXPECT_EQ(view_cond2.condition_values[0]->value, - apps_util::kIntentActionView); - - // Text filter - mime type match - const Condition& file_cond2 = *mime_filter2->conditions[1]; - EXPECT_EQ(file_cond2.condition_type, ConditionType::kFile); - ASSERT_EQ(file_cond2.condition_values.size(), 2); - EXPECT_EQ(file_cond2.condition_values[0]->match_type, - PatternMatchType::kMimeType); - EXPECT_EQ(file_cond2.condition_values[0]->value, "text/plain"); - // Text filter - file extension match - EXPECT_EQ(file_cond2.condition_values[1]->match_type, - PatternMatchType::kFileExtension); - EXPECT_EQ(file_cond2.condition_values[1]->value, "txt"); -} - -// TODO test verbs, generic.
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc index 2b43d44..88bcfc9 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc +++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -17,7 +17,6 @@ #include "base/bind.h" #include "base/callback.h" #include "base/containers/contains.h" -#include "base/containers/extend.h" #include "base/feature_list.h" #include "base/metrics/histogram_macros.h" #include "base/scoped_observation.h" @@ -25,7 +24,6 @@ #include "base/values.h" #include "chrome/browser/apps/app_service/app_icon_factory.h" #include "chrome/browser/apps/app_service/app_service_metrics.h" -#include "chrome/browser/apps/app_service/intent_util.h" #include "chrome/browser/apps/app_service/launch_utils.h" #include "chrome/browser/apps/app_service/menu_util.h" #include "chrome/browser/ash/arc/arc_util.h" @@ -673,10 +671,6 @@ app->show_in_shelf = apps::mojom::OptionalBool::kFalse; } - // Add file_handlers. - base::Extend(app->intent_filters, - apps_util::CreateChromeAppIntentFilters(extension)); - return app; }
diff --git a/chrome/browser/ash/cert_provisioning/cert_provisioning_common.cc b/chrome/browser/ash/cert_provisioning/cert_provisioning_common.cc index 14059871..c026474 100644 --- a/chrome/browser/ash/cert_provisioning/cert_provisioning_common.cc +++ b/chrome/browser/ash/cert_provisioning/cert_provisioning_common.cc
@@ -77,6 +77,36 @@ } // namespace +std::string CertificateProvisioningWorkerStateToString( + CertProvisioningWorkerState state) { + switch (state) { + case CertProvisioningWorkerState::kInitState: + return "InitState"; + case CertProvisioningWorkerState::kKeypairGenerated: + return "KeypairGenerated"; + case CertProvisioningWorkerState::kStartCsrResponseReceived: + return "StartCsrResponseReceived"; + case CertProvisioningWorkerState::kVaChallengeFinished: + return "VaChallengeFinished"; + case CertProvisioningWorkerState::kKeyRegistered: + return "KeyRegistered"; + case CertProvisioningWorkerState::kKeypairMarked: + return "KeypairMarked"; + case CertProvisioningWorkerState::kSignCsrFinished: + return "SignCsrFinished"; + case CertProvisioningWorkerState::kFinishCsrResponseReceived: + return "FinishCsrResponseReceived"; + case CertProvisioningWorkerState::kSucceeded: + return "Succeeded"; + case CertProvisioningWorkerState::kInconsistentDataError: + return "InconsistentDataError"; + case CertProvisioningWorkerState::kFailed: + return "Failed"; + case CertProvisioningWorkerState::kCanceled: + return "Canceled"; + } +} + bool IsFinalState(CertProvisioningWorkerState state) { switch (state) { case CertProvisioningWorkerState::kSucceeded:
diff --git a/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h b/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h index 57159cc..1afde83 100644 --- a/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h +++ b/chrome/browser/ash/cert_provisioning/cert_provisioning_common.h
@@ -72,6 +72,10 @@ kDownloadCert = 2, }; +// Converts the worker |state| to a string. This is mainly for logging purposes. +std::string CertificateProvisioningWorkerStateToString( + CertProvisioningWorkerState state); + // Returns true if the |state| is one of final states, i. e. worker should // finish its task in one of them. bool IsFinalState(CertProvisioningWorkerState state);
diff --git a/chrome/browser/ash/cert_provisioning/cert_provisioning_worker.cc b/chrome/browser/ash/cert_provisioning/cert_provisioning_worker.cc index c59ee93..fc4e907 100644 --- a/chrome/browser/ash/cert_provisioning/cert_provisioning_worker.cc +++ b/chrome/browser/ash/cert_provisioning/cert_provisioning_worker.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/no_destructor.h" +#include "base/syslog_logging.h" #include "base/time/time.h" #include "chrome/browser/ash/attestation/tpm_challenge_key_result.h" #include "chrome/browser/ash/cert_provisioning/cert_provisioning_common.h" @@ -739,7 +740,10 @@ policy::DeviceManagementStatus::DM_STATUS_TEMPORARY_UNAVAILABLE) || (status == policy::DeviceManagementStatus::DM_STATUS_REQUEST_FAILED) || (status == policy::DeviceManagementStatus::DM_STATUS_HTTP_STATUS_ERROR)) { - LOG(WARNING) << "Connection to DM Server failed, error: " << status; + LOG(WARNING) << "Connection to DM Server failed, error: " << status + << " for profile ID: " << cert_profile_.profile_id + << " in state: " + << CertificateProvisioningWorkerStateToString(state_); request_backoff_.InformOfRequest(false); ScheduleNextStep(request_backoff_.GetTimeUntilRelease()); return false; @@ -758,7 +762,10 @@ } if (status != policy::DeviceManagementStatus::DM_STATUS_SUCCESS) { - LOG(ERROR) << "DM Server returned error: " << status; + LOG(ERROR) << "DM Server returned error: " << status + << " for profile ID: " << cert_profile_.profile_id + << " in state: " + << CertificateProvisioningWorkerStateToString(state_); UpdateState(CertProvisioningWorkerState::kFailed); return false; } @@ -767,13 +774,19 @@ if (error.has_value() && (error.value() == CertProvisioningResponseError::INCONSISTENT_DATA)) { - LOG(ERROR) << "Server response contains error: " << error.value(); + LOG(ERROR) << "Server response contains error: " << error.value() + << " for profile ID: " << cert_profile_.profile_id + << " in state: " + << CertificateProvisioningWorkerStateToString(state_); UpdateState(CertProvisioningWorkerState::kInconsistentDataError); return false; } if (error.has_value()) { - LOG(ERROR) << "Server response contains error: " << error.value(); + LOG(ERROR) << "Server response contains error: " << error.value() + << " for profile ID: " << cert_profile_.profile_id + << " in state: " + << CertificateProvisioningWorkerStateToString(state_); UpdateState(CertProvisioningWorkerState::kFailed); return false; }
diff --git a/chrome/browser/ash/crosapi/BUILD.gn b/chrome/browser/ash/crosapi/BUILD.gn index ed92e2ba..81ee2e5 100644 --- a/chrome/browser/ash/crosapi/BUILD.gn +++ b/chrome/browser/ash/crosapi/BUILD.gn
@@ -108,6 +108,8 @@ "translate_proxy_config_to_crosapi.cc", "url_handler_ash.cc", "url_handler_ash.h", + "user_data_stats_recorder.cc", + "user_data_stats_recorder.h", "video_capture_device_ash.cc", "video_capture_device_ash.h", "video_capture_device_factory_ash.cc", @@ -202,6 +204,7 @@ "test_local_printer_ash.cc", "test_local_printer_ash.h", "test_mojo_connection_manager_unittest.cc", + "user_data_stats_recorder_unittest.cc", ] deps = [
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc index 100c232..df9bda7 100644 --- a/chrome/browser/ash/crosapi/browser_manager.cc +++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -47,6 +47,7 @@ #include "chrome/browser/ash/crosapi/crosapi_manager.h" #include "chrome/browser/ash/crosapi/environment_provider.h" #include "chrome/browser/ash/crosapi/test_mojo_connection_manager.h" +#include "chrome/browser/ash/crosapi/user_data_stats_recorder.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h" #include "chrome/browser/ash/policy/core/device_local_account_policy_service.h" #include "chrome/browser/ash/policy/core/user_cloud_policy_manager_ash.h" @@ -834,6 +835,13 @@ SetState(State::UNAVAILABLE); browser_loader_->Unload(); } + + // Post `RecordUserDataSizes()` to send UMA stats about sizes of files/dirs + // inside the profile data directory. + base::ThreadPool::PostTask( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&user_data_stats_recorder::RecordUserDataSizes, + ProfileManager::GetPrimaryUserProfile()->GetPath())); } void BrowserManager::OnStoreLoaded(policy::CloudPolicyStore* store) {
diff --git a/chrome/browser/ash/crosapi/user_data_stats_recorder.cc b/chrome/browser/ash/crosapi/user_data_stats_recorder.cc new file mode 100644 index 0000000..8a3ae08 --- /dev/null +++ b/chrome/browser/ash/crosapi/user_data_stats_recorder.cc
@@ -0,0 +1,205 @@ +// 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/user_data_stats_recorder.h" + +#include <string.h> + +#include <algorithm> + +#include "base/files/file_enumerator.h" +#include "base/files/file_path.h" +#include "base/logging.h" +#include "base/metrics/histogram_functions.h" +#include "base/ranges/algorithm.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_util.h" + +namespace crosapi { +namespace user_data_stats_recorder { + +namespace { + +struct PathNamePair { + const char* key; + const char* value; +}; + +struct PathNameComparator { + constexpr bool operator()(const PathNamePair& p1, + const PathNamePair& p2) const { + return base::StringPiece(p1.key) < base::StringPiece(p2.key); + } +}; + +// Key value pairs of path names in profile data directory and their +// corresponding UMA item names. +constexpr PathNamePair kPathNamePairs[] = { + {"AccountManagerTokens.bin", "AccountManagerTokensBin"}, + {"Accounts", "Accounts"}, + {"Affiliation Database", "AffiliationDatabase"}, + {"AutofillStrikeDatabase", "AutofillStrikeDatabase"}, + {"Bookmarks", "Bookmarks"}, + {"BudgetDatabase", "BudgetDatabase"}, + {"Cache", "Cache"}, + {"Code Cache", "CodeCache"}, + {"Cookies", "Cookies"}, + {"DNR Extension Rules", "DNRExtensionRules"}, + {"Download Service", "DownloadService"}, + {"Downloads", "Downloads"}, + {"Extension Cookies", "ExtensionCookies"}, + {"Extension Rules", "ExtensionRules"}, + {"Extension State", "ExtensionState"}, + {"Extensions", "Extensions"}, + {"Favicons", "Favicons"}, + {"Feature Engagement Tracker", "FeatureEngagementTracker"}, + {"File System", "FileSystem"}, + {"FullRestoreData", "FullRestoreData"}, + {"GCM Store", "GCMStore"}, + {"GCache", "GCache"}, + {"GPUCache", "GPUCache"}, + {"History", "History"}, + {"IndexedDB", "IndexedDB"}, + {"LOCK", "LOCK"}, + {"LOG", "LOG"}, + {"LOG.old", "LOGOld"}, + {"Local App Settings", "LocalAppSettings"}, + {"Local Extension Settings", "LocalExtensionSettings"}, + {"Local Storage", "LocalStorage"}, + {"Login Data", "LoginData"}, + {"Login Data For Account", "LoginDataForAccount"}, + {"Managed Extension Settings", "ManagedExtensionSettings"}, + {"MyFiles", "MyFiles"}, + {"NearbySharePublicCertificateDatabase", + "NearbySharePublicCertificateDatabase"}, + {"Network Action Predictor", "NetworkActionPredictor"}, + {"Network Persistent State", "NetworkPersistentState"}, + {"PPDCache", "PPDCache"}, + {"Platform Notifications", "PlatformNotifications"}, + {"Policy", "Policy"}, + {"Preferences", "Preferences"}, + {"PreferredApps", "PreferredApps"}, + {"PrintJobDatabase", "PrintJobDatabase"}, + {"QuotaManager", "QuotaManager"}, + {"README", "README"}, + {"RLZ Data", "RLZData"}, + {"Reporting and NEL", "ReportingAndNEL"}, + {"Service Worker", "ServiceWorker"}, + {"Session Storage", "SessionStorage"}, + {"Sessions", "Sessions"}, + {"Shortcuts", "Shortcuts"}, + {"Site Characteristics Database", "SiteCharacteristicsDatabase"}, + {"Storage", "Storage"}, + {"Sync App Settings", "SyncAppSettings"}, + {"Sync Data", "SyncData"}, + {"Sync Extension Settings", "SyncExtensionSettings"}, + {"Top Sites", "TopSites"}, + {"Translate Ranker Model", "TranslateRankerModel"}, + {"TransportSecurity", "TransportSecurity"}, + {"Trusted Vault", "TrustedVault"}, + {"Visited Links", "VisitedLinks"}, + {"Web Applications", "WebApplications"}, + {"Web Data", "WebData"}, + {"WebRTC Logs", "WebRTCLogs"}, + {"app_ranker.pb", "AppRankerPb"}, + {"arc.apps", "ArcApps"}, + {"autobrightness", "Autobrightness"}, + {"blob_storage", "BlobStorage"}, + {"crostini.icons", "CrostiniIcons"}, + {"data_reduction_proxy_leveldb", "DataReductionProxyLeveldb"}, + {"databases", "Databases"}, + {"extension_install_log", "ExtensionInstallLog"}, + {"google-assistant-library", "GoogleAssistantLibrary"}, + {"heavy_ad_intervention_opt_out.db", "HeavyAdInterventionOptOutDb"}, + {"lacros", "Lacros"}, + {"login-times", "LoginTimes"}, + {"logout-times", "LogoutTimes"}, + {"optimization_guide_hint_cache_store", "OptimizationGuideHintCacheStore"}, + {"optimization_guide_model_and_features_store", + "OptimizationGuideModelAndFeaturesStore"}, + {"previews_opt_out.db", "PreviewsOptOutDb"}, + {"shared_proto_db", "SharedProtoDb"}, + {"smartcharging", "Smartcharging"}, + {"structured_metrics", "StructuredMetrics"}, + {"webrtc_event_logs", "WebrtcEventLogs"}, + {"zero_state_group_ranker.pb", "ZeroStateGroupRankerPb"}, + {"zero_state_local_files.pb", "ZeroStateLocalFilesPb"}}; + +static_assert(base::ranges::is_sorted(kPathNamePairs, PathNameComparator()), + "kPathNamePairs needs to be sorted by the keys of its elements " + "so that binary_search can be used on it."); + +} // namespace + +void RecordUserDataSizes(const base::FilePath& profile_data_dir) { + base::FileEnumerator enumerator(profile_data_dir, false /* recursive */, + base::FileEnumerator::FILES | + base::FileEnumerator::DIRECTORIES | + base::FileEnumerator::SHOW_SYM_LINKS); + for (base::FilePath entry = enumerator.Next(); !entry.empty(); + entry = enumerator.Next()) { + const base::FileEnumerator::FileInfo& info = enumerator.GetInfo(); + + int64_t size; + if (S_ISREG(info.stat().st_mode)) { + size = info.GetSize(); + } else if (S_ISDIR(info.stat().st_mode)) { + size = ComputeDirectorySizeWithoutLinks(entry); + } else { + // Skip links. + continue; + } + + RecordUserDataSize(entry, size); + } +} + +int64_t ComputeDirectorySizeWithoutLinks(const base::FilePath& dir_path) { + base::FileEnumerator enumerator(dir_path, false /* recursive */, + base::FileEnumerator::FILES | + base::FileEnumerator::DIRECTORIES | + base::FileEnumerator::SHOW_SYM_LINKS); + int64_t size = 0; + for (base::FilePath entry = enumerator.Next(); !entry.empty(); + entry = enumerator.Next()) { + const base::FileEnumerator::FileInfo& info = enumerator.GetInfo(); + + if (S_ISREG(info.stat().st_mode)) { + size += info.GetSize(); + } else if (S_ISDIR(info.stat().st_mode)) { + size += ComputeDirectorySizeWithoutLinks(entry); + } else { + // Skip links. + continue; + } + } + + return size; +} + +void RecordUserDataSize(const base::FilePath& path, int64_t size) { + std::string uma_name = kUserDataStatsRecorderDataSize; + uma_name += GetUMAItemName(path); + + // Divide 10GB into 100 buckets. Unit in MB. + LOG(WARNING) << uma_name << ": " << size / 1024 / 1024 << "MB"; + base::UmaHistogramCustomCounts(uma_name, size / 1024 / 1024, 1, 10000, 100); +} + +std::string GetUMAItemName(const base::FilePath& path) { + std::string path_name = path.BaseName().value(); + + auto* it = std::lower_bound( + std::begin(kPathNamePairs), std::end(kPathNamePairs), + PathNamePair{path_name.c_str(), nullptr}, PathNameComparator()); + + if (it != std::end(kPathNamePairs) && base::StringPiece(it->key) == path_name) + return it->value; + + // If `path_name` was not found in kPathNamePairs, return "Unknown" as name. + return kUnknownUMAName; +} + +} // namespace user_data_stats_recorder +} // namespace crosapi
diff --git a/chrome/browser/ash/crosapi/user_data_stats_recorder.h b/chrome/browser/ash/crosapi/user_data_stats_recorder.h new file mode 100644 index 0000000..33ac581 --- /dev/null +++ b/chrome/browser/ash/crosapi/user_data_stats_recorder.h
@@ -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. + +#ifndef CHROME_BROWSER_ASH_CROSAPI_USER_DATA_STATS_RECORDER_H_ +#define CHROME_BROWSER_ASH_CROSAPI_USER_DATA_STATS_RECORDER_H_ + +#include <string> + +#include "base/files/file_path.h" + +namespace base { +class FilePath; +} + +namespace crosapi { +namespace user_data_stats_recorder { +// UMA name prefix to record sizes of files/dirs in profile data directory. The +// name unique to each file/dir is appended to the end to create a full UMA name +// as follows `Ash.UserDataStatsRecorder.DataSize.{ItemName}`. +constexpr char kUserDataStatsRecorderDataSize[] = + "Ash.UserDataStatsRecorder.DataSize."; +// Files/dirs that is not assigned a unique uma name is given this name. +constexpr char kUnknownUMAName[] = "Unknown"; + +constexpr int64_t kBytesInOneMB = 1024 * 1024; + +// Iterates over files/dirs inside `profile_data_dir` and calls +// `RecordUserDataSize()` to record UMA stats for each. +void RecordUserDataSizes(const base::FilePath& profile_data_dir); +// Records `size` of the file/dir pointed by `path`. If it is a directory, the +// size is the recursively accumulated sizes of contents inside. +void RecordUserDataSize(const base::FilePath& path, int64_t size); +// Returns UMA name for `path`. Returns `kUnknownUMAName` if `path` is not in +// `kPathNamePairs`. +std::string GetUMAItemName(const base::FilePath& path); +// Similar to `base::ComputeDirectorySize()` this computes the sum of all files +// under `dir_path` recursively while skipping symlinks. +int64_t ComputeDirectorySizeWithoutLinks(const base::FilePath& dir_path); + +} // namespace user_data_stats_recorder +} // namespace crosapi + +#endif // CHROME_BROWSER_ASH_CROSAPI_USER_DATA_STATS_RECORDER_H_
diff --git a/chrome/browser/ash/crosapi/user_data_stats_recorder_unittest.cc b/chrome/browser/ash/crosapi/user_data_stats_recorder_unittest.cc new file mode 100644 index 0000000..1af4747 --- /dev/null +++ b/chrome/browser/ash/crosapi/user_data_stats_recorder_unittest.cc
@@ -0,0 +1,116 @@ +// 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/user_data_stats_recorder.h" + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/test/metrics/histogram_tester.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace crosapi { +namespace user_data_stats_recorder { + +namespace { +constexpr char kCodeCachePath[] = "Code Cache"; +constexpr char kCodeCacheUMAName[] = "CodeCache"; +constexpr char kTextFileContent[] = "Hello, World!"; +constexpr int kTextFileSize = sizeof(kTextFileContent); +} // namespace + +TEST(UserDataStatsRecorderTest, ComputeDirectorySizeWithoutLinks) { + base::ScopedTempDir dir_1; + ASSERT_TRUE(dir_1.CreateUniqueTempDir()); + + ASSERT_TRUE( + base::WriteFile(dir_1.GetPath().Append(FILE_PATH_LITERAL("file1")), + kTextFileContent, kTextFileSize)); + ASSERT_TRUE( + base::CreateDirectory(dir_1.GetPath().Append(FILE_PATH_LITERAL("dir")))); + ASSERT_TRUE(base::WriteFile(dir_1.GetPath() + .Append(FILE_PATH_LITERAL("dir")) + .Append(FILE_PATH_LITERAL("file2")), + kTextFileContent, kTextFileSize)); + + // Check that `ComputeDirectorySizeWithoutLinks` returns the sum of sizes of + // the two files in the directory. + EXPECT_EQ(ComputeDirectorySizeWithoutLinks(dir_1.GetPath()), + kTextFileSize * 2); + + base::ScopedTempDir dir_2; + ASSERT_TRUE(dir_2.CreateUniqueTempDir()); + ASSERT_TRUE( + base::WriteFile(dir_2.GetPath().Append(FILE_PATH_LITERAL("file3")), + kTextFileContent, kTextFileSize)); + + ASSERT_TRUE(CreateSymbolicLink( + dir_2.GetPath().Append(FILE_PATH_LITERAL("file3")), + dir_1.GetPath().Append(FILE_PATH_LITERAL("link_to_file3")))); + + // Check that `ComputeDirectorySizeWithoutLinks` does not follow symlinks from + // `dir_1` to `dir_2`. + EXPECT_EQ(ComputeDirectorySizeWithoutLinks(dir_1.GetPath()), + kTextFileSize * 2); +} + +TEST(UserDataStatsRecorderTest, GetUMAItemName) { + base::FilePath profile_data_dir("/home/chronos/user"); + + EXPECT_STREQ(GetUMAItemName(profile_data_dir.Append(kCodeCachePath)).c_str(), + kCodeCacheUMAName); + + EXPECT_STREQ( + GetUMAItemName(profile_data_dir.Append(FILE_PATH_LITERAL("abcd"))) + .c_str(), + kUnknownUMAName); +} + +TEST(UserDataStatsRecorderTest, RecordUserDataSize) { + base::HistogramTester histogram_tester; + + base::FilePath profile_data_dir("/home/chronos/user"); + // Size in bytes. + int64_t size = 4 * 1024 * 1024; + RecordUserDataSize(profile_data_dir.Append(kCodeCachePath), size); + + std::string uma_name = + std::string(kUserDataStatsRecorderDataSize) + kCodeCacheUMAName; + + histogram_tester.ExpectTotalCount(uma_name, 1); + histogram_tester.ExpectBucketCount(uma_name, size / 1024 / 1024, 1); +} + +TEST(UserDataStatsRecorderTest, RecordUserDataSizes) { + base::HistogramTester histogram_tester; + base::ScopedTempDir profile_data_dir; + ASSERT_TRUE(profile_data_dir.CreateUniqueTempDir()); + + ASSERT_TRUE( + base::CreateDirectory(profile_data_dir.GetPath().Append(kCodeCachePath))); + ASSERT_TRUE(base::WriteFile(profile_data_dir.GetPath() + .Append(kCodeCachePath) + .Append(FILE_PATH_LITERAL("cache")), + kTextFileContent, kTextFileSize)); + ASSERT_TRUE(base::WriteFile( + profile_data_dir.GetPath().Append(FILE_PATH_LITERAL("abcd")), + kTextFileContent, kTextFileSize)); + std::string uma_name_1 = + std::string(kUserDataStatsRecorderDataSize) + kCodeCacheUMAName; + std::string uma_name_3 = + std::string(kUserDataStatsRecorderDataSize) + kUnknownUMAName; + + RecordUserDataSizes(profile_data_dir.GetPath()); + + histogram_tester.ExpectTotalCount(uma_name_1, 1); + histogram_tester.ExpectTotalCount(uma_name_3, 1); + + histogram_tester.ExpectBucketCount(uma_name_1, kTextFileSize / 1024 / 1024, + 1); + histogram_tester.ExpectBucketCount(uma_name_3, kTextFileSize / 1024 / 1024, + 1); +} + +} // namespace user_data_stats_recorder +} // namespace crosapi
diff --git a/chrome/browser/ash/file_manager/app_service_file_tasks.cc b/chrome/browser/ash/file_manager/app_service_file_tasks.cc index 0baedb78..a76067ec 100644 --- a/chrome/browser/ash/file_manager/app_service_file_tasks.cc +++ b/chrome/browser/ash/file_manager/app_service_file_tasks.cc
@@ -34,11 +34,9 @@ #include "components/arc/mojom/file_system.mojom.h" #include "components/arc/mojom/intent_helper.mojom.h" #include "components/services/app_service/public/cpp/intent_util.h" -#include "components/services/app_service/public/mojom/types.mojom-shared.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/entry_info.h" -#include "extensions/browser/extension_util.h" #include "storage/browser/file_system/file_system_context.h" #include "storage/browser/file_system/file_system_url.h" #include "url/gurl.h" @@ -46,8 +44,6 @@ namespace file_manager { namespace file_tasks { -using extensions::api::file_manager_private::Verb; - namespace { // TODO(crbug/1092784): Only going to support ARC app and web app // for now. @@ -58,12 +54,10 @@ case apps::mojom::AppType::kWeb: case apps::mojom::AppType::kSystemWeb: return TASK_TYPE_WEB_APP; - case apps::mojom::AppType::kExtension: - // TODO(petermarshall): Distinguish Chrome apps from Extensions. - return TASK_TYPE_FILE_HANDLER; case apps::mojom::AppType::kUnknown: case apps::mojom::AppType::kCrostini: case apps::mojom::AppType::kBuiltIn: + case apps::mojom::AppType::kExtension: case apps::mojom::AppType::kMacOs: case apps::mojom::AppType::kPluginVm: case apps::mojom::AppType::kStandaloneBrowser: @@ -107,34 +101,26 @@ // App Service doesn't exist in Incognito mode but we still want to find // handlers to open a download from its notification from Incognito mode. Use // the base profile in these cases (see crbug.com/1111695). - Profile* maybe_original_profile = profile; if (!apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(profile)) - maybe_original_profile = profile->GetOriginalProfile(); + profile = profile->GetOriginalProfile(); apps::AppServiceProxyChromeOs* proxy = - apps::AppServiceProxyFactory::GetForProfile(maybe_original_profile); + apps::AppServiceProxyFactory::GetForProfile(profile); - std::vector<apps::mojom::IntentFilePtr> intent_files; - intent_files.reserve(entries.size()); - for (size_t i = 0; i < entries.size(); i++) { - auto file = apps::mojom::IntentFile::New(); - file->url = file_urls.at(i); - file->mime_type = entries[i].mime_type; - file->is_directory = entries[i].is_directory - ? apps::mojom::OptionalBool::kTrue - : apps::mojom::OptionalBool::kFalse; - intent_files.push_back(std::move(file)); - } + std::vector<std::string> mime_types; + for (auto& entry : entries) + mime_types.push_back(entry.mime_type); std::vector<apps::IntentLaunchInfo> intent_launch_info = - proxy->GetAppsForFiles(std::move(intent_files)); + proxy->GetAppsForFiles(file_urls, mime_types); + using extensions::api::file_manager_private::Verb; for (auto& launch_entry : intent_launch_info) { apps::mojom::AppType app_type = proxy->AppRegistryCache().GetAppType(launch_entry.app_id); + // TODO(crbug/1092784): Only going to support ARC app and web apps. if (!(app_type == apps::mojom::AppType::kArc || app_type == apps::mojom::AppType::kWeb || - app_type == apps::mojom::AppType::kSystemWeb || - app_type == apps::mojom::AppType::kExtension)) + app_type == apps::mojom::AppType::kSystemWeb)) continue; if (app_type == apps::mojom::AppType::kWeb || @@ -156,7 +142,7 @@ // TODO(1240018): Remove when this feature is fully launched. This check // will not work for lacros web apps. web_app::WebAppProvider* provider = - web_app::WebAppProvider::GetDeprecated(maybe_original_profile); + web_app::WebAppProvider::GetDeprecated(profile); web_app::OsIntegrationManager& os_integration_manager = provider->os_integration_manager(); if (!os_integration_manager.IsFileHandlingAPIAvailable( @@ -164,12 +150,6 @@ continue; } - if (app_type == apps::mojom::AppType::kExtension) { - if (profile->IsOffTheRecord() && - !extensions::util::IsIncognitoEnabled(launch_entry.app_id, profile)) - continue; - } - constexpr int kIconSize = 32; GURL icon_url = apps::AppIconSource::GetIconURL(launch_entry.app_id, kIconSize); @@ -179,8 +159,9 @@ launch_entry.activity_label, Verb::VERB_OPEN_WITH, icon_url, /* is_default=*/false, // TODO(petermarshall): Handle the rest of the logic from FindWebTasks() - // e.g. prioritise non-generic handlers. - /* is_generic=*/launch_entry.is_generic_file_handler, + // e.g. IsGoodMatchAppsFileHandler(). + /* is_generic=*/ + !web_app::IsSystemAppIdWithFileHandlers(launch_entry.app_id), /* is_file_extension_match=*/launch_entry.is_file_extension_match)); } }
diff --git a/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc b/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc index 58af187..79ce88ae 100644 --- a/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc +++ b/chrome/browser/ash/file_manager/app_service_file_tasks_unittest.cc
@@ -12,7 +12,6 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/app_service_test.h" -#include "chrome/browser/apps/app_service/intent_util.h" #include "chrome/browser/ash/file_manager/file_tasks.h" #include "chrome/browser/ash/file_manager/path_util.h" #include "chrome/test/base/testing_profile.h" @@ -20,7 +19,6 @@ #include "components/services/app_service/public/mojom/types.mojom.h" #include "content/public/test/browser_task_environment.h" #include "extensions/browser/entry_info.h" -#include "extensions/common/extension_builder.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/features.h" #include "url/gurl.h" @@ -31,8 +29,6 @@ const char kAppIdText[] = "abcdefg"; const char kAppIdImage[] = "gfedcba"; const char kAppIdAny[] = "hijklmn"; -const char kChromeAppId[] = "chromeappid"; -const char kChromeAppWithVerbsId[] = "chromeappwithverbsid"; const char kAppIdTextWild[] = "zxcvbn"; const char kMimeTypeText[] = "text/plain"; const char kMimeTypeImage[] = "image/jpeg"; @@ -74,7 +70,6 @@ struct FakeFile { std::string file_name; std::string mime_type; - bool is_directory = false; }; std::vector<FullTaskDescriptor> FindAppServiceTasks( @@ -85,7 +80,7 @@ entries.emplace_back( util::GetMyFilesFolderForProfile(profile()).AppendASCII( fake_file.file_name), - fake_file.mime_type, fake_file.is_directory); + fake_file.mime_type, false); file_urls.push_back(test_url(fake_file.file_name)); } @@ -147,118 +142,6 @@ kActivityLabelAny); } - // Provides file handlers for all extensions and images. - void AddChromeApp() { - extensions::ExtensionBuilder baz_app; - baz_app.SetManifest( - extensions::DictionaryBuilder() - .Set("name", "Baz") - .Set("version", "1.0.0") - .Set("manifest_version", 2) - .Set("app", - extensions::DictionaryBuilder() - .Set("background", - extensions::DictionaryBuilder() - .Set("scripts", extensions::ListBuilder() - .Append("background.js") - .Build()) - .Build()) - .Build()) - .Set( - "file_handlers", - extensions::DictionaryBuilder() - .Set("any", extensions::DictionaryBuilder() - .Set("extensions", extensions::ListBuilder() - .Append("*") - .Append("bar") - .Build()) - .Build()) - .Set("image", extensions::DictionaryBuilder() - .Set("types", extensions::ListBuilder() - .Append("image/*") - .Build()) - .Build()) - .Build()) - .Build()); - baz_app.SetID(kChromeAppId); - auto filters = - apps_util::CreateChromeAppIntentFilters(baz_app.Build().get()); - AddFakeAppWithIntentFilters(kChromeAppId, std::move(filters), - apps::mojom::AppType::kExtension); - } - - void AddChromeAppWithVerbs() { - extensions::ExtensionBuilder foo_app; - foo_app.SetManifest( - extensions::DictionaryBuilder() - .Set("name", "Foo") - .Set("version", "1.0.0") - .Set("manifest_version", 2) - .Set("app", - extensions::DictionaryBuilder() - .Set("background", - extensions::DictionaryBuilder() - .Set("scripts", extensions::ListBuilder() - .Append("background.js") - .Build()) - .Build()) - .Build()) - .Set( - "file_handlers", - extensions::DictionaryBuilder() - .Set("any_with_directories", - extensions::DictionaryBuilder() - .Set("include_directories", true) - .Set("types", - extensions::ListBuilder().Append("*").Build()) - .Set("verb", "open_with") - .Build()) - .Set("html_handler", - extensions::DictionaryBuilder() - .Set("title", "Html") - .Set("types", extensions::ListBuilder() - .Append("text/html") - .Build()) - .Set("verb", "open_with") - .Build()) - .Set("plain_text", - extensions::DictionaryBuilder() - .Set("title", "Plain") - .Set("types", extensions::ListBuilder() - .Append("text/plain") - .Build()) - .Build()) - .Set("share_plain_text", - extensions::DictionaryBuilder() - .Set("title", "Share Plain") - .Set("types", extensions::ListBuilder() - .Append("text/plain") - .Build()) - .Set("verb", "share_with") - .Build()) - .Set("any_pack", extensions::DictionaryBuilder() - .Set("types", extensions::ListBuilder() - .Append("*") - .Build()) - .Set("verb", "pack_with") - .Build()) - .Set("plain_text_add_to", - extensions::DictionaryBuilder() - .Set("title", "Plain") - .Set("types", extensions::ListBuilder() - .Append("text/plain") - .Build()) - .Set("verb", "add_to") - .Build()) - .Build()) - .Build()); - foo_app.SetID(kChromeAppWithVerbsId); - auto filters = - apps_util::CreateChromeAppIntentFilters(foo_app.Build().get()); - AddFakeAppWithIntentFilters(kChromeAppWithVerbsId, std::move(filters), - apps::mojom::AppType::kExtension); - } - base::test::ScopedFeatureList feature_list_; content::BrowserTaskEnvironment task_environment_; std::unique_ptr<TestingProfile> profile_; @@ -301,7 +184,6 @@ ASSERT_EQ(1U, tasks.size()); EXPECT_EQ(kAppIdText, tasks[0].task_descriptor.app_id); EXPECT_EQ(kActivityLabelText, tasks[0].task_title); - EXPECT_FALSE(tasks[0].is_generic_file_handler); } // Test that between an image app and text app, the image app can be @@ -315,7 +197,6 @@ ASSERT_EQ(1U, tasks.size()); EXPECT_EQ(kAppIdImage, tasks[0].task_descriptor.app_id); EXPECT_EQ(kActivityLabelImage, tasks[0].task_title); - EXPECT_FALSE(tasks[0].is_generic_file_handler); } // Test that between an image app, text app and an app that can handle every @@ -330,7 +211,6 @@ ASSERT_EQ(1U, tasks.size()); EXPECT_EQ(kAppIdAny, tasks[0].task_descriptor.app_id); EXPECT_EQ(kActivityLabelAny, tasks[0].task_title); - EXPECT_TRUE(tasks[0].is_generic_file_handler); } // Don't register any apps and check that we get no matches. @@ -360,7 +240,6 @@ ASSERT_EQ(1U, tasks.size()); EXPECT_EQ(kAppIdText, tasks[0].task_descriptor.app_id); EXPECT_EQ(kActivityLabelText, tasks[0].task_title); - EXPECT_FALSE(tasks[0].is_generic_file_handler); } // Check that a web app that only handles text does not match when we have both @@ -423,115 +302,5 @@ EXPECT_EQ(kActivityLabelText, tasksBoth[0].task_title); } -// Check that Baz's ".*" handler, which is generic, is matched. -TEST_F(AppServiceFileTasksTestEnabled, FindAppServiceChromeAppText) { - AddChromeApp(); - std::vector<FullTaskDescriptor> tasks = - FindAppServiceTasks({{"foo.txt", kMimeTypeText}}); - ASSERT_EQ(1U, tasks.size()); - EXPECT_EQ(kChromeAppId, tasks[0].task_descriptor.app_id); - EXPECT_EQ("any", tasks[0].task_descriptor.action_id); - EXPECT_EQ(TASK_TYPE_FILE_HANDLER, tasks[0].task_descriptor.task_type); - EXPECT_EQ("Baz", tasks[0].task_title); - EXPECT_TRUE(tasks[0].is_generic_file_handler); - EXPECT_TRUE(tasks[0].is_file_extension_match); - EXPECT_EQ(Verb::VERB_OPEN_WITH, tasks[0].task_verb); -} - -// File extension matches with bar, but there is a generic * type as well, -// so the overall match should still be generic. -TEST_F(AppServiceFileTasksTestEnabled, FindAppServiceChromeAppBar) { - AddChromeApp(); - std::vector<FullTaskDescriptor> tasks = - FindAppServiceTasks({{"foo.bar", kMimeTypeText}}); - ASSERT_EQ(1U, tasks.size()); - EXPECT_EQ(kChromeAppId, tasks[0].task_descriptor.app_id); - EXPECT_EQ("any", tasks[0].task_descriptor.action_id); - EXPECT_EQ(TASK_TYPE_FILE_HANDLER, tasks[0].task_descriptor.task_type); - EXPECT_EQ("Baz", tasks[0].task_title); - EXPECT_TRUE(tasks[0].is_generic_file_handler); - EXPECT_TRUE(tasks[0].is_file_extension_match); - EXPECT_EQ(Verb::VERB_OPEN_WITH, tasks[0].task_verb); -} - -// Check that we can get web apps and Chrome apps in the same call. -TEST_F(AppServiceFileTasksTestEnabled, FindAppServiceMultiAppType) { - AddTextApp(); - AddChromeApp(); - std::vector<FullTaskDescriptor> tasks = - FindAppServiceTasks({{"foo.txt", kMimeTypeText}}); - ASSERT_EQ(2U, tasks.size()); - EXPECT_EQ(kAppIdText, tasks[0].task_descriptor.app_id); - EXPECT_EQ(kActivityLabelText, tasks[0].task_title); - EXPECT_EQ(TASK_TYPE_WEB_APP, tasks[0].task_descriptor.task_type); - EXPECT_EQ(kChromeAppId, tasks[1].task_descriptor.app_id); - EXPECT_EQ("Baz", tasks[1].task_title); - EXPECT_EQ(TASK_TYPE_FILE_HANDLER, tasks[1].task_descriptor.task_type); -} - -// Check that Baz's "image/*" handler is picked because it is not generic, -// because it matches the mime type directly, even though there is an earlier -// generic handler. -TEST_F(AppServiceFileTasksTestEnabled, FindAppServiceChromeAppImage) { - AddChromeApp(); - std::vector<FullTaskDescriptor> tasks = - FindAppServiceTasks({{"bar.jpeg", kMimeTypeImage}}); - ASSERT_EQ(1U, tasks.size()); - EXPECT_EQ(kChromeAppId, tasks[0].task_descriptor.app_id); - EXPECT_EQ("image", tasks[0].task_descriptor.action_id); - EXPECT_EQ(TASK_TYPE_FILE_HANDLER, tasks[0].task_descriptor.task_type); - EXPECT_EQ("Baz", tasks[0].task_title); - EXPECT_FALSE(tasks[0].is_generic_file_handler); - EXPECT_FALSE(tasks[0].is_file_extension_match); - EXPECT_EQ(Verb::VERB_OPEN_WITH, tasks[0].task_verb); -} - -TEST_F(AppServiceFileTasksTestEnabled, FindAppServiceChromeAppWithVerbs) { - AddChromeAppWithVerbs(); - std::vector<FullTaskDescriptor> tasks = - FindAppServiceTasks({{"foo.txt", kMimeTypeText}}); - - // We expect that all non-"open_with" handlers are ignored, and that we - // only get one open_with handler. - ASSERT_EQ(1U, tasks.size()); - EXPECT_EQ(kChromeAppWithVerbsId, tasks[0].task_descriptor.app_id); - EXPECT_EQ("Foo", tasks[0].task_title); - EXPECT_EQ("plain_text", tasks[0].task_descriptor.action_id); - EXPECT_FALSE(tasks[0].is_generic_file_handler); - EXPECT_FALSE(tasks[0].is_file_extension_match); - EXPECT_EQ(Verb::VERB_OPEN_WITH, tasks[0].task_verb); -} - -TEST_F(AppServiceFileTasksTestEnabled, FindAppServiceChromeAppWithVerbs_Html) { - AddChromeAppWithVerbs(); - std::vector<FullTaskDescriptor> tasks = - FindAppServiceTasks({{"foo.html", kMimeTypeHtml}}); - - // Check that we get the non-generic handler which appears later in the - // manifest. - EXPECT_EQ(kChromeAppWithVerbsId, tasks[0].task_descriptor.app_id); - EXPECT_EQ("Foo", tasks[0].task_title); - EXPECT_EQ("html_handler", tasks[0].task_descriptor.action_id); - EXPECT_FALSE(tasks[0].is_generic_file_handler); - EXPECT_FALSE(tasks[0].is_file_extension_match); - EXPECT_EQ(Verb::VERB_OPEN_WITH, tasks[0].task_verb); -} - -TEST_F(AppServiceFileTasksTestEnabled, - FindAppServiceChromeAppWithVerbs_Directory) { - AddChromeAppWithVerbs(); - std::vector<FullTaskDescriptor> tasks = - FindAppServiceTasks({{"dir", "", true}}); - - // Only one handler handles directories. - ASSERT_EQ(1U, tasks.size()); - EXPECT_EQ(kChromeAppWithVerbsId, tasks[0].task_descriptor.app_id); - EXPECT_EQ("Foo", tasks[0].task_title); - EXPECT_EQ("any_with_directories", tasks[0].task_descriptor.action_id); - EXPECT_TRUE(tasks[0].is_generic_file_handler); - EXPECT_FALSE(tasks[0].is_file_extension_match); - EXPECT_EQ(Verb::VERB_OPEN_WITH, tasks[0].task_verb); -} - } // namespace file_tasks } // namespace file_manager.
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc index 9dba649..bb24e62 100644 --- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc +++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -467,10 +467,12 @@ TestCase("checkCutDisabledForReadOnlyFolder"), TestCase("checkPasteIntoFolderEnabledForReadWriteFolder"), TestCase("checkPasteIntoFolderDisabledForReadOnlyFolder"), - TestCase("checkInstallWithLinuxDisabledForDebianFile"), + // TODO(crbug.com/1251932): Fix broken test + // TestCase("checkInstallWithLinuxDisabledForDebianFile"), TestCase("checkInstallWithLinuxEnabledForDebianFile"), TestCase("checkImportCrostiniImageEnabled"), - TestCase("checkImportCrostiniImageDisabled"), + // TODO(crbug.com/1251932): Fix broken test + // TestCase("checkImportCrostiniImageDisabled"), TestCase("checkNewFolderEnabledInsideReadWriteFolder"), TestCase("checkNewFolderDisabledInsideReadOnlyFolder"), TestCase("checkPasteEnabledInsideReadWriteFolder"),
diff --git a/chrome/browser/ash/file_manager/file_tasks.cc b/chrome/browser/ash/file_manager/file_tasks.cc index 77cce0d..7e152363 100644 --- a/chrome/browser/ash/file_manager/file_tasks.cc +++ b/chrome/browser/ash/file_manager/file_tasks.cc
@@ -833,15 +833,18 @@ std::unique_ptr<std::vector<FullTaskDescriptor>> result_list) { std::vector<FullTaskDescriptor>* result_list_ptr = result_list.get(); - // 2. Find and append file browser handler tasks. We know there aren't + // 2. Continues from FindAllTypesOfTasks. Find and append file handler tasks. + FindFileHandlerTasks(profile, entries, result_list_ptr); + + // 3. Find and append file browser handler tasks. We know there aren't // duplicates because "file_browser_handlers" and "file_handlers" shouldn't // be used in the same manifest.json. FindFileBrowserHandlerTasks(profile, file_urls, result_list_ptr); - // 3. Web tasks file_handlers (View/Open With), and Chrome app file_handlers. + // 4. Web tasks file_handlers (View/Open With). FindAppServiceTasks(profile, entries, file_urls, result_list_ptr); - // 4. Find and append Guest OS tasks. + // 5. Find and append Guest OS tasks. FindGuestOsTasks(profile, entries, file_urls, result_list_ptr, // Done. Apply post-filtering and callback. base::BindOnce(PostProcessFoundTasks, profile, entries,
diff --git a/chrome/browser/ash/file_manager/file_tasks_browsertest.cc b/chrome/browser/ash/file_manager/file_tasks_browsertest.cc index 260150b..b9427ee 100644 --- a/chrome/browser/ash/file_manager/file_tasks_browsertest.cc +++ b/chrome/browser/ash/file_manager/file_tasks_browsertest.cc
@@ -360,7 +360,8 @@ TaskDescriptor(extension->id(), StringToTaskType("app"), "tiffAction"), {"tiff"}, {"image/tiff"}); if (profile_type() == TestProfileType::kIncognito) { - // In incognito, the installed app is not enabled and we filter it out. + // In incognito, the provided file system can exist, but the file handler + // preference can't be changed. TestExpectationsAgainstDefaultTasks({{"tiff", kMediaAppId}}); } else { TestExpectationsAgainstDefaultTasks({{"tiff", extension->id().c_str()}});
diff --git a/chrome/browser/ash/file_manager/file_tasks_unittest.cc b/chrome/browser/ash/file_manager/file_tasks_unittest.cc index f1c09ae..2562494 100644 --- a/chrome/browser/ash/file_manager/file_tasks_unittest.cc +++ b/chrome/browser/ash/file_manager/file_tasks_unittest.cc
@@ -879,6 +879,90 @@ ASSERT_TRUE(tasks.empty()); } +// Test that all kinds of apps (file handler and file browser handler) are +// returned. +TEST_F(FileManagerFileTasksComplexTest, FindAllTypesOfTasks) { + // kFooId and kBarId copied from FindFileHandlerTasks test above. + const char kFooId[] = "hhgbjpmdppecanaaogonaigmmifgpaph"; + const char kBarId[] = "odlhccgofgkadkkhcmhgnhgahonahoca"; + + // Foo.app can handle "text/plain". + // This is a packaged app (file handler). + extensions::ExtensionBuilder foo_app; + foo_app.SetManifest( + extensions::DictionaryBuilder() + .Set("name", "Foo") + .Set("version", "1.0.0") + .Set("manifest_version", 2) + .Set("app", extensions::DictionaryBuilder() + .Set("background", + extensions::DictionaryBuilder() + .Set("scripts", extensions::ListBuilder() + .Append("background.js") + .Build()) + .Build()) + .Build()) + .Set("file_handlers", + extensions::DictionaryBuilder() + .Set("text", extensions::DictionaryBuilder() + .Set("title", "Text") + .Set("types", extensions::ListBuilder() + .Append("text/plain") + .Build()) + .Build()) + .Build()) + .Build()); + foo_app.SetID(kFooId); + extension_service_->AddExtension(foo_app.Build().get()); + + // Bar.app can only handle ".txt". + // This is an extension (file browser handler). + extensions::ExtensionBuilder bar_app; + bar_app.SetManifest( + extensions::DictionaryBuilder() + .Set("name", "Bar") + .Set("version", "1.0.0") + .Set("manifest_version", 2) + .Set("permissions", + extensions::ListBuilder().Append("fileBrowserHandler").Build()) + .Set("file_browser_handlers", + extensions::ListBuilder() + .Append( + extensions::DictionaryBuilder() + .Set("id", "open") + .Set("default_title", "open") + .Set("file_filters", extensions::ListBuilder() + .Append("filesystem:*.txt") + .Build()) + .Build()) + .Build()) + .Build()); + bar_app.SetID(kBarId); + extension_service_->AddExtension(bar_app.Build().get()); + + // Find apps for "foo.txt". All apps should be found. + std::vector<extensions::EntryInfo> entries; + std::vector<GURL> file_urls; + entries.emplace_back(util::GetMyFilesFolderForProfile(test_profile_.get()) + .AppendASCII("foo.txt"), + "text/plain", false); + file_urls.emplace_back("filesystem:chrome-extension://id/dir/foo.txt"); + + std::vector<FullTaskDescriptor> tasks; + FindAllTypesOfTasksSynchronousWrapper().Call(test_profile_.get(), entries, + file_urls, &tasks); + ASSERT_EQ(2U, tasks.size()); + + // Sort the app IDs, as the order is not guaranteed. + std::vector<std::string> app_ids; + app_ids.push_back(tasks[0].task_descriptor.app_id); + app_ids.push_back(tasks[1].task_descriptor.app_id); + std::sort(app_ids.begin(), app_ids.end()); + // Confirm that all apps are found. + EXPECT_EQ(kFooId, app_ids[0]); + EXPECT_EQ(kBarId, app_ids[1]); +} + TEST_F(FileManagerFileTasksComplexTest, FindAllTypesOfTasks_GoogleDocument) { // kFooId and kBarId copied from FindFileHandlerTasks test above. const char kBarId[] = "odlhccgofgkadkkhcmhgnhgahonahoca";
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector.cc b/chrome/browser/ash/policy/status_collector/device_status_collector.cc index 161bb68fe..e906c2c 100644 --- a/chrome/browser/ash/policy/status_collector/device_status_collector.cc +++ b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
@@ -2233,16 +2233,8 @@ if (!statistics_provider_->GetMachineStatistic( chromeos::system::kFirmwareWriteProtectCurrentKey, &firmware_write_protect)) { - // TODO(crbug.com/1123153): Remove logging after the bug is fixed. - LOG(WARNING) << "Missing " - << chromeos::system::kFirmwareWriteProtectCurrentKey - << " statistics"; return false; } - // TODO(crbug.com/1123153): Remove logging after the bug is fixed. - LOG(WARNING) << "Statistics " - << chromeos::system::kFirmwareWriteProtectCurrentKey << ": " - << firmware_write_protect; if (firmware_write_protect == chromeos::system::kFirmwareWriteProtectCurrentValueOff) {
diff --git a/chrome/browser/ash/policy/uploading/status_uploader.cc b/chrome/browser/ash/policy/uploading/status_uploader.cc index 9fbb475..57a8be488b 100644 --- a/chrome/browser/ash/policy/uploading/status_uploader.cc +++ b/chrome/browser/ash/policy/uploading/status_uploader.cc
@@ -212,14 +212,8 @@ return; } - // TODO(crbug.com/1123153): Remove write_protect_switch logging after bugfix. - SYSLOG(INFO) - << "Starting status upload: has_device_status = " << has_device_status - << " write_protect_switch = " - << (callback_params.device_status && - callback_params.device_status->has_write_protect_switch() - ? callback_params.device_status->write_protect_switch() - : -1); + SYSLOG(INFO) << "Starting status upload: has_device_status = " + << has_device_status; client_->UploadDeviceStatus(callback_params.device_status.get(), callback_params.session_status.get(),
diff --git a/chrome/browser/browsing_data/access_context_audit_browsertest.cc b/chrome/browser/browsing_data/access_context_audit_browsertest.cc index 5ee3975..383d4db8 100644 --- a/chrome/browser/browsing_data/access_context_audit_browsertest.cc +++ b/chrome/browser/browsing_data/access_context_audit_browsertest.cc
@@ -139,12 +139,13 @@ // Calls the accessStorage javascript function and awaits its completion for // each frame in the active web contents for |browser|. void EnsurePageAccessedStorage(content::WebContents* web_contents) { - auto frames = web_contents->GetAllFrames(); - for (auto* frame : frames) { - ASSERT_TRUE(content::EvalJs( - frame, "(async () => { return await accessStorage();})()") - .value.GetBool()); - } + web_contents->GetMainFrame()->ForEachRenderFrameHost( + base::BindRepeating([](content::RenderFrameHost* frame) { + EXPECT_TRUE( + content::EvalJs(frame, + "(async () => { return await accessStorage();})()") + .value.GetBool()); + })); } } // namespace
diff --git a/chrome/browser/chrome_navigation_browsertest.cc b/chrome/browser/chrome_navigation_browsertest.cc index ea30d9d..62faccb 100644 --- a/chrome/browser/chrome_navigation_browsertest.cc +++ b/chrome/browser/chrome_navigation_browsertest.cc
@@ -905,9 +905,9 @@ } // 3. Find the cross-site subframes in the popup. - EXPECT_EQ(3u, popup->GetAllFrames().size()); content::RenderFrameHost* popup_root = popup->GetMainFrame(); - content::RenderFrameHost* cross_site_subframe = popup->GetAllFrames()[1]; + content::RenderFrameHost* cross_site_subframe = ChildFrameAt(popup_root, 0); + ASSERT_TRUE(cross_site_subframe); EXPECT_NE(cross_site_subframe->GetLastCommittedOrigin(), popup_root->GetLastCommittedOrigin()); EXPECT_NE(cross_site_subframe->GetLastCommittedOrigin(),
diff --git a/chrome/browser/chrome_shared_array_buffer_browsertest.cc b/chrome/browser/chrome_shared_array_buffer_browsertest.cc index 13b81cbe..5c51ce5 100644 --- a/chrome/browser/chrome_shared_array_buffer_browsertest.cc +++ b/chrome/browser/chrome_shared_array_buffer_browsertest.cc
@@ -130,7 +130,7 @@ )", sub_url))); WaitForLoadStop(web_contents()); - content::RenderFrameHost* sub_document = web_contents()->GetAllFrames()[1]; + content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0); EXPECT_EQ(false, EvalJs(main_document, "self.crossOriginIsolated")); EXPECT_EQ(false, EvalJs(sub_document, "self.crossOriginIsolated")); @@ -161,7 +161,7 @@ )", sub_url))); WaitForLoadStop(web_contents()); - content::RenderFrameHost* sub_document = web_contents()->GetAllFrames()[1]; + content::RenderFrameHost* sub_document = ChildFrameAt(main_document, 0); EXPECT_EQ(false, EvalJs(main_document, "self.crossOriginIsolated")); EXPECT_EQ(false, EvalJs(sub_document, "self.crossOriginIsolated"));
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc index 21e69eb..37c31af 100644 --- a/chrome/browser/download/save_page_browsertest.cc +++ b/chrome/browser/download/save_page_browsertest.cc
@@ -1152,20 +1152,23 @@ // Kill one of renderer processes (this is the essence of this test). WebContents* web_contents = GetCurrentTab(browser()); bool did_kill_a_process = false; - for (RenderFrameHost* frame : web_contents->GetAllFrames()) { - if (frame->GetLastCommittedURL().host() == "bar.com") { - RenderProcessHost* process_to_kill = frame->GetProcess(); - EXPECT_NE( - web_contents->GetMainFrame()->GetProcess()->GetID(), - process_to_kill->GetID()) - << "a.com and bar.com should be in different processes."; + web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating( + [](WebContents* web_contents, bool* did_kill_a_process, + RenderFrameHost* frame) { + if (frame->GetLastCommittedURL().host() == "bar.com") { + RenderProcessHost* process_to_kill = frame->GetProcess(); + EXPECT_NE(web_contents->GetMainFrame()->GetProcess()->GetID(), + process_to_kill->GetID()) + << "a.com and bar.com should be in different processes."; - EXPECT_TRUE(process_to_kill->FastShutdownIfPossible()); - EXPECT_FALSE(process_to_kill->IsInitializedAndNotDead()); - did_kill_a_process = true; - break; - } - } + EXPECT_TRUE(process_to_kill->FastShutdownIfPossible()); + EXPECT_FALSE(process_to_kill->IsInitializedAndNotDead()); + *did_kill_a_process = true; + return content::RenderFrameHost::FrameIterationAction::kStop; + } + return content::RenderFrameHost::FrameIterationAction::kContinue; + }, + web_contents, &did_kill_a_process)); EXPECT_TRUE(did_kill_a_process); // Main verification is that we don't hang and time out when saving. @@ -1292,7 +1295,8 @@ const std::vector<std::string>& expected_substrings, content::SavePageType save_page_type) { int actual_number_of_frames = - GetCurrentTab(browser())->GetAllFrames().size(); + CollectAllRenderFrameHosts(GetCurrentTab(browser())->GetPrimaryPage()) + .size(); EXPECT_EQ(expected_number_of_frames, actual_number_of_frames); for (const auto& expected_substring : expected_substrings) { @@ -1314,10 +1318,13 @@ save_page_type == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) { DLOG(INFO) << "Verifying that a.htm frame has fully loaded..."; std::vector<std::string> frame_names; - for (content::RenderFrameHost* frame : - GetCurrentTab(browser())->GetAllFrames()) { - frame_names.push_back(frame->GetFrameName()); - } + GetCurrentTab(browser())->GetMainFrame()->ForEachRenderFrameHost( + base::BindRepeating( + [](std::vector<std::string>* frame_names, + content::RenderFrameHost* frame) { + frame_names->push_back(frame->GetFrameName()); + }, + &frame_names)); EXPECT_THAT(frame_names, testing::Contains("Frame name of a.htm")); }
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc index fef586d..b4167bd 100644 --- a/chrome/browser/extensions/content_script_apitest.cc +++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -1080,7 +1080,7 @@ var iframe = document.createElement('iframe'); document.body.appendChild(iframe); window.name = 'main-frame'; )")); - content::RenderFrameHost* subframe1 = web_contents->GetAllFrames()[1]; + content::RenderFrameHost* subframe1 = ChildFrameAt(web_contents, 0); ASSERT_TRUE( content::ExecJs(subframe1, "var w = window.open('', 'main-frame');")); EXPECT_EQ(subframe1, web_contents->GetOpener());
diff --git a/chrome/browser/extensions/extension_cookies_browsertest.cc b/chrome/browser/extensions/extension_cookies_browsertest.cc index cc460df..158cd83 100644 --- a/chrome/browser/extensions/extension_cookies_browsertest.cc +++ b/chrome/browser/extensions/extension_cookies_browsertest.cc
@@ -766,8 +766,8 @@ content::JsReplace(kSubframeInjectionScriptTemplate, extension->GetResourceURL("subframe.html")))); subframe_nav_observer.Wait(); - ASSERT_EQ(2u, web_contents()->GetAllFrames().size()); - extension_subframe = web_contents()->GetAllFrames()[1]; + extension_subframe = ChildFrameAt(web_contents(), 0); + ASSERT_TRUE(extension_subframe); ASSERT_EQ(extension->origin(), extension_subframe->GetLastCommittedOrigin()); }
diff --git a/chrome/browser/extensions/extension_nacl_browsertest.cc b/chrome/browser/extensions/extension_nacl_browsertest.cc index f7e19e8..ceafc60 100644 --- a/chrome/browser/extensions/extension_nacl_browsertest.cc +++ b/chrome/browser/extensions/extension_nacl_browsertest.cc
@@ -258,7 +258,7 @@ // Sanity check - the test setup should cause main frame and subframe to be in // a different process. - content::RenderFrameHost* subframe = web_contents->GetAllFrames()[1]; + content::RenderFrameHost* subframe = ChildFrameAt(web_contents, 0); EXPECT_NE(web_contents->GetMainFrame()->GetProcess(), subframe->GetProcess()); // Insert a plugin element into the subframe. Before the fix from
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 6621e76..5ff4200 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1032,6 +1032,11 @@ "expiry_milestone": 97 }, { + "name": "default-user-agent", + "owners": [ "gambard", "bling-flags@google.com" ], + "expiry_milestone": 100 + }, + { "name": "default-wkwebview-context-menu", "owners": [ "gambard", "bling-flags@google.com" ], "expiry_milestone": 100 @@ -1069,11 +1074,6 @@ "expiry_milestone": 97 }, { - "name": "desktop-version-default", - "owners": [ "gambard", "bling-flags@google.com" ], - "expiry_milestone": 100 - }, - { "name": "destroy-profile-on-browser-close", "owners": [ "nicolaso" ], "expiry_milestone": 98 @@ -2109,11 +2109,6 @@ "expiry_milestone": 95 }, { - "name": "enable-incognito-authentication-ios", - "owners": [ "stkhapugin", "bling-flags@google.com" ], - "expiry_milestone": 90 - }, - { "name": "enable-incognito-shortcut-on-desktop", "owners": [ "rhalavati", "chrome-privacy-core@google.com" ], "expiry_milestone": 92 @@ -2403,6 +2398,14 @@ "expiry_milestone": -1 }, { + "name": "enable-payment-request-basic-card", + "owners": [ "maxlg", "web-payments-team@google.com" ], + // This flag is used by developers to disable the "basic-card" method, to + // make sure their web pages do not break after Chrome deprecates + // "basic-card" in M100. + "expiry_milestone": 100 + }, + { "name": "enable-pci-guard-ui", "owners": [ "jimmyxgong", "cros-peripherals@google.com" ], "expiry_milestone": 94 @@ -3898,11 +3901,6 @@ "expiry_milestone": 92 }, { - "name": "mobile-google-srp", - "owners": [ "gambard", "bling-flags@google.com" ], - "expiry_milestone": 100 - }, - { "name": "mobile-identity-consistency", "owners": [ "bsazonov", "aliceywang", "msarda", "fernandex" ], "expiry_milestone": 99
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index c25d821..1b11896 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2756,6 +2756,11 @@ const char kWebPaymentsExperimentalFeaturesDescription[] = "Enable experimental Web Payments API features"; +const char kPaymentRequestBasicCardName[] = + "PaymentRequest API 'basic-card' method"; +const char kPaymentRequestBasicCardDescription[] = + "The 'basic-card' payment method of the PaymentRequest API."; + const char kAppStoreBillingDebugName[] = "Web Payments App Store Billing Debug Mode"; const char kAppStoreBillingDebugDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 6d44787d..04e4a97 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1560,6 +1560,9 @@ extern const char kWebPaymentsExperimentalFeaturesName[]; extern const char kWebPaymentsExperimentalFeaturesDescription[]; +extern const char kPaymentRequestBasicCardName[]; +extern const char kPaymentRequestBasicCardDescription[]; + extern const char kAppStoreBillingDebugName[]; extern const char kAppStoreBillingDebugDescription[];
diff --git a/chrome/browser/lacros/net/network_settings_translation.h b/chrome/browser/lacros/net/network_settings_translation.h new file mode 100644 index 0000000..758e60c --- /dev/null +++ b/chrome/browser/lacros/net/network_settings_translation.h
@@ -0,0 +1,25 @@ +// 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_LACROS_NET_NETWORK_SETTINGS_TRANSLATION_H_ +#define CHROME_BROWSER_LACROS_NET_NETWORK_SETTINGS_TRANSLATION_H_ + +#include "chromeos/crosapi/mojom/network_settings_service.mojom.h" +#include "net/proxy_resolution/proxy_config_with_annotation.h" + +namespace chromeos { + +// Translates the proxy from a crosapi mojo representation to an internal //net +// proxy representation. Used when sending the proxy configuration set by an +// extension in the Lacros primary profile to Ash-Chrome. +net::ProxyConfigWithAnnotation CrosapiProxyToNetProxy( + crosapi::mojom::ProxyConfigPtr crosapi_proxy); + +// Translates the proxy from an internal //net proxy representation to a crosapi +// mojo representation. +crosapi::mojom::ProxyConfigPtr NetProxyToCrosapiProxy( + const net::ProxyConfigWithAnnotation& proxy_config); + +} // namespace chromeos +#endif // CHROME_BROWSER_LACROS_NET_NETWORK_SETTINGS_TRANSLATION_H_
diff --git a/chrome/browser/lacros/net/network_settings_translation_crosapi.cc b/chrome/browser/lacros/net/network_settings_translation_crosapi.cc new file mode 100644 index 0000000..8fafe4e --- /dev/null +++ b/chrome/browser/lacros/net/network_settings_translation_crosapi.cc
@@ -0,0 +1,122 @@ +// 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/lacros/net/network_settings_translation.h" + +#include "components/proxy_config/proxy_config_pref_names.h" +#include "components/proxy_config/proxy_prefs.h" +#include "net/base/host_port_pair.h" +#include "net/base/proxy_server.h" +#include "net/proxy_resolution/proxy_config.h" +#include "net/proxy_resolution/proxy_list.h" +#include "net/traffic_annotation/network_traffic_annotation.h" + +namespace { + +constexpr net::NetworkTrafficAnnotationTag kAshProxyConfigTrafficAnnotation = + net::DefineNetworkTrafficAnnotation("proxy_config_system", R"( + semantics { + sender: "Proxy Config" + description: + "Establishing a connection through a proxy server using system proxy " + "settings." + trigger: + "Whenever a network request is made when the system proxy settings " + "are used, and they indicate to use a proxy server." + data: + "Proxy configuration." + destination: OTHER + destination_other: + "The proxy server specified in the configuration." + } + policy { + cookies_allowed: NO + setting: + "User cannot override system proxy settings, but can change them " + "through the Chrome OS Network Settings UI." + policy_exception_justification: + "Using either of 'ProxyMode', 'ProxyServer', or 'ProxyPacUrl' " + "policies can set Chrome to use a specific proxy settings and avoid " + "system proxy." + })"); + +net::ProxyConfigWithAnnotation TranslatePacProxySettings( + crosapi::mojom::ProxySettingsPacPtr proxy_settings) { + if (!proxy_settings->pac_url.is_valid()) + return net::ProxyConfigWithAnnotation::CreateDirect(); + net::ProxyConfig proxy_config = + net::ProxyConfig::CreateFromCustomPacURL(proxy_settings->pac_url); + if (proxy_settings->pac_mandatory) + proxy_config.set_pac_mandatory(proxy_settings->pac_mandatory); + return net::ProxyConfigWithAnnotation(proxy_config, + kAshProxyConfigTrafficAnnotation); +} + +net::ProxyConfigWithAnnotation TranslateWpadProxySettings( + crosapi::mojom::ProxySettingsWpadPtr proxy_settings) { + // Ash-Chrome has it's own mechanisms for detecting the PAC URL when + // configured via WPAD. + net::ProxyConfig proxy_config = net::ProxyConfig::CreateAutoDetect(); + return net::ProxyConfigWithAnnotation(proxy_config, + kAshProxyConfigTrafficAnnotation); +} + +net::ProxyConfigWithAnnotation TranslateManualProxySettings( + crosapi::mojom::ProxySettingsManualPtr proxy_settings) { + net::ProxyConfig proxy_config = net::ProxyConfig(); + proxy_config.proxy_rules().type = + net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME; + + for (auto const& proxy : proxy_settings->http_proxies) { + proxy_config.proxy_rules().proxies_for_http.AddProxyServer( + net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTP, + net::HostPortPair(proxy->host, proxy->port))); + } + for (auto const& proxy : proxy_settings->secure_http_proxies) { + proxy_config.proxy_rules().proxies_for_https.AddProxyServer( + net::ProxyServer(net::ProxyServer::Scheme::SCHEME_HTTPS, + net::HostPortPair(proxy->host, proxy->port))); + } + for (auto const& proxy : proxy_settings->socks_proxies) { + // See `net::ProxyServer::GetSchemeFromPacTypeInternal()`. + proxy_config.proxy_rules().fallback_proxies.AddProxyServer( + net::ProxyServer(net::ProxyServer::Scheme::SCHEME_SOCKS4, + net::HostPortPair(proxy->host, proxy->port))); + } + + for (const auto& domains : proxy_settings->exclude_domains) { + proxy_config.proxy_rules().bypass_rules.AddRuleFromString(domains); + } + return net::ProxyConfigWithAnnotation(proxy_config, + kAshProxyConfigTrafficAnnotation); +} + +} // namespace + +namespace chromeos { + +net::ProxyConfigWithAnnotation CrosapiProxyToNetProxy( + crosapi::mojom::ProxyConfigPtr crosapi_proxy) { + if (!crosapi_proxy) + return net::ProxyConfigWithAnnotation::CreateDirect(); + + if (crosapi_proxy->proxy_settings->is_direct()) + return net::ProxyConfigWithAnnotation::CreateDirect(); + + if (crosapi_proxy->proxy_settings->is_pac()) + return TranslatePacProxySettings( + std::move(crosapi_proxy->proxy_settings->get_pac())); + + if (crosapi_proxy->proxy_settings->is_wpad()) + return TranslateWpadProxySettings( + std::move(crosapi_proxy->proxy_settings->get_wpad())); + + if (crosapi_proxy->proxy_settings->is_manual()) + return TranslateManualProxySettings( + std::move(crosapi_proxy->proxy_settings->get_manual())); + + return net::ProxyConfigWithAnnotation::CreateDirect(); +} + +} // namespace chromeos
diff --git a/chrome/browser/lacros/net/network_settings_translation_net_proxy.cc b/chrome/browser/lacros/net/network_settings_translation_net_proxy.cc new file mode 100644 index 0000000..db3da75 --- /dev/null +++ b/chrome/browser/lacros/net/network_settings_translation_net_proxy.cc
@@ -0,0 +1,103 @@ +// 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/lacros/net/network_settings_translation.h" + +#include "base/strings/string_split.h" +#include "components/proxy_config/proxy_config_dictionary.h" +#include "components/proxy_config/proxy_config_pref_names.h" +#include "components/proxy_config/proxy_prefs.h" +#include "net/base/host_port_pair.h" +#include "net/base/proxy_server.h" +#include "net/proxy_resolution/proxy_config.h" +#include "net/proxy_resolution/proxy_list.h" +#include "net/traffic_annotation/network_traffic_annotation.h" + +namespace { + +std::vector<crosapi::mojom::ProxyLocationPtr> TranslateProxyLocations( + const net::ProxyList& proxy_list) { + std::vector<net::ProxyServer> proxies = proxy_list.GetAll(); + std::vector<crosapi::mojom::ProxyLocationPtr> ptr_list; + crosapi::mojom::ProxyLocationPtr ptr; + for (const auto& proxy : proxies) { + ptr = crosapi::mojom::ProxyLocation::New(); + ptr->host = proxy.host_port_pair().host(); + ptr->port = proxy.host_port_pair().port(); + ptr_list.push_back(std::move(ptr)); + } + return ptr_list; +} + +crosapi::mojom::ProxySettingsManualPtr TranslateManualProxySettings( + const net::ProxyConfig::ProxyRules& rules) { + crosapi::mojom::ProxySettingsManualPtr ptr = + crosapi::mojom::ProxySettingsManual::New(); + switch (rules.type) { + case net::ProxyConfig::ProxyRules::Type::EMPTY: + return nullptr; + case net::ProxyConfig::ProxyRules::Type::PROXY_LIST: + ptr->http_proxies = TranslateProxyLocations(rules.single_proxies); + ptr->secure_http_proxies = TranslateProxyLocations(rules.single_proxies); + ptr->socks_proxies = TranslateProxyLocations(rules.single_proxies); + break; + case net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME: + ptr->http_proxies = TranslateProxyLocations(rules.proxies_for_http); + ptr->secure_http_proxies = + TranslateProxyLocations(rules.proxies_for_https); + ptr->socks_proxies = TranslateProxyLocations(rules.fallback_proxies); + break; + } + + for (const auto& domain : rules.bypass_rules.rules()) { + ptr->exclude_domains.push_back(domain->ToString()); + } + return ptr; +} + +crosapi::mojom::ProxySettingsPtr NetProxyToProxySettings( + const net::ProxyConfigWithAnnotation& net_proxy) { + net::ProxyConfig proxy_config = net_proxy.value(); + auto proxy_settings = crosapi::mojom::ProxySettings::New(); + if (proxy_config.proxy_rules().empty() && + !proxy_config.HasAutomaticSettings()) { + proxy_settings->set_direct(crosapi::mojom::ProxySettingsDirect::New()); + return proxy_settings; + } + + if (proxy_config.has_pac_url()) { + auto pac = crosapi::mojom::ProxySettingsPac::New(); + pac->pac_url = proxy_config.pac_url(); + pac->pac_mandatory = proxy_config.pac_mandatory(); + proxy_settings->set_pac(std::move(pac)); + return proxy_settings; + } + + if (proxy_config.auto_detect()) { + proxy_settings->set_wpad(crosapi::mojom::ProxySettingsWpad::New()); + return proxy_settings; + } + + crosapi::mojom::ProxySettingsManualPtr manual = + TranslateManualProxySettings(proxy_config.proxy_rules()); + if (!manual) { + proxy_settings->set_direct(crosapi::mojom::ProxySettingsDirect::New()); + return proxy_settings; + } + proxy_settings->set_manual(std::move(manual)); + return proxy_settings; +} + +} // namespace + +namespace chromeos { + +crosapi::mojom::ProxyConfigPtr NetProxyToCrosapiProxy( + const net::ProxyConfigWithAnnotation& net_proxy) { + auto proxy_config = crosapi::mojom::ProxyConfig::New(); + proxy_config->proxy_settings = NetProxyToProxySettings(net_proxy); + return proxy_config; +} + +} // namespace chromeos
diff --git a/chrome/browser/lacros/net/network_settings_translation_unittest.cc b/chrome/browser/lacros/net/network_settings_translation_unittest.cc new file mode 100644 index 0000000..aed511f --- /dev/null +++ b/chrome/browser/lacros/net/network_settings_translation_unittest.cc
@@ -0,0 +1,202 @@ +// 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/lacros/net/network_settings_translation.h" + +#include "chromeos/crosapi/mojom/network_settings_service.mojom.h" +#include "components/proxy_config/pref_proxy_config_tracker_impl.h" +#include "components/proxy_config/proxy_config_dictionary.h" +#include "net/base/proxy_server.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +constexpr char kPacUrl[] = "http://pac.pac/"; + +} // namespace + +namespace chromeos { + +TEST(NetworkSettingsTranslationTest, NetProxyToCrosapiProxyDirect) { + crosapi::mojom::ProxyConfigPtr actual = + NetProxyToCrosapiProxy(net::ProxyConfigWithAnnotation::CreateDirect()); + EXPECT_TRUE(actual->proxy_settings->is_direct()); +} + +TEST(NetworkSettingsTranslationTest, NetProxyToCrosapiProxyWpad) { + crosapi::mojom::ProxyConfigPtr actual = + NetProxyToCrosapiProxy(net::ProxyConfigWithAnnotation( + net::ProxyConfig::CreateAutoDetect(), TRAFFIC_ANNOTATION_FOR_TESTS)); + EXPECT_TRUE(actual->proxy_settings->is_wpad()); +} + +TEST(NetworkSettingsTranslationTest, NetProxyToCrosapiProxyPacNotMandatory) { + net::ProxyConfig config = + net::ProxyConfig::CreateFromCustomPacURL(GURL(kPacUrl)); + + crosapi::mojom::ProxyConfigPtr actual = NetProxyToCrosapiProxy( + net::ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS)); + ASSERT_TRUE(actual->proxy_settings->is_pac()); + EXPECT_EQ(actual->proxy_settings->get_pac()->pac_url, GURL(kPacUrl)); + EXPECT_EQ(actual->proxy_settings->get_pac()->pac_mandatory, false); +} + +TEST(NetworkSettingsTranslationTest, NetProxyToCrosapiProxyPacMandatory) { + net::ProxyConfig config = + net::ProxyConfig::CreateFromCustomPacURL(GURL(kPacUrl)); + config.set_pac_mandatory(true); + + crosapi::mojom::ProxyConfigPtr actual = NetProxyToCrosapiProxy( + net::ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS)); + ASSERT_TRUE(actual->proxy_settings->is_pac()); + EXPECT_EQ(actual->proxy_settings->get_pac()->pac_url, GURL(kPacUrl)); + EXPECT_EQ(actual->proxy_settings->get_pac()->pac_mandatory, true); +} + +TEST(NetworkSettingsTranslationTest, NetProxyToCrosapiProxyManual) { + net::ProxyConfig config; + config.proxy_rules().ParseFromString( + "http=proxy:80;https=secure_proxy:81;socks=socks_proxy:82;"); + config.proxy_rules().bypass_rules.ParseFromString("localhost;google.com;"); + + crosapi::mojom::ProxyConfigPtr actual = NetProxyToCrosapiProxy( + net::ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS)); + ASSERT_TRUE(actual->proxy_settings->is_manual()); + std::vector<crosapi::mojom::ProxyLocationPtr> proxy_ptr = + std::move(actual->proxy_settings->get_manual()->http_proxies); + ASSERT_EQ(proxy_ptr.size(), 1u); + EXPECT_EQ(proxy_ptr[0]->host, "proxy"); + EXPECT_EQ(proxy_ptr[0]->port, 80); + + proxy_ptr = + std::move(actual->proxy_settings->get_manual()->secure_http_proxies); + ASSERT_EQ(proxy_ptr.size(), 1u); + EXPECT_EQ(proxy_ptr[0]->host, "secure_proxy"); + EXPECT_EQ(proxy_ptr[0]->port, 81); + + proxy_ptr = std::move(actual->proxy_settings->get_manual()->socks_proxies); + ASSERT_EQ(proxy_ptr.size(), 1u); + EXPECT_EQ(proxy_ptr[0]->host, "socks_proxy"); + EXPECT_EQ(proxy_ptr[0]->port, 82); + + const std::vector<std::string> exclude_domains = + actual->proxy_settings->get_manual()->exclude_domains; + ASSERT_EQ(exclude_domains.size(), 2u); + EXPECT_EQ(exclude_domains[0], "localhost"); + EXPECT_EQ(exclude_domains[1], "google.com"); +} + +TEST(NetworkSettingsTranslationTest, + NetProxyToCrosapiProxyManualFromSingleProxies) { + net::ProxyConfig config; + config.proxy_rules().ParseFromString("proxy:80;"); + + crosapi::mojom::ProxyConfigPtr actual = NetProxyToCrosapiProxy( + net::ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS)); + ASSERT_TRUE(actual->proxy_settings->is_manual()); + std::vector<crosapi::mojom::ProxyLocationPtr> proxy_ptr = + std::move(actual->proxy_settings->get_manual()->http_proxies); + ASSERT_EQ(proxy_ptr.size(), 1u); + EXPECT_EQ(proxy_ptr[0]->host, "proxy"); + EXPECT_EQ(proxy_ptr[0]->port, 80); + + proxy_ptr = + std::move(actual->proxy_settings->get_manual()->secure_http_proxies); + ASSERT_EQ(proxy_ptr.size(), 1u); + EXPECT_EQ(proxy_ptr[0]->host, "proxy"); + EXPECT_EQ(proxy_ptr[0]->port, 80); + + proxy_ptr = std::move(actual->proxy_settings->get_manual()->socks_proxies); + ASSERT_EQ(proxy_ptr.size(), 1u); + EXPECT_EQ(proxy_ptr[0]->host, "proxy"); + EXPECT_EQ(proxy_ptr[0]->port, 80); +} + +TEST(NetworkSettingsTranslationTest, NetProxyToCrosapiProxyManualEmptyList) { + net::ProxyConfig config; + config.proxy_rules().ParseFromString(""); + crosapi::mojom::ProxyConfigPtr actual = NetProxyToCrosapiProxy( + net::ProxyConfigWithAnnotation(config, TRAFFIC_ANNOTATION_FOR_TESTS)); + EXPECT_TRUE(actual->proxy_settings->is_direct()); +} + +TEST(NetworkSettingsTranslationTest, CrosapiProxyToNetProxyDirect) { + crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New(); + crosapi::mojom::ProxySettingsPtr proxy = crosapi::mojom::ProxySettings::New(); + crosapi::mojom::ProxySettingsDirectPtr direct = + crosapi::mojom::ProxySettingsDirect::New(); + proxy->set_direct(std::move(direct)); + ptr->proxy_settings = std::move(proxy); + + EXPECT_EQ(CrosapiProxyToNetProxy(std::move(ptr)).value().ToValue(), + net::ProxyConfig::CreateDirect().ToValue()); +} + +TEST(NetworkSettingsTranslationTest, CrosapiProxyToNetProxyWpad) { + crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New(); + crosapi::mojom::ProxySettingsPtr proxy = crosapi::mojom::ProxySettings::New(); + crosapi::mojom::ProxySettingsWpadPtr wpad = + crosapi::mojom::ProxySettingsWpad::New(); + proxy->set_wpad(std::move(wpad)); + ptr->proxy_settings = std::move(proxy); + + auto actual = CrosapiProxyToNetProxy(std::move(ptr)); + EXPECT_TRUE(actual.value().auto_detect()); +} + +TEST(NetworkSettingsTranslationTest, CrosapiProxyToNetProxyPac) { + crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New(); + crosapi::mojom::ProxySettingsPtr proxy = crosapi::mojom::ProxySettings::New(); + crosapi::mojom::ProxySettingsPacPtr pac = + crosapi::mojom::ProxySettingsPac::New(); + pac->pac_url = GURL(kPacUrl); + pac->pac_mandatory = true; + proxy->set_pac(pac.Clone()); + ptr->proxy_settings = proxy.Clone(); + auto actual = CrosapiProxyToNetProxy(ptr.Clone()); + EXPECT_FALSE(actual.value().auto_detect()); + EXPECT_EQ(actual.value().pac_url(), GURL(kPacUrl)); + EXPECT_TRUE(actual.value().pac_mandatory()); + + pac->pac_mandatory = false; + proxy->set_pac(std::move(pac)); + ptr->proxy_settings = std::move(proxy); + actual = CrosapiProxyToNetProxy(std::move(ptr)); + EXPECT_FALSE(actual.value().pac_mandatory()); +} + +TEST(NetworkSettingsTranslationTest, CrosapiProxyToNetProxyManual) { + crosapi::mojom::ProxyConfigPtr ptr = crosapi::mojom::ProxyConfig::New(); + crosapi::mojom::ProxySettingsPtr proxy = crosapi::mojom::ProxySettings::New(); + crosapi::mojom::ProxySettingsManualPtr manual = + crosapi::mojom::ProxySettingsManual::New(); + crosapi::mojom::ProxyLocationPtr location = + crosapi::mojom::ProxyLocation::New(); + location->host = "proxy"; + location->port = 80; + manual->http_proxies.push_back(location.Clone()); + location->host = "secure_proxy"; + location->port = 81; + manual->secure_http_proxies.push_back(location.Clone()); + location->host = "socks_proxy"; + location->port = 82; + manual->socks_proxies.push_back(std::move(location)); + manual->exclude_domains = {"localhost", "google.com"}; + proxy->set_manual(std::move(manual)); + ptr->proxy_settings = std::move(proxy); + + auto actual = CrosapiProxyToNetProxy(std::move(ptr)); + + EXPECT_EQ(actual.value().proxy_rules().proxies_for_http.ToPacString(), + "PROXY proxy:80"); + EXPECT_EQ(actual.value().proxy_rules().proxies_for_https.ToPacString(), + "HTTPS secure_proxy:81"); + EXPECT_EQ(actual.value().proxy_rules().fallback_proxies.ToPacString(), + "SOCKS socks_proxy:82"); + EXPECT_EQ(actual.value().proxy_rules().bypass_rules.ToString(), + "localhost;google.com;"); +} + +} // namespace chromeos
diff --git a/chrome/browser/lacros/net/proxy_config_service_lacros.cc b/chrome/browser/lacros/net/proxy_config_service_lacros.cc new file mode 100644 index 0000000..fc3b156 --- /dev/null +++ b/chrome/browser/lacros/net/proxy_config_service_lacros.cc
@@ -0,0 +1,115 @@ +// 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/lacros/net/proxy_config_service_lacros.h" + +#include <memory> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/callback_helpers.h" +#include "base/logging.h" +#include "base/values.h" +#include "chrome/browser/lacros/net/network_settings_translation.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/pref_names.h" +#include "chromeos/lacros/lacros_service.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "net/proxy_resolution/proxy_config.h" +#include "net/proxy_resolution/proxy_config_with_annotation.h" + +namespace { + +net::ProxyConfigWithAnnotation GetConfigOrDirect( + const absl::optional<net::ProxyConfigWithAnnotation>& optional_config, + PrefService* pref_service) { + if (!optional_config || !pref_service || + !pref_service->GetBoolean(prefs::kUseAshProxy)) { + net::ProxyConfigWithAnnotation config = + net::ProxyConfigWithAnnotation::CreateDirect(); + return config; + } + return optional_config.value(); +} +} // namespace + +namespace chromeos { + +ProxyConfigServiceLacros::ProxyConfigServiceLacros(Profile* profile) { + DCHECK(profile); + auto* lacros_service = chromeos::LacrosService::Get(); + // crosapi is disabled in browser_tests. + if (!lacros_service->IsAvailable<crosapi::mojom::NetworkSettingsService>()) { + LOG(ERROR) << "The NetworkSettingsService service is not available"; + return; + } + lacros_service->GetRemote<crosapi::mojom::NetworkSettingsService>() + ->AddNetworkSettingsObserver(receiver_.BindNewPipeAndPassRemote()); + + // `kUseAshProxy` is a user exposed setting whether to use the ash proxy (from + // the system) or whether to use profile specific proxy settings. This option + // is only given for secondary profiles. For the primary profile, the user has + // to use the system proxy settings, the value of kUseAshProxy is always true, + // and the setting is not exposed to the user. + // TODO(acostinas, b:192915915) Enable secondary profiles to configure + // `kUseAshProxy` from chrome://settings. + if (profile->IsMainProfile()) { + profile->GetPrefs()->SetBoolean(prefs::kUseAshProxy, true); + } + + profile_prefs_ = profile->GetPrefs(); + profile_pref_change_registrar_.Init(profile_prefs_); + profile_pref_change_registrar_.Add( + prefs::kUseAshProxy, + base::BindRepeating(&ProxyConfigServiceLacros::OnUseAshProxyPrefChanged, + base::Unretained(this))); +} + +ProxyConfigServiceLacros::~ProxyConfigServiceLacros() = default; + +void ProxyConfigServiceLacros::OnProxyChanged( + crosapi::mojom::ProxyConfigPtr proxy_config) { + cached_config_ = CrosapiProxyToNetProxy(std::move(proxy_config)); + NotifyObservers(); +} + +void ProxyConfigServiceLacros::OnUseAshProxyPrefChanged() { + NotifyObservers(); +} + +void ProxyConfigServiceLacros::NotifyObservers() { + for (auto& observer : observers_) { + observer.OnProxyConfigChanged( + GetConfigOrDirect(cached_config_, profile_prefs_), + ConfigAvailability::CONFIG_VALID); + } +} + +void ProxyConfigServiceLacros::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void ProxyConfigServiceLacros::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +// static +void ProxyConfigServiceLacros::RegisterProfilePrefs( + PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kUseAshProxy, false); +} + +net::ProxyConfigService::ConfigAvailability +ProxyConfigServiceLacros::GetLatestProxyConfig( + net::ProxyConfigWithAnnotation* config) { + // Returns the last proxy configuration that the Ash + // NetworkSettingsService notified us, or the direct proxy if `cached_config_` + // is not set. + *config = GetConfigOrDirect(cached_config_, profile_prefs_); + return ConfigAvailability::CONFIG_VALID; +} + +} // namespace chromeos
diff --git a/chrome/browser/lacros/net/proxy_config_service_lacros.h b/chrome/browser/lacros/net/proxy_config_service_lacros.h new file mode 100644 index 0000000..84697bc --- /dev/null +++ b/chrome/browser/lacros/net/proxy_config_service_lacros.h
@@ -0,0 +1,71 @@ +// 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_LACROS_NET_PROXY_CONFIG_SERVICE_LACROS_H_ +#define CHROME_BROWSER_LACROS_NET_PROXY_CONFIG_SERVICE_LACROS_H_ + +#include "base/observer_list.h" +#include "chromeos/crosapi/mojom/network_settings_service.mojom.h" +#include "components/prefs/pref_change_registrar.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "net/proxy_resolution/proxy_config_service.h" +#include "net/proxy_resolution/proxy_config_with_annotation.h" + +class PrefRegistrySimple; +class PrefService; +class Profile; + +namespace chromeos { + +// Implementation of ProxyConfigService that retrieves the system proxy +// settings from Ash-Chrome via the mojo API. Unlike other +// net::ProxyConfigService implementations used as base service, this class will +// only forward the system proxy retrieved from Ash-Chrome if allowed by pref +// kUseAshProxy. +class ProxyConfigServiceLacros + : public net::ProxyConfigService, + public crosapi::mojom::NetworkSettingsObserver { + public: + explicit ProxyConfigServiceLacros(Profile* profile); + + ProxyConfigServiceLacros(const ProxyConfigServiceLacros&) = delete; + ProxyConfigServiceLacros& operator=(const ProxyConfigServiceLacros&) = delete; + ~ProxyConfigServiceLacros() override; + + // net::ProxyConfigService impl + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + ProxyConfigService::ConfigAvailability GetLatestProxyConfig( + net::ProxyConfigWithAnnotation* config) override; + + static void RegisterProfilePrefs(PrefRegistrySimple* registry); + + private: + // crosapi::mojom::NetworkSettingsObserver impl + void OnProxyChanged(crosapi::mojom::ProxyConfigPtr proxy_config) override; + + void OnUseAshProxyPrefChanged(); + + void NotifyObservers(); + + // Owned by the Profile instance. + PrefService* profile_prefs_ = nullptr; + + PrefChangeRegistrar profile_pref_change_registrar_; + + // TODO(acostinas, b/200001678): Use checked observers. + base::ObserverList<net::ProxyConfigService::Observer>::Unchecked observers_; + // Receives mojo messages from Ash-Chrome. + mojo::Receiver<crosapi::mojom::NetworkSettingsObserver> receiver_{this}; + // The latest proxy configuration sent by Ash-Chrome via mojo. This proxy is + // enforced in the browser only if the pref kUseAshProxy=true and the + // kProxy pref, which has precedence, is unset or set to mode=system. + absl::optional<net::ProxyConfigWithAnnotation> cached_config_; + + base::WeakPtrFactory<ProxyConfigServiceLacros> weak_ptr_factory_{this}; +}; + +} // namespace chromeos + +#endif // CHROME_BROWSER_LACROS_NET_PROXY_CONFIG_SERVICE_LACROS_H_
diff --git a/chrome/browser/lacros/net/proxy_config_service_lacros_browsertest.cc b/chrome/browser/lacros/net/proxy_config_service_lacros_browsertest.cc new file mode 100644 index 0000000..1c55e15 --- /dev/null +++ b/chrome/browser/lacros/net/proxy_config_service_lacros_browsertest.cc
@@ -0,0 +1,297 @@ +// 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/lacros/net/proxy_config_service_lacros.h" + +#include "base/time/time.h" +#include "chrome/browser/lacros/net/network_settings_translation.h" +#include "chrome/browser/net/proxy_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/crosapi/mojom/network_settings_service.mojom.h" +#include "chromeos/lacros/lacros_service.h" +#include "components/prefs/pref_service.h" +#include "components/proxy_config/pref_proxy_config_tracker_impl.h" +#include "components/proxy_config/proxy_config_dictionary.h" +#include "components/proxy_config/proxy_config_pref_names.h" +#include "components/proxy_config/proxy_prefs.h" +#include "content/public/test/browser_test.h" +#include "mojo/public/cpp/bindings/receiver_set.h" +#include "net/proxy_resolution/proxy_config_service.h" + +namespace { + +constexpr char kPacUrl[] = "pac.pac"; + +// Fakes the NetworkSettingsService in Ash-Chrome so we can send proxy updates +// from the tests via the mojo API. +class FakeNetworkSettingsService + : public crosapi::mojom::NetworkSettingsService { + public: + FakeNetworkSettingsService() = default; + FakeNetworkSettingsService(const FakeNetworkSettingsService&) = delete; + FakeNetworkSettingsService& operator=(const FakeNetworkSettingsService&) = + delete; + ~FakeNetworkSettingsService() override = default; + + bool HasObserver() { return observer_.is_bound(); } + + // crosapi::mojom::AshNetworService: + void AddNetworkSettingsObserver( + mojo::PendingRemote<crosapi::mojom::NetworkSettingsObserver> observer) + override { + observer_ = mojo::Remote<crosapi::mojom::NetworkSettingsObserver>( + std::move(observer)); + if (quit_closure_) { + std::move(quit_closure_).Run(); + } + } + + void SetQuitClosure(base::OnceClosure quit_closure) { + quit_closure_ = std::move(quit_closure); + } + + void SendProxyUpdate(crosapi::mojom::ProxyConfigPtr proxy_config) { + if (observer_) { + observer_->OnProxyChanged(std::move(proxy_config)); + } + } + + private: + mojo::Remote<crosapi::mojom::NetworkSettingsObserver> observer_; + base::OnceClosure quit_closure_; +}; + +// Fakes the ProxyConfigMonitor which is the class that sends the proxy updates +// to the Browser's NetworkService process via mojo. +class FakeProxyMonitor : public net::ProxyConfigService::Observer { + public: + FakeProxyMonitor() = default; + FakeProxyMonitor(const FakeProxyMonitor&) = delete; + FakeProxyMonitor& operator=(const FakeProxyMonitor&) = delete; + ~FakeProxyMonitor() override = default; + + void OnProxyConfigChanged( + const net::ProxyConfigWithAnnotation& config, + net::ProxyConfigService::ConfigAvailability availability) override { + cached_proxy_config_ = std::move(config); + if (quit_closure_) { + std::move(quit_closure_).Run(); + } + } + + void SetQuitClosure(base::OnceClosure quit_closure) { + quit_closure_ = std::move(quit_closure); + } + net::ProxyConfigWithAnnotation cached_proxy_config_; + + private: + base::OnceClosure quit_closure_; +}; + +} // namespace + +namespace chromeos { + +class ProxyConfigServiceLacrosTest : public InProcessBrowserTest { + protected: + ProxyConfigServiceLacrosTest() = default; + + ProxyConfigServiceLacrosTest(const ProxyConfigServiceLacrosTest&) = delete; + ProxyConfigServiceLacrosTest& operator=(const ProxyConfigServiceLacrosTest&) = + delete; + ~ProxyConfigServiceLacrosTest() override = default; + mojo::Remote<crosapi::mojom::NetworkSettingsService> + network_settings_service_; + + bool IsServiceAvailable() { + auto* lacros_service = chromeos::LacrosService::Get(); + if (!lacros_service) + return false; + return lacros_service + ->IsAvailable<crosapi::mojom::NetworkSettingsService>(); + } + + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + // If the lacros service or the network settings service interface are not + // available on this version of ash-chrome, this test suite will no-op. + if (!IsServiceAvailable()) + return; + // Replace the production network settings service with a fake for testing. + mojo::Remote<crosapi::mojom::NetworkSettingsService>& remote = + chromeos::LacrosService::Get() + ->GetRemote<crosapi::mojom::NetworkSettingsService>(); + remote.reset(); + receiver_.Bind(remote.BindNewPipeAndPassReceiver()); + + pref_proxy_config_tracker_ = + ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile( + browser()->profile()->GetPrefs(), nullptr); + + base::RunLoop run_loop; + service_.SetQuitClosure(run_loop.QuitClosure()); + proxy_config_service_ = ProxyServiceFactory::CreateProxyConfigService( + pref_proxy_config_tracker_.get(), browser()->profile()); + // Wait for the mojom::NetworkSettingsObserver created by + // `proxy_config_service_` in Lacros to be added as an observer to the + // AshNetworkSettingsService in Ash-Chrome. + run_loop.Run(); + + proxy_monitor_ = std::make_unique<FakeProxyMonitor>(); + proxy_config_service_->AddObserver(proxy_monitor_.get()); + } + + void TearDownOnMainThread() override { + proxy_config_service_->RemoveObserver(proxy_monitor_.get()); + pref_proxy_config_tracker_->DetachFromPrefService(); + pref_proxy_config_tracker_.reset(); + proxy_config_service_.reset(); + proxy_monitor_.reset(); + base::RunLoop().RunUntilIdle(); + } + + protected: + // Sends a proxy update via the AshNetworkSettingService in Ash-Chrome and + // waits for `proxy_monitor_` in Lacros-Chrome to receive the config. + void SendAshProxyUpdateAndWait(crosapi::mojom::ProxyConfigPtr proxy_config) { + base::RunLoop run_loop; + proxy_monitor_->SetQuitClosure(run_loop.QuitClosure()); + service_.SendProxyUpdate(std::move(proxy_config)); + run_loop.Run(); + } + + std::unique_ptr<net::ProxyConfigService> proxy_config_service_; + // Monitors global and profile prefs related to proxy configuration. + std::unique_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; + // Fakes the ProxyConfigMonitor which directly updates the Browser's + // NetworkService process. + std::unique_ptr<FakeProxyMonitor> proxy_monitor_; + FakeNetworkSettingsService service_; + mojo::Receiver<crosapi::mojom::NetworkSettingsService> receiver_{&service_}; +}; + +// Tests that the chromeos::ProxyConfigServiceLacros instance internally created +// by `proxy_config_service_` is added to Ash-Chrome as an observer for network +// changes. +IN_PROC_BROWSER_TEST_F(ProxyConfigServiceLacrosTest, ObserverSet) { + if (!IsServiceAvailable()) + return; + ASSERT_TRUE(service_.HasObserver()); +} + +// Tests that proxy updates from the AshNetworkService in Ash-Chrome are +// correctly propagated to observers of the `proxy_config_service_` in +// Lacros-Chrome. +IN_PROC_BROWSER_TEST_F(ProxyConfigServiceLacrosTest, ProxyUpdates) { + if (!IsServiceAvailable()) + return; + + crosapi::mojom::ProxyConfigPtr proxy_config = + crosapi::mojom::ProxyConfig::New(); + proxy_config->proxy_settings = crosapi::mojom::ProxySettings::New(); + + proxy_config->proxy_settings->set_direct( + crosapi::mojom::ProxySettingsDirect::New()); + SendAshProxyUpdateAndWait(proxy_config.Clone()); + EXPECT_EQ(proxy_monitor_->cached_proxy_config_.value().ToValue(), + net::ProxyConfig::CreateDirect().ToValue()); + + crosapi::mojom::ProxySettingsWpadPtr wpad = + crosapi::mojom::ProxySettingsWpad::New(); + wpad->pac_url = GURL(kPacUrl); + proxy_config->proxy_settings->set_wpad( + crosapi::mojom::ProxySettingsWpad::New()); + SendAshProxyUpdateAndWait(proxy_config.Clone()); + EXPECT_EQ(proxy_monitor_->cached_proxy_config_.value().ToValue(), + CrosapiProxyToNetProxy(proxy_config.Clone()).value().ToValue()); + + crosapi::mojom::ProxySettingsManualPtr manual = + crosapi::mojom::ProxySettingsManual::New(); + crosapi::mojom::ProxyLocationPtr location = + crosapi::mojom::ProxyLocation::New(); + location->host = "proxy"; + location->port = 80; + manual->secure_http_proxies.push_back(location.Clone()); + manual->socks_proxies.push_back(location.Clone()); + proxy_config->proxy_settings->set_manual(std::move(manual)); + SendAshProxyUpdateAndWait(proxy_config.Clone()); + EXPECT_EQ(proxy_monitor_->cached_proxy_config_.value().ToValue(), + CrosapiProxyToNetProxy(std::move(proxy_config)).value().ToValue()); +} + +// Tests that proxies set via the user pref `kProxy` have precedence over system +// proxies coming from Ash-Chrome. +IN_PROC_BROWSER_TEST_F(ProxyConfigServiceLacrosTest, UserPrefPrecedence) { + if (!IsServiceAvailable()) + return; + // Set a proxy via pref. + base::RunLoop run_loop; + proxy_monitor_->SetQuitClosure(run_loop.QuitClosure()); + base::Value proxy_config_wpad(base::Value::Type::DICTIONARY); + proxy_config_wpad.SetKey("mode", + base::Value(ProxyPrefs::kAutoDetectProxyModeName)); + browser()->profile()->GetPrefs()->Set(proxy_config::prefs::kProxy, + proxy_config_wpad); + run_loop.Run(); + // Verify that the pref proxy is applied. + EXPECT_EQ(proxy_monitor_->cached_proxy_config_.value().ToValue(), + net::ProxyConfig::CreateAutoDetect().ToValue()); + + // Set a system proxy via the AshNetworkSettingsService. + crosapi::mojom::ProxyConfigPtr proxy_config = + crosapi::mojom::ProxyConfig::New(); + proxy_config->proxy_settings = crosapi::mojom::ProxySettings::New(); + crosapi::mojom::ProxySettingsPacPtr pac = + crosapi::mojom::ProxySettingsPac::New(); + pac->pac_url = GURL(kPacUrl); + proxy_config->proxy_settings->set_pac(std::move(pac)); + service_.SendProxyUpdate(std::move(proxy_config)); + base::RunLoop().RunUntilIdle(); + + // Verify that the pref proxy is still applied. + EXPECT_EQ(proxy_monitor_->cached_proxy_config_.value().ToValue(), + net::ProxyConfig::CreateAutoDetect().ToValue()); + + // Remove the pref and verify that the system proxy is applied. + browser()->profile()->GetPrefs()->ClearPref(proxy_config::prefs::kProxy); + EXPECT_EQ(proxy_monitor_->cached_proxy_config_.value().ToValue(), + CrosapiProxyToNetProxy(std::move(proxy_config)).value().ToValue()); +} + +// Test that verifies that the system proxy sent from Ash-Chrome is only applied +// if the pref `kUseAshProxy` is true. +IN_PROC_BROWSER_TEST_F(ProxyConfigServiceLacrosTest, UseAshProxyPref) { + if (!IsServiceAvailable()) + return; + browser()->profile()->GetPrefs()->SetBoolean(prefs::kUseAshProxy, false); + crosapi::mojom::ProxyConfigPtr proxy_config = + crosapi::mojom::ProxyConfig::New(); + proxy_config->proxy_settings = crosapi::mojom::ProxySettings::New(); + crosapi::mojom::ProxySettingsWpadPtr wpad = + crosapi::mojom::ProxySettingsWpad::New(); + wpad->pac_url = GURL(kPacUrl); + proxy_config->proxy_settings->set_wpad( + crosapi::mojom::ProxySettingsWpad::New()); + service_.SendProxyUpdate(proxy_config.Clone()); + base::RunLoop().RunUntilIdle(); + // Verify that the system proxy is not applied. + EXPECT_EQ(proxy_monitor_->cached_proxy_config_.value().ToValue(), + net::ProxyConfig::CreateDirect().ToValue()); + + browser()->profile()->GetPrefs()->SetBoolean(prefs::kUseAshProxy, true); + // Verify that the system proxy is applied. + EXPECT_EQ(proxy_monitor_->cached_proxy_config_.value().ToValue(), + CrosapiProxyToNetProxy(proxy_config.Clone()).value().ToValue()); + + // Verify that the system proxy is not applied. + browser()->profile()->GetPrefs()->SetBoolean(prefs::kUseAshProxy, false); + EXPECT_EQ(proxy_monitor_->cached_proxy_config_.value().ToValue(), + net::ProxyConfig::CreateDirect().ToValue()); +} + +} // namespace chromeos
diff --git a/chrome/browser/media/autoplay_metrics_browsertest.cc b/chrome/browser/media/autoplay_metrics_browsertest.cc index 54031a9..c715508 100644 --- a/chrome/browser/media/autoplay_metrics_browsertest.cc +++ b/chrome/browser/media/autoplay_metrics_browsertest.cc
@@ -56,11 +56,11 @@ } content::RenderFrameHost* first_child() const { - return web_contents()->GetAllFrames()[1]; + return ChildFrameAt(web_contents(), 0); } content::RenderFrameHost* second_child() const { - return web_contents()->GetAllFrames()[2]; + return ChildFrameAt(web_contents(), 1); } };
diff --git a/chrome/browser/media/unified_autoplay_browsertest.cc b/chrome/browser/media/unified_autoplay_browsertest.cc index b06abd5..18b2398 100644 --- a/chrome/browser/media/unified_autoplay_browsertest.cc +++ b/chrome/browser/media/unified_autoplay_browsertest.cc
@@ -458,11 +458,11 @@ } content::RenderFrameHost* main_frame() const { - return web_contents()->GetAllFrames()[0]; + return web_contents()->GetMainFrame(); } content::RenderFrameHost* first_child() const { - return web_contents()->GetAllFrames()[1]; + return ChildFrameAt(main_frame(), 0); } private:
diff --git a/chrome/browser/metrics/variations/variations_safe_mode_browsertest.cc b/chrome/browser/metrics/variations/variations_safe_mode_browsertest.cc index 8380434..1c7061d 100644 --- a/chrome/browser/metrics/variations/variations_safe_mode_browsertest.cc +++ b/chrome/browser/metrics/variations/variations_safe_mode_browsertest.cc
@@ -8,17 +8,34 @@ #include <string> +#include "base/base_switches.h" +#include "base/containers/contains.h" #include "base/metrics/field_trial.h" +#include "base/path_service.h" +#include "base/ranges/ranges.h" +#include "base/strings/strcat.h" +#include "base/test/launcher/test_launcher.h" #include "base/test/metrics/histogram_tester.h" +#include "base/test/task_environment.h" +#include "base/test/test_switches.h" #include "chrome/browser/browser_process.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "components/metrics/clean_exit_beacon.h" #include "components/metrics/metrics_pref_names.h" +#include "components/metrics/metrics_service.h" +#include "components/prefs/json_pref_store.h" #include "components/prefs/pref_service.h" +#include "components/prefs/pref_service_factory.h" #include "components/variations/metrics.h" #include "components/variations/pref_names.h" #include "components/variations/service/variations_field_trial_creator.h" +#include "components/variations/service/variations_safe_mode_constants.h" +#include "components/variations/service/variations_service.h" +#include "components/variations/variations_switches.h" #include "components/variations/variations_test_utils.h" +#include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" #include "testing/gtest/include/gtest/gtest.h" @@ -94,7 +111,7 @@ SeedUsage::kSafeSeedUsed, 1); // Verify that there is a field trial associated with the sole test seed - // study, |kTestSeedStudyName|. + // study, |variations::kTestSeedStudyName|. EXPECT_TRUE(base::FieldTrialList::TrialExists(kTestSeedStudyName)); } @@ -151,4 +168,176 @@ SeedUsage::kRegularSeedUsed, 1); } +// This test code is programmatically launched by the SafeModeEndToEnd +// test below. Its primary purpose is to provide an entry-point by +// which the SafeModeEndToEnd test can cause the Field Trial Setup +// code to be exercised. For some launches, the setup code is expected +// to crash before reaching the test body; the test body simply verifies +// that the test is using the user-data-dir configured on the command-line. +// +// The MANUAL_ prefix prevents the test from running unless explicitly +// invoked. +IN_PROC_BROWSER_TEST_F(VariationsSafeModeBrowserTest, MANUAL_SubTest) { + // Validate that Chrome is running with the user-data-dir specified on the + // command-line. + base::FilePath expected_user_data_dir = + base::CommandLine::ForCurrentProcess()->GetSwitchValuePath( + ::switches::kUserDataDir); + base::FilePath actual_user_data_dir; + ASSERT_TRUE( + base::PathService::Get(chrome::DIR_USER_DATA, &actual_user_data_dir)); + ASSERT_FALSE(expected_user_data_dir.empty()); + ASSERT_FALSE(actual_user_data_dir.empty()); + ASSERT_EQ(actual_user_data_dir, expected_user_data_dir); +} + +namespace { + +class FieldTrialTest : public ::testing::TestWithParam<std::string> { + public: + void SetUp() override { + ::testing::TestWithParam<std::string>::SetUp(); + metrics::CleanExitBeacon::SkipCleanShutdownStepsForTesting(); + + pref_registry_ = base::MakeRefCounted<PrefRegistrySimple>(); + metrics::MetricsService::RegisterPrefs(pref_registry_.get()); + variations::VariationsService::RegisterPrefs(pref_registry_.get()); + + base::ScopedAllowBlockingForTesting allow_blocking; + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + user_data_dir_ = temp_dir_.GetPath().AppendASCII("user-data-dir"); + pref_service_factory_.set_user_prefs(base::MakeRefCounted<JsonPrefStore>( + user_data_dir_.AppendASCII("Local State"))); + } + + protected: + const std::string& field_trial_group() const { return GetParam(); } + const base::FilePath& user_data_dir() const { return user_data_dir_; } + + bool IsSuccessfulSubTestOutput(const std::string& output) { + static const char* const kSubTestSuccessStrings[] = { + "Running 1 test from 1 test suite", + "OK ] VariationsSafeModeBrowserTest.MANUAL_SubTest", + "1 test from VariationsSafeModeBrowserTest", + "1 test from 1 test suite ran", + }; + auto is_in_output = [&](const char* s) { + return base::Contains(output, s); + }; + return base::ranges::all_of(kSubTestSuccessStrings, is_in_output); + } + + bool IsCrashingSubTestOutput(const std::string& output) { + const char* const kSubTestCrashStrings[] = { + "Running 1 test from 1 test suite", + "VariationsSafeModeBrowserTest.MANUAL_SubTest", + "crash_for_testing", + }; + auto is_in_output = [&](const char* s) { + return base::Contains(output, s); + }; + return base::ranges::all_of(kSubTestCrashStrings, is_in_output); + } + + void RunAndExpectSuccessfulSubTest( + const base::CommandLine& sub_test_command) { + std::string output; + base::GetAppOutputAndError(sub_test_command, &output); + EXPECT_TRUE(IsSuccessfulSubTestOutput(output)) + << "Did not find success signals in output:\n" + << output; + } + + void RunAndExpectCrashingSubTest(const base::CommandLine& sub_test_command) { + std::string output; + base::GetAppOutputAndError(sub_test_command, &output); + EXPECT_FALSE(IsSuccessfulSubTestOutput(output)) + << "Expected crash but found success signals in output:\n" + << output; + EXPECT_TRUE(IsCrashingSubTestOutput(output)) + << "Did not find crash signals in output:\n" + << output; + } + + std::unique_ptr<PrefService> LoadLocalState() { + return pref_service_factory_.Create(pref_registry_); + } + + std::unique_ptr<metrics::CleanExitBeacon> LoadCleanExitBeacon( + PrefService* pref_service) { + static constexpr wchar_t kDummyWindowsRegistryKey[] = L""; + auto clean_exit_beacon = std::make_unique<metrics::CleanExitBeacon>( + kDummyWindowsRegistryKey, user_data_dir(), pref_service); + clean_exit_beacon->Initialize(); + return clean_exit_beacon; + } + + private: + base::test::TaskEnvironment task_environment_; + scoped_refptr<PrefRegistrySimple> pref_registry_; + PrefServiceFactory pref_service_factory_; + base::ScopedTempDir temp_dir_; + base::FilePath user_data_dir_; +}; + +} // namespace + +TEST_P(FieldTrialTest, ExtendedSafeModeEndToEnd) { + SCOPED_TRACE(field_trial_group()); + + // Reuse the browser_tests binary (i.e., that this test code is in), to + // manually run the sub-test. + base::CommandLine sub_test = + base::CommandLine(base::CommandLine::ForCurrentProcess()->GetProgram()); + + // Run the sub-test in the |user_data_dir()| allocated for the test case. + sub_test.AppendSwitchASCII(base::kGTestFilterFlag, + "VariationsSafeModeBrowserTest.MANUAL_SubTest"); + sub_test.AppendSwitch(::switches::kRunManualTestsFlag); + sub_test.AppendSwitch(::switches::kSingleProcessTests); + sub_test.AppendSwitchPath(::switches::kUserDataDir, user_data_dir()); + + // Select the extended variations safe mode field trial group. The "*" + // prefix forces the experiment/trial state to "active" at startup. + sub_test.AppendSwitchASCII(::switches::kForceFieldTrials, + base::StrCat({"*", kExtendedSafeModeTrial, "/", + field_trial_group(), "/"})); + + // Explicitly avoid any terminal control characters in the output. + sub_test.AppendSwitchASCII("gtest_color", "no"); + + // Initial sub-test run should be successful. + RunAndExpectSuccessfulSubTest(sub_test); + + // Add command-line switch to force crash during metric initialization. + // TODO(crbug/1249256): inject variations seed into user-data-dir that + // enables this feature instead of using altered command line. + base::CommandLine crashing_sub_test = sub_test; + crashing_sub_test.AppendSwitchASCII( + ::switches::kEnableFeatures, kForceFieldTrialSetupCrashForTesting.name); + + SetUpExtendedSafeModeExperiment(field_trial_group()); + + // The next three runs of the sub-test should crash... + for (int expected_crash_streak = 1; + expected_crash_streak <= kCrashStreakThreshold; + ++expected_crash_streak) { + RunAndExpectCrashingSubTest(crashing_sub_test); + auto local_state = LoadLocalState(); + auto clean_exit_beacon = LoadCleanExitBeacon(local_state.get()); + ASSERT_TRUE(clean_exit_beacon != nullptr); + ASSERT_FALSE(clean_exit_beacon->exited_cleanly()); + EXPECT_EQ(expected_crash_streak, + local_state->GetInteger(prefs::kVariationsCrashStreak)); + } + + // Until safe mode kicks in. + RunAndExpectSuccessfulSubTest(sub_test); +} + +INSTANTIATE_TEST_CASE_P( + VariationsSafeModeBrowserTest, + FieldTrialTest, + ::testing::Values(kSignalAndWriteSynchronouslyViaPrefServiceGroup, + kSignalAndWriteViaFileUtilGroup)); } // namespace variations
diff --git a/chrome/browser/net/proxy_config_monitor.cc b/chrome/browser/net/proxy_config_monitor.cc index 55cc762b..583ae4a36 100644 --- a/chrome/browser/net/proxy_config_monitor.cc +++ b/chrome/browser/net/proxy_config_monitor.cc
@@ -52,7 +52,7 @@ } proxy_config_service_ = ProxyServiceFactory::CreateProxyConfigService( - pref_proxy_config_tracker_.get()); + pref_proxy_config_tracker_.get(), profile); proxy_config_service_->AddObserver(this); } @@ -66,8 +66,7 @@ local_state); proxy_config_service_ = ProxyServiceFactory::CreateProxyConfigService( - pref_proxy_config_tracker_.get()); - + pref_proxy_config_tracker_.get(), nullptr); proxy_config_service_->AddObserver(this); }
diff --git a/chrome/browser/net/proxy_service_factory.cc b/chrome/browser/net/proxy_service_factory.cc index 9f6edc5..e340c32e 100644 --- a/chrome/browser/net/proxy_service_factory.cc +++ b/chrome/browser/net/proxy_service_factory.cc
@@ -20,11 +20,16 @@ #include "chromeos/network/proxy/proxy_config_service_impl.h" #endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/lacros/net/proxy_config_service_lacros.h" +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + using content::BrowserThread; // static std::unique_ptr<net::ProxyConfigService> -ProxyServiceFactory::CreateProxyConfigService(PrefProxyConfigTracker* tracker) { +ProxyServiceFactory::CreateProxyConfigService(PrefProxyConfigTracker* tracker, + Profile* profile) { // The linux gsettings-based proxy settings getter relies on being initialized // from the UI thread. The system proxy config service could also get created // without full browser process by launching service manager alone. @@ -33,8 +38,17 @@ std::unique_ptr<net::ProxyConfigService> base_service; -#if !BUILDFLAG(IS_CHROMEOS_ASH) - // On ChromeOS, base service is NULL; chromeos::ProxyConfigServiceImpl +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // The base service for Lacros observes proxy updates coming from Ash-Chrome + // via Mojo. Only created for `tracker` instances associated to a profile; + // for`tracker` instances associated to local_state the base_service is + // nullptr. + if (profile) { + base_service = + std::make_unique<chromeos::ProxyConfigServiceLacros>(profile); + } +#elif !BUILDFLAG(IS_CHROMEOS_ASH) + // On Ash-Chrome, base service is NULL; chromeos::ProxyConfigServiceImpl // determines the effective proxy config to take effect in the network layer, // be it from prefs or system (which is network shill on chromeos).
diff --git a/chrome/browser/net/proxy_service_factory.h b/chrome/browser/net/proxy_service_factory.h index 5f35c19e..82b26f2 100644 --- a/chrome/browser/net/proxy_service_factory.h +++ b/chrome/browser/net/proxy_service_factory.h
@@ -11,6 +11,7 @@ class PrefProxyConfigTracker; class PrefService; +class Profile; namespace net { class ProxyConfigService; @@ -19,9 +20,10 @@ class ProxyServiceFactory { public: // Creates a ProxyConfigService that delivers the system preferences - // (or the respective ChromeOS equivalent). + // (or the respective Ash-Chrome equivalent). static std::unique_ptr<net::ProxyConfigService> CreateProxyConfigService( - PrefProxyConfigTracker* tracker); + PrefProxyConfigTracker* tracker, + Profile* profile); // Creates a PrefProxyConfigTracker that tracks preferences of a // profile. On ChromeOS it additionaly tracks local state for shared proxy
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index 0b758d0..58c2f3d3 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -3236,7 +3236,9 @@ observer.Wait(); // Ensure that there is at least one more frame created than just the main // frame. - EXPECT_LT(1u, detached_web_contents->GetAllFrames().size()); + EXPECT_LT(1u, + CollectAllRenderFrameHosts(detached_web_contents->GetPrimaryPage()) + .size()); auto* tab_strip_model = browser()->tab_strip_model(); // Check that the autofill and password manager driver factories are notified
diff --git a/chrome/browser/platform_util_unittest.cc b/chrome/browser/platform_util_unittest.cc index c108277e..fa3b5bf1 100644 --- a/chrome/browser/platform_util_unittest.cc +++ b/chrome/browser/platform_util_unittest.cc
@@ -20,10 +20,6 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "base/json/json_string_value_serializer.h" #include "base/values.h" -#include "chrome/browser/apps/app_service/app_service_proxy_chromeos.h" -#include "chrome/browser/apps/app_service/app_service_proxy_factory.h" -#include "chrome/browser/apps/app_service/app_service_test.h" -#include "chrome/browser/apps/app_service/intent_util.h" #include "chrome/browser/ash/file_manager/app_id.h" #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/chromeos/fileapi/file_system_backend.h" @@ -84,11 +80,6 @@ old_content_browser_client_ = content::SetBrowserClientForTesting(content_browser_client_.get()); - app_service_test_.SetUp(GetProfile()); - app_service_proxy_ = - apps::AppServiceProxyFactory::GetForProfile(GetProfile()); - ASSERT_TRUE(app_service_proxy_); - // The test_directory needs to be mounted for it to be accessible. GetProfile()->GetMountPoints()->RegisterFileSystem( "test", storage::kFileSystemTypeLocal, storage::FileSystemMountOption(), @@ -128,20 +119,7 @@ extensions::mojom::ManifestLocation::kInvalidLocation, *manifest_dictionary, extensions::Extension::NO_FLAGS, &error); ASSERT_TRUE(error.empty()) << error; - - std::vector<apps::mojom::AppPtr> apps; - auto app = apps::mojom::App::New(); - app->app_id = "invalid-chrome-app"; - app->app_type = apps::mojom::AppType::kExtension; - app->show_in_launcher = apps::mojom::OptionalBool::kTrue; - app->readiness = apps::mojom::Readiness::kReady; - app->intent_filters = - apps_util::CreateChromeAppIntentFilters(extension.get()); - apps.push_back(std::move(app)); - app_service_proxy_->AppRegistryCache().OnApps( - std::move(apps), apps::mojom::AppType::kExtension, - /*should_notify_initialized=*/false); - app_service_test_.WaitForAppService(); + extensions::ExtensionRegistry::Get(GetProfile())->AddEnabled(extension); } void SetUp() override { @@ -163,8 +141,6 @@ private: std::unique_ptr<content::ContentBrowserClient> content_browser_client_; content::ContentBrowserClient* old_content_browser_client_ = nullptr; - apps::AppServiceTest app_service_test_; - apps::AppServiceProxyChromeOs* app_service_proxy_ = nullptr; }; #else
diff --git a/chrome/browser/plugins/flash_temporary_permission_tracker_unittest.cc b/chrome/browser/plugins/flash_temporary_permission_tracker_unittest.cc index 16585d8d..00a13af 100644 --- a/chrome/browser/plugins/flash_temporary_permission_tracker_unittest.cc +++ b/chrome/browser/plugins/flash_temporary_permission_tracker_unittest.cc
@@ -87,14 +87,16 @@ GrantSurvivesChildFrameNavigations) { content::RenderFrameHost* rfh = GetMainRFH(kOrigin1); content::RenderFrameHost* child = AddChildRFH(rfh, kOrigin2); - EXPECT_EQ(2u, web_contents()->GetAllFrames().size()); + EXPECT_EQ( + 2u, CollectAllRenderFrameHosts(web_contents()->GetPrimaryPage()).size()); tracker()->FlashEnabledForWebContents(web_contents()); content::NavigationSimulator::Reload(web_contents()); EXPECT_TRUE(tracker()->IsFlashEnabled(GURL(kOrigin1))); // Recreate the child frame after the reload. - EXPECT_EQ(1u, web_contents()->GetAllFrames().size()); + EXPECT_EQ( + 1u, CollectAllRenderFrameHosts(web_contents()->GetPrimaryPage()).size()); child = AddChildRFH(rfh, kOrigin2); // Navigate the child frame. Flash should still be enabled after this.
diff --git a/chrome/browser/policy/test/autoplay_policy_browsertest.cc b/chrome/browser/policy/test/autoplay_policy_browsertest.cc index 7633cc5..48cae9da 100644 --- a/chrome/browser/policy/test/autoplay_policy_browsertest.cc +++ b/chrome/browser/policy/test/autoplay_policy_browsertest.cc
@@ -72,7 +72,7 @@ } content::RenderFrameHost* GetChildFrame() { - return GetWebContents()->GetAllFrames()[1]; + return ChildFrameAt(GetMainFrame(), 0); } private:
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 4293ff1..a0e78ab 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -418,6 +418,7 @@ #if BUILDFLAG(IS_CHROMEOS_LACROS) #include "chrome/browser/lacros/lacros_prefs.h" +#include "chrome/browser/lacros/net/proxy_config_service_lacros.h" #endif #if !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) @@ -1356,6 +1357,7 @@ #if BUILDFLAG(IS_CHROMEOS_LACROS) lacros_prefs::RegisterProfilePrefs(registry); + chromeos::ProxyConfigServiceLacros::RegisterProfilePrefs(registry); #endif #if defined(OS_WIN)
diff --git a/chrome/browser/printing/print_browsertest.cc b/chrome/browser/printing/print_browsertest.cc index c5bf0918..f4eb890 100644 --- a/chrome/browser/printing/print_browsertest.cc +++ b/chrome/browser/printing/print_browsertest.cc
@@ -736,8 +736,7 @@ content::WebContents* original_contents = browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_EQ(2u, original_contents->GetAllFrames().size()); - content::RenderFrameHost* test_frame = original_contents->GetAllFrames()[1]; + content::RenderFrameHost* test_frame = ChildFrameAt(original_contents, 0); ASSERT_TRUE(test_frame); CreateTestPrintRenderFrame(test_frame, original_contents); @@ -761,7 +760,6 @@ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); content::WebContents* original_contents = browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_EQ(3u, original_contents->GetAllFrames().size()); // Create composite client so subframe print message can be forwarded. PrintCompositeClient::CreateForWebContents(original_contents); @@ -808,7 +806,6 @@ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); content::WebContents* original_contents = browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_EQ(3u, original_contents->GetAllFrames().size()); // Create composite client so subframe print message can be forwarded. PrintCompositeClient::CreateForWebContents(original_contents); @@ -859,10 +856,9 @@ content::WebContents* original_contents = browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_EQ(2u, original_contents->GetAllFrames().size()); content::RenderFrameHost* main_frame = original_contents->GetMainFrame(); ASSERT_TRUE(main_frame); - content::RenderFrameHost* test_frame = original_contents->GetAllFrames()[1]; + content::RenderFrameHost* test_frame = ChildFrameAt(main_frame, 0); ASSERT_TRUE(test_frame); ASSERT_NE(main_frame->GetProcess(), test_frame->GetProcess()); @@ -930,8 +926,7 @@ content::WebContents* original_contents = browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_EQ(2u, original_contents->GetAllFrames().size()); - content::RenderFrameHost* test_frame = original_contents->GetAllFrames()[1]; + content::RenderFrameHost* test_frame = ChildFrameAt(original_contents, 0); ASSERT_TRUE(test_frame); ASSERT_TRUE(test_frame->IsRenderFrameLive()); // Wait for the renderer to be down. @@ -958,8 +953,7 @@ content::WebContents* original_contents = browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_EQ(2u, original_contents->GetAllFrames().size()); - content::RenderFrameHost* subframe = original_contents->GetAllFrames()[1]; + content::RenderFrameHost* subframe = ChildFrameAt(original_contents, 0); ASSERT_TRUE(subframe); auto* subframe_rph = subframe->GetProcess(); @@ -998,9 +992,8 @@ browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_TRUE(NavigateIframeToURL(original_contents, "iframe", isolated_url)); - ASSERT_EQ(2u, original_contents->GetAllFrames().size()); auto* main_frame = original_contents->GetMainFrame(); - auto* subframe = original_contents->GetAllFrames()[1]; + auto* subframe = ChildFrameAt(main_frame, 0); ASSERT_NE(main_frame->GetProcess(), subframe->GetProcess()); PrintAndWaitUntilPreviewIsReady(/*print_only_selection=*/false);
diff --git a/chrome/browser/profiles/incognito_profile_containment_browsertest.cc b/chrome/browser/profiles/incognito_profile_containment_browsertest.cc index d7fce82..94f149e 100644 --- a/chrome/browser/profiles/incognito_profile_containment_browsertest.cc +++ b/chrome/browser/profiles/incognito_profile_containment_browsertest.cc
@@ -30,9 +30,12 @@ // List of file or directory prefixes that are known to be modified during an // Incognito session. +// For ChromeOS, a copy of all members of |kAllowListPrefixesForAllPlatforms| +// that start with "/Default" is added to the allow list, replacing "/Default" +// with "/test-user". // TODO(http://crbug.com/1234755): Add audit message (or fix the issue) for all // paths that do not have a comment. -constexpr std::array<const char*, 11> kAllowListPrefixesForAllPlatforms = { +const char* kAllowListPrefixesForAllPlatforms[] = { "/Default/data_reduction_proxy_leveldb", "/Default/Extension State", "/Default/GCM Store/", @@ -42,34 +45,27 @@ "/Default/Reporting and NEL", "/Default/shared_proto_db", "/Default/Trust Tokens", + "/Default/Shortcuts", "/GrShaderCache/GPUCache", "/Local State"}; #if defined(OS_MAC) -constexpr std::array<const char*, 2> kAllowListPrefixesForPlatform = { - "/Default/Shortcuts", "/Default/Visited Links"}; +const char* kAllowListPrefixesForPlatform[] = {"/Default/Visited Links"}; #elif defined(OS_WIN) -constexpr std::array<const char*, 6> kAllowListPrefixesForPlatform = { +const char* kAllowListPrefixesForPlatform[] = { "/Default/databases-off-the-record", - "/Default/heavy_ad_intervention_opt_out.db", "/Default/Shortcuts", - "/Default/Top Sites", "/GrShaderCache/old_GPUCache", + "/Default/heavy_ad_intervention_opt_out.db", "/Default/Top Sites", + "/GrShaderCache/old_GPUCache", // This file only contains the path to the latest executable of Chrome, // therefore it's safe to be written in Incognito. "/Last Browser"}; #elif defined(OS_CHROMEOS) -constexpr std::array<const char*, 7> kAllowListPrefixesForPlatform = { - "/test-user/.variations-list.txt", - "/test-user/GCM Store", - "/test-user/Network Action Predictor", - "/test-user/PreferredApps", - "/test-user/shared_proto_db", - "/test-user/Shortcuts", - "/test-user/Trust Tokens"}; +const char* kAllowListPrefixesForPlatform[] = { + "/test-user/.variations-list.txt"}; #elif defined(OS_LINUX) -constexpr std::array<const char*, 1> kAllowListPrefixesForPlatform = { - "/Default/Web Data"}; +const char* kAllowListPrefixesForPlatform[] = {"/Default/Web Data"}; #else -constexpr std::array<const char*, 0> kAllowListPrefixesForPlatform = {}; +const char* kAllowListPrefixesForPlatform[] = {}; #endif // Structure that keeps data about a snapshotted file. @@ -139,7 +135,7 @@ bool IsDiskStateModified(Snapshot& snapshot_before, Snapshot& snapshot_after, - std::set<const char*>& allow_list) { + std::set<std::string>& allow_list) { bool modified = false; // TODO(http://crbug.com/1234755): Consider deleted files as well. Currently // we only look for added and modified files, but file deletion is also @@ -151,7 +147,7 @@ fd.second.last_modified_time != before->second.last_modified_time) { // Ignore allow-listed paths. if (std::any_of(allow_list.begin(), allow_list.end(), - [&fd](const char* prefix) { + [&fd](std::string prefix) { return fd.first.find(prefix) == 0; })) { continue; @@ -183,6 +179,19 @@ IncognitoProfileContainmentBrowserTest() : allow_list_(std::begin(kAllowListPrefixesForAllPlatforms), std::end(kAllowListPrefixesForAllPlatforms)) { +#if defined(OS_CHROMEOS) + // These prefixes are allowed twice, once under "Default" and once under + // "test-user". + std::set<std::string> test_folder; + const int offset = strlen("/Default"); + for (std::string prefix : allow_list_) { + if (prefix.find("/Default/") == 0) { + test_folder.insert(std::string("/test-user") + prefix.substr(offset)); + } + } + allow_list_.insert(test_folder.begin(), test_folder.end()); +#endif + allow_list_.insert(std::begin(kAllowListPrefixesForPlatform), std::end(kAllowListPrefixesForPlatform)); } @@ -201,7 +210,7 @@ } protected: - std::set<const char*> allow_list_; + std::set<std::string> allow_list_; }; // Open a page in a separate session to ensure all files that are created
diff --git a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc index 5187e10a..5e0fca7d 100644 --- a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
@@ -768,8 +768,8 @@ // Grab the original frames. content::WebContents* contents = tsm()->GetActiveWebContents(); content::RenderFrameHost* main_frame = contents->GetMainFrame(); - ASSERT_EQ(3u, contents->GetAllFrames().size()); - content::RenderFrameHost* child_frame = contents->GetAllFrames()[1]; + content::RenderFrameHost* child_frame = ChildFrameAt(main_frame, 0); + ASSERT_TRUE(child_frame); // Sanity check that in this test page the main frame and the // subframe are cross-site. @@ -805,8 +805,8 @@ // Re-assign pointers after discarding, as they've changed. contents = tsm()->GetActiveWebContents(); main_frame = contents->GetMainFrame(); - ASSERT_LE(2u, contents->GetAllFrames().size()); - child_frame = contents->GetAllFrames()[1]; + child_frame = ChildFrameAt(main_frame, 0); + ASSERT_TRUE(child_frame); // document.wasDiscarded is true after discard, on mainframe and childframe. bool discarded_mainframe_result; @@ -823,7 +823,7 @@ GURL childframe_url(embedded_test_server()->GetURL("b.com", "/title1.html")); EXPECT_TRUE(NavigateIframeToURL(contents, "frame1", childframe_url)); EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - contents->GetAllFrames()[1], kDiscardedStateJS, + ChildFrameAt(contents, 0), kDiscardedStateJS, &discarded_childframe_result)); EXPECT_FALSE(discarded_childframe_result); @@ -832,7 +832,7 @@ embedded_test_server()->GetURL("d.com", "/title1.html")); EXPECT_TRUE(NavigateIframeToURL(contents, "frame2", second_childframe_url)); EXPECT_TRUE(content::ExecuteScriptAndExtractBool( - contents->GetAllFrames()[2], kDiscardedStateJS, + ChildFrameAt(contents, 1), kDiscardedStateJS, &discarded_childframe_result)); EXPECT_FALSE(discarded_childframe_result);
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_my.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_my.xtb index f08c891..02dea42 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_my.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_my.xtb
@@ -559,7 +559,7 @@ <translation id="4839925464551908214">ယခင် အတန်းသို့ သွားရန်</translation> <translation id="4841614409681890122">ပန်းရင့်</translation> <translation id="4844625982113518938">ကြိုက်ရာခလုတ်ကို နှိပ်ပြီး ၎င်း၏ အမည်ကို လေ့လာပါ။ Ctrl+W ကိုနှိပ်လိုက်လျှင် လေ့လာခြင်းမုဒ်ကို ပိတ်လိုက်ပါမည်။</translation> -<translation id="4846428657345567687">ChromeVox မှ ကြိုဆိုပါသည်။</translation> +<translation id="4846428657345567687">ChromeVox က ကြိုဆိုပါသည်။</translation> <translation id="4848993367330139335">tmr</translation> <translation id="4854380505292502090">ယခင် မီဒီယာဝိဂျက် မရှိပါ</translation> <translation id="4855927945655956315">အဓိက ကီးများ- Control</translation>
diff --git a/chrome/browser/resources/settings/BUILD.gn b/chrome/browser/resources/settings/BUILD.gn index e421a41..9c98f792 100644 --- a/chrome/browser/resources/settings/BUILD.gn +++ b/chrome/browser/resources/settings/BUILD.gn
@@ -188,7 +188,7 @@ in_files += [ "languages_page/languages.js", "languages_page/languages_browser_proxy.js", - "languages_page/languages_settings_metrics_proxy.js", + "languages_page/languages_settings_metrics_proxy.ts", "languages_page/languages_types.js", "people_page/import_data_browser_proxy.js", "people_page/manage_profile_browser_proxy.js", @@ -347,7 +347,7 @@ } if (!is_chromeos_ash && !is_mac) { - in_files += [ "languages_page/edit_dictionary_page.js" ] + in_files += [ "languages_page/edit_dictionary_page.ts" ] } if (!is_chromeos) { @@ -359,9 +359,9 @@ if (!is_chromeos_ash) { in_files += [ - "languages_page/add_languages_dialog.js", - "languages_page/languages_page.js", - "languages_page/languages_subpage.js", + "languages_page/add_languages_dialog.ts", + "languages_page/languages_page.ts", + "languages_page/languages_subpage.ts", "people_page/import_data_dialog.js", "people_page/manage_profile.js", ] @@ -476,9 +476,6 @@ if (!is_chromeos_ash) { deps = [ "languages_page:languages_browser_proxy", - "languages_page:languages_page", - "languages_page:languages_settings_metrics_proxy", - "languages_page:languages_subpage", "languages_page:languages_types", ] } @@ -827,12 +824,12 @@ ] } in_files += [ - "languages_page/add_languages_dialog.js", + "languages_page/add_languages_dialog.ts", "languages_page/languages_browser_proxy.js", "languages_page/languages.js", - "languages_page/languages_page.js", - "languages_page/languages_settings_metrics_proxy.js", - "languages_page/languages_subpage.js", + "languages_page/languages_page.ts", + "languages_page/languages_settings_metrics_proxy.ts", + "languages_page/languages_subpage.ts", "languages_page/languages_types.js", "people_page/import_data_browser_proxy.js", "people_page/import_data_dialog.js", @@ -842,7 +839,7 @@ } if (!is_chromeos_ash && !is_mac) { - in_files += [ "languages_page/edit_dictionary_page.js" ] + in_files += [ "languages_page/edit_dictionary_page.ts" ] } deps = [ @@ -859,6 +856,7 @@ definitions = [ "//tools/typescript/definitions/autofill_private.d.ts", "//tools/typescript/definitions/chrome_send.d.ts", + "//tools/typescript/definitions/language_settings_private.d.ts", "//tools/typescript/definitions/management.d.ts", "//tools/typescript/definitions/metrics_private.d.ts", "//tools/typescript/definitions/passwords_private.d.ts",
diff --git a/chrome/browser/resources/settings/languages_page/BUILD.gn b/chrome/browser/resources/settings/languages_page/BUILD.gn index 31b834a..ca3cbca 100644 --- a/chrome/browser/resources/settings/languages_page/BUILD.gn +++ b/chrome/browser/resources/settings/languages_page/BUILD.gn
@@ -15,45 +15,12 @@ ":languages_browser_proxy", ":languages_types", ] - - if (!is_chromeos_ash) { - deps += [ - ":add_languages_dialog", - ":edit_dictionary_page", - ":languages_page", - ":languages_settings_metrics_proxy", - ":languages_subpage", - ] - } } js_library("languages_types") { externs_list = [ "$externs_path/language_settings_private.js" ] } -js_library("add_languages_dialog") { - deps = [ - ":languages_types", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements:cr_scrollable_behavior.m", - "//ui/webui/resources/cr_elements:find_shortcut_behavior", - "//ui/webui/resources/cr_elements/cr_search_field:cr_search_field", - ] -} - -js_library("edit_dictionary_page") { - deps = [ - ":languages_browser_proxy", - "..:global_scroll_target_mixin", - "..:route", - "../prefs:prefs", - "//third_party/polymer/v3_0/components-chromium/iron-list:iron-list", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements/cr_button:cr_button.m", - "//ui/webui/resources/cr_elements/cr_input:cr_input.m", - ] -} - js_library("languages") { deps = [ ":languages_browser_proxy", @@ -91,50 +58,13 @@ ] } -js_library("languages_settings_metrics_proxy") { - deps = [ "//ui/webui/resources/js:cr.m" ] - externs_list = [ "$externs_path/metrics_private.js" ] -} - -js_library("languages_page") { - deps = [ - ":languages", - ":languages_settings_metrics_proxy", - "..:route", - "..:router", - "../settings_page:settings_animated_pages", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements/cr_expand_button:cr_expand_button.m", - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:load_time_data.m", - "//ui/webui/resources/js/cr/ui:focus_without_ink.m", - ] -} - -js_library("languages_subpage") { - deps = [ - ":languages", - ":languages_settings_metrics_proxy", - "..:lifetime_browser_proxy", - "..:route", - "..:router", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", - "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render.m", - "//ui/webui/resources/js:assert.m", - "//ui/webui/resources/js:cr.m", - "//ui/webui/resources/js:load_time_data.m", - "//ui/webui/resources/js/cr/ui:focus_without_ink.m", - ] -} - if (!is_chromeos_ash) { html_to_js("web_components") { js_files = [ - "add_languages_dialog.js", - "edit_dictionary_page.js", - "languages_page.js", - "languages_subpage.js", + "add_languages_dialog.ts", + "edit_dictionary_page.ts", + "languages_page.ts", + "languages_subpage.ts", ] } }
diff --git a/chrome/browser/resources/settings/languages_page/add_languages_dialog.js b/chrome/browser/resources/settings/languages_page/add_languages_dialog.ts similarity index 66% rename from chrome/browser/resources/settings/languages_page/add_languages_dialog.js rename to chrome/browser/resources/settings/languages_page/add_languages_dialog.ts index 6aff74e..96f8833d 100644 --- a/chrome/browser/resources/settings/languages_page/add_languages_dialog.js +++ b/chrome/browser/resources/settings/languages_page/add_languages_dialog.ts
@@ -14,19 +14,37 @@ import 'chrome://resources/polymer/v3_0/iron-list/iron-list.js'; import '../settings_shared_css.js'; +import {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js'; +import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js'; import {CrScrollableBehavior} from 'chrome://resources/cr_elements/cr_scrollable_behavior.m.js'; +import {CrSearchFieldElement} from 'chrome://resources/cr_elements/cr_search_field/cr_search_field.js'; import {FindShortcutBehavior} from 'chrome://resources/cr_elements/find_shortcut_behavior.js'; import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +interface SettingsAddLanguagesDialogElement { + $: { + dialog: CrDialogElement, + search: CrSearchFieldElement, + }; +} -/** - * @constructor - * @extends {PolymerElement} - */ -const SettingsAddLanguagesDialogElementBase = mixinBehaviors( - [CrScrollableBehavior, FindShortcutBehavior], PolymerElement); +// Workaround for the fact that TypeScript definitions are missing +// |scrollIntoViewIfNeeded|. +interface HTMLElementWithScroll extends HTMLElement { + scrollIntoViewIfNeeded(): void; +} -/** @polymer */ +interface Repeaterevent extends Event { + model: { + item: chrome.languageSettingsPrivate.Language, + }; +} + +const SettingsAddLanguagesDialogElementBase = + mixinBehaviors( + [CrScrollableBehavior, FindShortcutBehavior], PolymerElement) as + {new (): PolymerElement & FindShortcutBehavior}; + class SettingsAddLanguagesDialogElement extends SettingsAddLanguagesDialogElementBase { static get is() { @@ -39,13 +57,11 @@ static get properties() { return { - /** @type {!Array<!chrome.languageSettingsPrivate.Language>} */ languages: { type: Array, notify: true, }, - /** @private {!Set<string>} */ languagesToAdd_: { type: Object, value() { @@ -53,13 +69,11 @@ }, }, - /** @private */ disableActionButton_: { type: Boolean, value: true, }, - /** @private */ filterValue_: { type: String, value: '', @@ -67,7 +81,11 @@ }; } - /** @override */ + languages: Array<chrome.languageSettingsPrivate.Language>; + private languagesToAdd_: Set<string>; + private disableActionButton_: boolean; + private filterValue_: string; + connectedCallback() { super.connectedCallback(); @@ -75,10 +93,10 @@ } // Override FindShortcutBehavior methods. - handleFindShortcut(modalContextOpen) { + handleFindShortcut(_modalContextOpen: boolean) { // Assumes this is the only open modal. const searchInput = this.$.search.getSearchInput(); - searchInput.scrollIntoViewIfNeeded(); + (searchInput as unknown as HTMLElementWithScroll).scrollIntoViewIfNeeded(); if (!this.searchInputHasFocus()) { searchInput.focus(); } @@ -88,23 +106,17 @@ // Override FindShortcutBehavior methods. searchInputHasFocus() { return this.$.search.getSearchInput() === - this.$.search.shadowRoot.activeElement; + this.$.search.shadowRoot!.activeElement; } - /** - * @param {!CustomEvent<string>} e - * @private - */ - onSearchChanged_(e) { + private onSearchChanged_(e: CustomEvent<string>) { this.filterValue_ = e.detail; } /** - * @return {!Array<!chrome.languageSettingsPrivate.Language>} A list of - * languages to be displayed. - * @private + * @return A list of languages to be displayed. */ - getLanguages_() { + private getLanguages_(): Array<chrome.languageSettingsPrivate.Language> { if (!this.filterValue_) { return this.languages; } @@ -117,12 +129,8 @@ }); } - /** - * @param {!chrome.languageSettingsPrivate.Language} language - * @return {string} The text to be displayed. - * @private - */ - getDisplayText_(language) { + private getDisplayText_(language: chrome.languageSettingsPrivate.Language): + string { let displayText = language.displayName; // If the native name is different, add it. if (language.displayName !== language.nativeDisplayName) { @@ -132,28 +140,23 @@ } /** - * True if the user has chosen to add this language (checked its checkbox). - * @param {string} languageCode - * @return {boolean} - * @private + * @return Whether the user has chosen to add this language (checked its + * checkbox). */ - willAdd_(languageCode) { + private willAdd_(languageCode: string): boolean { return this.languagesToAdd_.has(languageCode); } /** * Handler for checking or unchecking a language item. - * @param {!{model: !{item: !chrome.languageSettingsPrivate.Language}, - * target: !Element}} e - * @private */ - onLanguageCheckboxChange_(e) { + private onLanguageCheckboxChange_(e: Repeaterevent) { // Add or remove the item to the Set. No need to worry about data binding: // willAdd_ is called to initialize the checkbox state (in case the // iron-list re-uses a previous checkbox), and the checkbox can only be // changed after that by user action. const language = e.model.item; - if (e.target.checked) { + if ((e.target as CrCheckboxElement).checked) { this.languagesToAdd_.add(language.code); } else { this.languagesToAdd_.delete(language.code); @@ -162,16 +165,14 @@ this.disableActionButton_ = !this.languagesToAdd_.size; } - /** @private */ - onCancelButtonTap_() { + private onCancelButtonTap_() { this.$.dialog.close(); } /** * Enables the checked languages. - * @private */ - onActionButtonTap_() { + private onActionButtonTap_() { this.dispatchEvent(new CustomEvent('languages-added', { bubbles: true, composed: true, @@ -180,16 +181,13 @@ this.$.dialog.close(); } - /** - * @param {!KeyboardEvent} e - * @private - */ - onKeydown_(e) { + private onKeydown_(e: KeyboardEvent) { // Close dialog if 'esc' is pressed and the search box is already empty. if (e.key === 'Escape' && !this.$.search.getValue().trim()) { this.$.dialog.close(); } else if (e.key !== 'PageDown' && e.key !== 'PageUp') { - this.$.search.scrollIntoViewIfNeeded(); + (this.$.search as unknown as HTMLElementWithScroll) + .scrollIntoViewIfNeeded(); } } }
diff --git a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.ts similarity index 76% rename from chrome/browser/resources/settings/languages_page/edit_dictionary_page.js rename to chrome/browser/resources/settings/languages_page/edit_dictionary_page.ts index c9b46d99..adab957 100644 --- a/chrome/browser/resources/settings/languages_page/edit_dictionary_page.js +++ b/chrome/browser/resources/settings/languages_page/edit_dictionary_page.ts
@@ -17,12 +17,15 @@ import '../settings_shared_css.js'; import '../settings_vars_css.js'; +import {CrInputElement} from 'chrome://resources/cr_elements/cr_input/cr_input.m.js'; +import {IronA11yKeysElement} from 'chrome://resources/polymer/v3_0/iron-a11y-keys/iron-a11y-keys.js'; import {flush, html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {GlobalScrollTargetMixin} from '../global_scroll_target_mixin.js'; import {loadTimeData} from '../i18n_setup.js'; import {PrefsBehavior} from '../prefs/prefs_behavior.js'; import {routes} from '../route.js'; +import {Route} from '../router.js'; import {LanguagesBrowserProxyImpl} from './languages_browser_proxy.js'; @@ -30,15 +33,17 @@ // https://cs.chromium.org/chromium/src/components/spellcheck/common/spellcheck_common.h?l=28 const MAX_CUSTOM_DICTIONARY_WORD_BYTES = 99; +interface SettingsEditDictionaryPageElement { + $: { + keys: IronA11yKeysElement, + newWord: HTMLElement, + }; +} -/** - * @constructor - * @extends {PolymerElement} - */ const SettingsEditDictionaryPageElementBase = - GlobalScrollTargetMixin(PolymerElement); + GlobalScrollTargetMixin(PolymerElement) as unknown as + {new (): PolymerElement}; -/** @polymer */ class SettingsEditDictionaryPageElement extends SettingsEditDictionaryPageElementBase { static get is() { @@ -51,7 +56,6 @@ static get properties() { return { - /** @private {string} */ newWordValue_: { type: String, value: '', @@ -59,14 +63,12 @@ /** * Needed by GlobalScrollTargetMixin. - * @override */ subpageRoute: { type: Object, value: routes.EDIT_DICTIONARY, }, - /** @private {!Array<string>} */ words_: { type: Array, value() { @@ -74,35 +76,32 @@ }, }, - /** @private {boolean} */ hasWords_: { type: Boolean, value: false, }, - }; } - constructor() { - super(); + private newWordValue_: string; + subpageRoute: Route; + private words_: Array<string>; + private hasWords_: boolean; + private languageSettingsPrivate_: + (typeof chrome.languageSettingsPrivate)|null = null; - /** @private {?LanguageSettingsPrivate} */ - this.languageSettingsPrivate_ = null; - } - - /** @override */ ready() { super.ready(); this.languageSettingsPrivate_ = LanguagesBrowserProxyImpl.getInstance().getLanguageSettingsPrivate(); - this.languageSettingsPrivate_.getSpellcheckWords(words => { + this.languageSettingsPrivate_!.getSpellcheckWords(words => { this.hasWords_ = words.length > 0; this.words_ = words; }); - this.languageSettingsPrivate_.onCustomDictionaryChanged.addListener( + this.languageSettingsPrivate_!.onCustomDictionaryChanged.addListener( this.onCustomDictionaryChanged_.bind(this)); // Add a key handler for the new-word input. @@ -111,31 +110,24 @@ /** * Adds the word in the new-word input to the dictionary. - * @private */ - addWordFromInput_() { + private addWordFromInput_() { // Spaces are allowed, but removing leading and trailing whitespace. const word = this.getTrimmedNewWord_(); this.newWordValue_ = ''; if (word) { - this.languageSettingsPrivate_.addSpellcheckWord(word); + this.languageSettingsPrivate_!.addSpellcheckWord(word); } } /** * Check if the field is empty or invalid. - * @return {boolean} - * @private */ - disableAddButton_() { + private disableAddButton_(): boolean { return this.getTrimmedNewWord_().length === 0 || this.isWordInvalid_(); } - /** - * @return {string} - * @private - */ - getErrorMessage_() { + private getErrorMessage_(): string { if (this.newWordIsTooLong_()) { return loadTimeData.getString('addDictionaryWordLengthError'); } @@ -145,44 +137,30 @@ return ''; } - /** - * @return {string} - * @private - */ - getTrimmedNewWord_() { + private getTrimmedNewWord_(): string { return this.newWordValue_.trim(); } /** * If the word is invalid, returns true (or a message if one is provided). * Otherwise returns false. - * @return {boolean} - * @private */ - isWordInvalid_() { + private isWordInvalid_(): boolean { return this.newWordAlreadyAdded_() || this.newWordIsTooLong_(); } - /** - * @return {boolean} - * @private - */ - newWordAlreadyAdded_() { + private newWordAlreadyAdded_(): boolean { return this.words_.includes(this.getTrimmedNewWord_()); } - /** - * @return {boolean} - * @private - */ - newWordIsTooLong_() { + private newWordIsTooLong_(): boolean { return this.getTrimmedNewWord_().length > MAX_CUSTOM_DICTIONARY_WORD_BYTES; } /** * Handles tapping on the Add Word button. */ - onAddWordTap_(e) { + private onAddWordTap_() { this.addWordFromInput_(); this.$.newWord.focus(); } @@ -190,10 +168,9 @@ /** * Handles updates to the word list. Additions are unshifted to the top * of the list so that users can see them easily. - * @param {!Array<string>} added - * @param {!Array<string>} removed */ - onCustomDictionaryChanged_(added, removed) { + private onCustomDictionaryChanged_( + added: Array<string>, removed: Array<string>) { const wasEmpty = this.words_.length === 0; for (const word of removed) { @@ -227,28 +204,27 @@ // wrapping the list is expanded. if (wasEmpty && this.words_.length > 0) { flush(); - this.shadowRoot.querySelector('#list').notifyResize(); + this.shadowRoot!.querySelector('iron-list')!.notifyResize(); } } /** * Handles Enter and Escape key presses for the new-word input. - * @param {!CustomEvent<!{key: string}>} e */ - onKeysPress_(e) { + private onKeysPress_( + e: CustomEvent<{key: string, keyboardEvent: KeyboardEvent}>) { if (e.detail.key === 'enter' && !this.disableAddButton_()) { this.addWordFromInput_(); } else if (e.detail.key === 'esc') { - e.detail.keyboardEvent.target.value = ''; + (e.detail.keyboardEvent.target as CrInputElement).value = ''; } } /** * Handles tapping on a "Remove word" icon button. - * @param {!{model: !{item: string}}} e */ - onRemoveWordTap_(e) { - this.languageSettingsPrivate_.removeSpellcheckWord(e.model.item); + private onRemoveWordTap_(e: {model: {item: string}}) { + this.languageSettingsPrivate_!.removeSpellcheckWord(e.model.item); } }
diff --git a/chrome/browser/resources/settings/languages_page/languages_browser_proxy.js b/chrome/browser/resources/settings/languages_page/languages_browser_proxy.js index c94971a..8f542e9 100644 --- a/chrome/browser/resources/settings/languages_page/languages_browser_proxy.js +++ b/chrome/browser/resources/settings/languages_page/languages_browser_proxy.js
@@ -8,7 +8,7 @@ */ // clang-format off -import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; +import {sendWithPromise} from 'chrome://resources/js/cr.m.js'; // clang-format on /** @interface */ @@ -64,8 +64,17 @@ return /** @type {!InputMethodPrivate} */ (chrome.inputMethodPrivate); } // </if> + + /** @return {!LanguagesBrowserProxy} */ + static getInstance() { + return instance || (instance = new LanguagesBrowserProxyImpl()); + } + + /** @param {!LanguagesBrowserProxy} obj */ + static setInstance(obj) { + instance = obj; + } } - // The singleton instance_ is replaced with a test version of this wrapper - // during testing. -addSingletonGetter(LanguagesBrowserProxyImpl); +/** @type {?LanguagesBrowserProxy} */ +let instance = null;
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.js b/chrome/browser/resources/settings/languages_page/languages_page.ts similarity index 76% rename from chrome/browser/resources/settings/languages_page/languages_page.js rename to chrome/browser/resources/settings/languages_page/languages_page.ts index 7b96676..819b453 100644 --- a/chrome/browser/resources/settings/languages_page/languages_page.js +++ b/chrome/browser/resources/settings/languages_page/languages_page.ts
@@ -37,7 +37,7 @@ import {assert} from 'chrome://resources/js/assert.m.js'; import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js'; -import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js'; +import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; import {flush, html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {loadTimeData} from '../i18n_setup.js'; @@ -48,16 +48,18 @@ import {LanguageSettingsActionType, LanguageSettingsMetricsProxy, LanguageSettingsMetricsProxyImpl, LanguageSettingsPageImpressionType} from './languages_settings_metrics_proxy.js'; import {LanguageHelper, LanguagesModel, LanguageState, SpellCheckLanguageState} from './languages_types.js'; -/** - * @constructor - * @extends {PolymerElement} - * @implements {I18nBehaviorInterface} - * @implements {PrefsBehaviorInterface} - */ -const SettingsLanguagesPageElementBase = - mixinBehaviors([I18nBehavior, PrefsBehavior], PolymerElement); +interface RepeaterEvent extends Event { + model: { + item: LanguageState, + }; +} -/** @polymer */ +type FocusConfig = Map<string, (string|(() => void))>; + +const SettingsLanguagesPageElementBase = + mixinBehaviors([I18nBehavior, PrefsBehavior], PolymerElement) as + {new (): PolymerElement & I18nBehavior & PrefsBehaviorInterface}; + class SettingsLanguagesPageElement extends SettingsLanguagesPageElementBase { static get is() { return 'settings-languages-page'; @@ -80,18 +82,15 @@ /** * Read-only reference to the languages model provided by the * 'settings-languages' instance. - * @type {!LanguagesModel|undefined} */ languages: { type: Object, notify: true, }, - /** @type {!LanguageHelper} */ languageHelper: Object, // <if expr="not is_macosx"> - /** @private */ spellCheckLanguages_: { type: Array, value() { @@ -102,12 +101,9 @@ /** * The language to display the details for. - * @type {!LanguageState|undefined} - * @private */ detailLanguage_: Object, - /** @private */ enableDesktopRestructuredLanguageSettings_: { type: Boolean, value() { @@ -120,7 +116,6 @@ }, }, - /** @private */ hideSpellCheckLanguages_: { type: Boolean, value: false, @@ -128,17 +123,14 @@ /** * Whether the language settings list is opened. - * @private */ languagesOpened_: { type: Boolean, observer: 'onLanguagesOpenedChanged_', }, - /** @private */ showAddLanguagesDialog_: Boolean, - /** @private {!Map<string, string>} */ focusConfig_: { type: Object, value() { @@ -174,26 +166,26 @@ } // </if> - /** @override */ - constructor() { - super(); - - /** @private {!LanguageSettingsMetricsProxy} */ - this.languageSettingsMetricsProxy_ = - LanguageSettingsMetricsProxyImpl.getInstance(); - } + languages?: LanguagesModel; + languageHelper: LanguageHelper; + private spellCheckLanguages_: Array<LanguageState|SpellCheckLanguageState>; + private detailLanguage_?: LanguageState; + private enableDesktopRestructuredLanguageSettings_: boolean; + private hideSpellCheckLanguages_: boolean; + private languagesOpened_: boolean; + private showAddLanguagesDialog_: boolean; + private focusConfig_: FocusConfig; + private languageSettingsMetricsProxy_: LanguageSettingsMetricsProxy = + LanguageSettingsMetricsProxyImpl.getInstance(); // <if expr="not is_macosx"> /** * Checks if there are any errors downloading the spell check dictionary. * This is used for showing/hiding error messages, spell check toggle and * retry. button. - * @param {number} downloadDictionaryFailureCount - * @param {number} threshold - * @return {boolean} - * @private */ - errorsGreaterThan_(downloadDictionaryFailureCount, threshold) { + private errorsGreaterThan_( + downloadDictionaryFailureCount: number, threshold: number): boolean { return downloadDictionaryFailureCount > threshold; } // </if> @@ -202,9 +194,10 @@ /** * Returns the value to use as the |pref| attribute for the policy indicator * of spellcheck languages, based on whether or not the language is enabled. - * @param {boolean} isEnabled Whether the language is enabled or not. + * @param isEnabled Whether the language is enabled or not. */ - getIndicatorPrefForManagedSpellcheckLanguage_(isEnabled) { + getIndicatorPrefForManagedSpellcheckLanguage_(isEnabled: boolean): + chrome.settingsPrivate.PrefObject { return isEnabled ? this.get('spellcheck.forced_dictionaries', this.prefs) : this.get('spellcheck.blocked_dictionaries', this.prefs); } @@ -212,18 +205,17 @@ /** * Returns an array of enabled languages, plus spellcheck languages that are * force-enabled by policy. - * @return {!Array<!LanguageState|!SpellCheckLanguageState>} - * @private */ - getSpellCheckLanguages_() { - const supportedSpellcheckLanguages = - /** @type {!Array<!LanguageState|!SpellCheckLanguageState>} */ ( - this.languages.enabled.filter( - (item) => item.language.supportsSpellcheck)); + private getSpellCheckLanguages_(): + Array<LanguageState|SpellCheckLanguageState> { + const supportedSpellcheckLanguages: + Array<LanguageState|SpellCheckLanguageState> = + this.languages!.enabled.filter( + (item) => item.language.supportsSpellcheck); const supportedSpellcheckLanguagesSet = new Set(supportedSpellcheckLanguages.map(x => x.language.code)); - this.languages.spellCheckOnLanguages.forEach(spellCheckLang => { + this.languages!.spellCheckOnLanguages.forEach(spellCheckLang => { if (!supportedSpellcheckLanguagesSet.has(spellCheckLang.language.code)) { supportedSpellcheckLanguages.push(spellCheckLang); } @@ -232,8 +224,7 @@ return supportedSpellcheckLanguages; } - /** @private */ - updateSpellcheckLanguages_() { + private updateSpellcheckLanguages_() { if (this.languages === undefined) { return; } @@ -275,8 +266,7 @@ } } - /** @private */ - updateSpellcheckEnabled_() { + private updateSpellcheckEnabled_() { if (this.prefs === undefined) { return; } @@ -295,18 +285,15 @@ /** * Opens the Custom Dictionary page. - * @private */ - onEditDictionaryTap_() { - Router.getInstance().navigateTo( - /** @type {!Route} */ (routes.EDIT_DICTIONARY)); + private onEditDictionaryTap_() { + Router.getInstance().navigateTo(routes.EDIT_DICTIONARY); } /** * Handler for enabling or disabling spell check for a specific language. - * @param {!{target: Element, model: !{item: !LanguageState}}} e */ - onSpellCheckLanguageChange_(e) { + private onSpellCheckLanguageChange_(e: RepeaterEvent) { const item = e.model.item; if (!item.language.supportsSpellcheck) { return; @@ -317,20 +304,17 @@ } /** - * @param {string} languageCode - * @return {string} The display name for a given language code. - * @private + * @return The display name for a given language code. */ - getProspectiveUILanguageName_(languageCode) { - return this.languageHelper.getLanguage(languageCode).displayName; + private getProspectiveUILanguageName_(languageCode: string): string { + return this.languageHelper.getLanguage(languageCode)!.displayName; } /** * Handler to initiate another attempt at downloading the spell check * dictionary for a specified language. - * @param {!{target: Element, model: !{item: !LanguageState}}} e */ - onRetryDictionaryDownloadClick_(e) { + private onRetryDictionaryDownloadClick_(e: RepeaterEvent) { assert(this.errorsGreaterThan_( e.model.item.downloadDictionaryFailureCount, 0)); this.languageHelper.retryDownloadDictionary(e.model.item.language.code); @@ -339,9 +323,8 @@ /** * Handler for clicking on the name of the language. The action taken must * match the control that is available. - * @param {!{target: Element, model: !{item: !LanguageState}}} e */ - onSpellCheckNameClick_(e) { + private onSpellCheckNameClick_(e: RepeaterEvent) { assert(!this.isSpellCheckNameClickDisabled_(e.model.item)); this.onSpellCheckLanguageChange_(e); } @@ -349,21 +332,15 @@ /** * Name only supports clicking when language is not managed, supports * spellcheck, and the dictionary has been downloaded with no errors. - * @param {!LanguageState|!SpellCheckLanguageState} item - * @return {boolean} - * @private */ - isSpellCheckNameClickDisabled_(item) { + private isSpellCheckNameClickDisabled_(item: LanguageState| + SpellCheckLanguageState): boolean { return item.isManaged || !item.language.supportsSpellcheck || item.downloadDictionaryFailureCount > 0; } // </if> expr="not is_macosx" - /** - * @return {string|undefined} - * @private - */ - getSpellCheckSubLabel_() { + private getSpellCheckSubLabel_(): string|undefined { // <if expr="not is_macosx"> if (this.spellCheckLanguages_.length === 0) { return this.i18n('spellCheckDisabledReason'); @@ -374,11 +351,10 @@ } /** - * @param {boolean} newVal The new value of languagesOpened_. - * @param {boolean} oldVal The old value of languagesOpened_. - * @private + * @param newVal The new value of languagesOpened_. + * @param oldVal The old value of languagesOpened_. */ - onLanguagesOpenedChanged_(newVal, oldVal) { + private onLanguagesOpenedChanged_(newVal: boolean, oldVal: boolean) { if (!oldVal && newVal) { this.languageSettingsMetricsProxy_.recordPageImpressionMetric( LanguageSettingsPageImpressionType.MAIN); @@ -388,34 +364,29 @@ // <if expr="not lacros"> /** * Opens the Language Settings page. - * @private */ - onLanguagesSubpageClick_() { + private onLanguagesSubpageClick_() { if (this.enableDesktopRestructuredLanguageSettings_) { - Router.getInstance().navigateTo( - /** @type {!Route} */ (routes.LANGUAGE_SETTINGS)); + Router.getInstance().navigateTo(routes.LANGUAGE_SETTINGS); } } // </if> /** * Toggles the expand button within the element being listened to. - * @param {!Event} e - * @private */ - toggleExpandButton_(e) { + private toggleExpandButton_(e: Event) { // The expand button handles toggling itself. - const expandButtonTag = 'CR-EXPAND-BUTTON'; - if (e.target.tagName === expandButtonTag) { + if ((e.target as HTMLElement).tagName === 'CR-EXPAND-BUTTON') { return; } - if (!e.currentTarget.hasAttribute('actionable')) { + if (!(e.currentTarget as HTMLElement).hasAttribute('actionable')) { return; } - /** @type {!CrExpandButtonElement} */ - const expandButton = e.currentTarget.querySelector(expandButtonTag); + const expandButton = + (e.currentTarget as HTMLElement).querySelector('cr-expand-button')!; assert(expandButton); expandButton.expanded = !expandButton.expanded; focusWithoutInk(expandButton);
diff --git a/chrome/browser/resources/settings/languages_page/languages_settings_metrics_proxy.js b/chrome/browser/resources/settings/languages_page/languages_settings_metrics_proxy.js deleted file mode 100644 index f4759eb..0000000 --- a/chrome/browser/resources/settings/languages_page/languages_settings_metrics_proxy.js +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -/* - This file is for recording Chrome Browser's language settings metrics on the - frontend. -*/ - -import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; - -/** - * These values are persisted to LanguageSettingsActionType - * in tools/metrics/histograms/enums.xml. Entries should not be renumbered and - * should never be reused. - * @enum {number} - */ -export const LanguageSettingsActionType = { - // CLICK_ON_ADD_LANGUAGE: 1, // Deprecated, use ADD_LANGUAGE in - // LanguageSettingsPageImpression - LANGUAGE_ADDED: 2, - LANGUAGE_REMOVED: 3, - DISABLE_TRANSLATE_GLOBALLY: 4, - ENABLE_TRANSLATE_GLOBALLY: 5, - DISABLE_TRANSLATE_FOR_SINGLE_LANGUAGE: 6, - ENABLE_TRANSLATE_FOR_SINGLE_LANGUAGE: 7, - LANGUAGE_LIST_REORDERED: 8, -}; - -/** - * These values are persisted to LanguageSettingsPageImpression - * in tools/metrics/histograms/enums.xml. Entries should not be renumbered and - * should never be reused. - * @enum {number} - */ -export const LanguageSettingsPageImpressionType = { - MAIN: 0, - ADD_LANGUAGE: 1, - // LANGUAGE_DETAILS: 2, // iOS only - CHROME_LANGUAGE: 3, - ADVANCED_LANGUAGE_SETTINGS: 4, - TARGET_LANGUAGE: 5, - LANGUAGE_OVERFLOW_MENU_OPENED: 6, -}; - -/** @interface */ -export class LanguageSettingsMetricsProxy { - /** - * Records the interaction to enumerated histogram. - * @param {!LanguageSettingsActionType} interaction - */ - recordSettingsMetric(interaction) {} - - /** - * Records the interaction to enumerated histogram. - * @param {!LanguageSettingsPageImpressionType} interaction - */ - recordPageImpressionMetric(interaction) {} -} - -/** @implements {LanguageSettingsMetricsProxy} */ -export class LanguageSettingsMetricsProxyImpl { - /** @override */ - recordSettingsMetric(interaction) { - chrome.metricsPrivate.recordEnumerationValue( - 'LanguageSettings.Actions', interaction, - Object.keys(LanguageSettingsActionType).length); - } - - /** @override */ - recordPageImpressionMetric(interaction) { - chrome.metricsPrivate.recordEnumerationValue( - 'LanguageSettings.PageImpression', interaction, - Object.keys(LanguageSettingsPageImpressionType).length); - } -} - -addSingletonGetter(LanguageSettingsMetricsProxyImpl);
diff --git a/chrome/browser/resources/settings/languages_page/languages_settings_metrics_proxy.ts b/chrome/browser/resources/settings/languages_page/languages_settings_metrics_proxy.ts new file mode 100644 index 0000000..41149e56 --- /dev/null +++ b/chrome/browser/resources/settings/languages_page/languages_settings_metrics_proxy.ts
@@ -0,0 +1,78 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/* + This file is for recording Chrome Browser's language settings metrics on the + frontend. +*/ + +/** + * These values are persisted to LanguageSettingsActionType + * in tools/metrics/histograms/enums.xml. Entries should not be renumbered and + * should never be reused. + */ +export enum LanguageSettingsActionType { + // CLICK_ON_ADD_LANGUAGE = 1, // Deprecated, use ADD_LANGUAGE in + // LanguageSettingsPageImpression + LANGUAGE_ADDED = 2, + LANGUAGE_REMOVED = 3, + DISABLE_TRANSLATE_GLOBALLY = 4, + ENABLE_TRANSLATE_GLOBALLY = 5, + DISABLE_TRANSLATE_FOR_SINGLE_LANGUAGE = 6, + ENABLE_TRANSLATE_FOR_SINGLE_LANGUAGE = 7, + LANGUAGE_LIST_REORDERED = 8, +} + +/** + * These values are persisted to LanguageSettingsPageImpression + * in tools/metrics/histograms/enums.xml. Entries should not be renumbered and + * should never be reused. + */ +export enum LanguageSettingsPageImpressionType { + MAIN = 0, + ADD_LANGUAGE = 1, + // LANGUAGE_DETAILS = 2, // iOS only + CHROME_LANGUAGE = 3, + ADVANCED_LANGUAGE_SETTINGS = 4, + TARGET_LANGUAGE = 5, + LANGUAGE_OVERFLOW_MENU_OPENED = 6, +} + +export interface LanguageSettingsMetricsProxy { + /** + * Records the interaction to enumerated histogram. + */ + recordSettingsMetric(interaction: LanguageSettingsActionType): void; + + /** + * Records the interaction to enumerated histogram. + */ + recordPageImpressionMetric(interaction: LanguageSettingsPageImpressionType): + void; +} + +export class LanguageSettingsMetricsProxyImpl implements + LanguageSettingsMetricsProxy { + recordSettingsMetric(interaction: LanguageSettingsActionType) { + chrome.metricsPrivate.recordEnumerationValue( + 'LanguageSettings.Actions', interaction, + Object.keys(LanguageSettingsActionType).length); + } + + recordPageImpressionMetric(interaction: LanguageSettingsPageImpressionType) { + chrome.metricsPrivate.recordEnumerationValue( + 'LanguageSettings.PageImpression', interaction, + Object.keys(LanguageSettingsPageImpressionType).length); + } + + static getInstance(): LanguageSettingsMetricsProxy { + return instance || (instance = new LanguageSettingsMetricsProxyImpl()); + } + + static setInstance(obj: LanguageSettingsMetricsProxy) { + instance = obj; + } +} + +let instance: LanguageSettingsMetricsProxy|null = null;
diff --git a/chrome/browser/resources/settings/languages_page/languages_subpage.js b/chrome/browser/resources/settings/languages_page/languages_subpage.ts similarity index 63% rename from chrome/browser/resources/settings/languages_page/languages_subpage.js rename to chrome/browser/resources/settings/languages_page/languages_subpage.ts index d6f228a..30664d3 100644 --- a/chrome/browser/resources/settings/languages_page/languages_subpage.js +++ b/chrome/browser/resources/settings/languages_page/languages_subpage.ts
@@ -29,12 +29,15 @@ import '../settings_vars_css.js'; import {CrActionMenuElement} from '//resources/cr_elements/cr_action_menu/cr_action_menu.js'; +import {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.m.js'; +import {CrLazyRenderElement} from 'chrome://resources/cr_elements/cr_lazy_render/cr_lazy_render.m.js'; import {assert} from 'chrome://resources/js/assert.m.js'; import {isWindows} from 'chrome://resources/js/cr.m.js'; import {focusWithoutInk} from 'chrome://resources/js/cr/ui/focus_without_ink.m.js'; import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js'; import {flush, html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {SettingsToggleButtonElement} from '../controls/settings_toggle_button_ts.js'; import {loadTimeData} from '../i18n_setup.js'; import {LifetimeBrowserProxyImpl} from '../lifetime_browser_proxy.js'; import {PrefsBehavior, PrefsBehaviorInterface} from '../prefs/prefs_behavior.js'; @@ -43,31 +46,35 @@ import {LanguageHelper, LanguagesModel, LanguageState} from './languages_types.js'; /** - * @type {number} Millisecond delay that can be used when closing an action - * menu to keep it briefly on-screen. + * Millisecond delay that can be used when closing an action menu to keep it + * briefly on-screen. */ -export const kMenuCloseDelay = 100; +export const kMenuCloseDelay: number = 100; +interface RepeaterEvent<T> extends Event { + model: { + item: T, + }; +} -/** - * @constructor - * @extends {PolymerElement} - * @implements {PrefsBehaviorInterface} - */ +type FocusConfig = Map<string, (string|(() => void))>; + +export interface SettingsLanguagesSubpageElement { + $: { + menu: CrLazyRenderElement<CrActionMenuElement>, + } +} + const SettingsLanguagesSubpageElementBase = - mixinBehaviors([I18nBehavior, PrefsBehavior], PolymerElement); + mixinBehaviors([I18nBehavior, PrefsBehavior], PolymerElement) as + {new (): PolymerElement & I18nBehavior & PrefsBehaviorInterface}; -/** @polymer */ export class SettingsLanguagesSubpageElement extends SettingsLanguagesSubpageElementBase { static get is() { return 'settings-languages-subpage'; } - static get template() { - return html`{__html_template__}`; - } - static get properties() { return { /** @@ -81,54 +88,39 @@ /** * Read-only reference to the languages model provided by the * 'settings-languages' instance. - * @type {!LanguagesModel|undefined} */ languages: { type: Object, notify: true, }, - /** @type {!LanguageHelper} */ languageHelper: Object, /** * The language to display the details for. - * @type {!LanguageState|undefined} - * @private */ detailLanguage_: Object, - /** @private */ showAddLanguagesDialog_: Boolean, - - /** @private */ showAddAlwaysTranslateDialog_: Boolean, - - /** @private */ showAddNeverTranslateDialog_: Boolean, - - /** @private {?Array<!chrome.languageSettingsPrivate.Language>} */ addLanguagesDialogLanguages_: Array, - /** @private {!Map<string, string>} */ focusConfig_: { type: Object, - value() { - const map = new Map(); - return map; + value: function() { + return new Map(); }, }, - /** @private */ showManagedLanguageDialog_: { type: Boolean, value: false, }, - /** @private */ enableDesktopDetailedLanguageSettings_: { type: Boolean, - value() { + value: function() { let enabled = false; // <if expr="not lacros"> enabled = @@ -140,48 +132,45 @@ }; } - /** @override */ - constructor() { - super(); + languages?: LanguagesModel; + languageHelper: LanguageHelper; + private detailLanguage_?: LanguageState; + private showAddLanguagesDialog_: boolean; + private showAddAlwaysTranslateDialog_: boolean; + private showAddNeverTranslateDialog_: boolean; + private addLanguagesDialogLanguages_: + Array<chrome.languageSettingsPrivate.Language>|null; + private focusConfig_: FocusConfig; + private showManagedLanguageDialog_: boolean; + private enableDesktopDetailedLanguageSettings_: boolean; + private languageSettingsMetricsProxy_: LanguageSettingsMetricsProxy = + LanguageSettingsMetricsProxyImpl.getInstance(); - /** @private {!LanguageSettingsMetricsProxy} */ - this.languageSettingsMetricsProxy_ = - LanguageSettingsMetricsProxyImpl.getInstance(); - - // <if expr="is_win"> - /** @private {boolean} */ - this.isChangeInProgress_ = false; - // </if> - } + // <if expr="is_win"> + private isChangeInProgress_: boolean = false; + // </if> /** * Stamps and opens the Add Languages dialog, registering a listener to * disable the dialog's dom-if again on close. - * @param {!Event} e - * @private */ - onAddLanguagesTap_(e) { + private onAddLanguagesTap_(e: Event) { e.preventDefault(); this.languageSettingsMetricsProxy_.recordPageImpressionMetric( LanguageSettingsPageImpressionType.ADD_LANGUAGE); - this.addLanguagesDialogLanguages_ = this.languages.supported.filter( + this.addLanguagesDialogLanguages_ = this.languages!.supported.filter( language => this.languageHelper.canEnableLanguage(language)); this.showAddLanguagesDialog_ = true; } - /** @private */ - onAddLanguagesDialogClose_() { + private onAddLanguagesDialogClose_() { this.showAddLanguagesDialog_ = false; this.addLanguagesDialogLanguages_ = null; - focusWithoutInk(assert(this.shadowRoot.querySelector('#addLanguages'))); + focusWithoutInk(assert(this.shadowRoot!.querySelector('#addLanguages')!)); } - /** - * @param {!CustomEvent<!Array<string>>} e - * @private - */ - onLanguagesAdded_(e) { + private onLanguagesAdded_(e: CustomEvent<Array<string>>) { const languagesToAdd = e.detail; languagesToAdd.forEach(languageCode => { this.languageHelper.enableLanguage(languageCode); @@ -193,33 +182,28 @@ /** * Stamps and opens the Add Languages dialog, registering a listener to * disable the dialog's dom-if again on close. - * @param {!Event} e - * @private */ - onAddAlwaysTranslateLanguagesClick_(e) { + private onAddAlwaysTranslateLanguagesClick_(e: Event) { e.preventDefault(); const translatableLanguages = this.getTranslatableLanguages_(); this.addLanguagesDialogLanguages_ = translatableLanguages.filter( - language => !this.languages.alwaysTranslate.includes(language)); + language => !this.languages!.alwaysTranslate.includes(language)); this.showAddAlwaysTranslateDialog_ = true; } - /** @private */ - onAlwaysTranslateDialogClose_() { + private onAlwaysTranslateDialogClose_() { this.showAddAlwaysTranslateDialog_ = false; this.addLanguagesDialogLanguages_ = null; focusWithoutInk( - assert(this.shadowRoot.querySelector('#addAlwaysTranslate'))); + assert(this.shadowRoot!.querySelector('#addAlwaysTranslate')!)); } /** * Helper function fired by the add dialog's on-languages-added event. Adds * selected languages to the always-translate languages list. - * @param {!CustomEvent<!Array<string>>} e - * @private */ - onAlwaysTranslateLanguagesAdded_(e) { + private onAlwaysTranslateLanguagesAdded_(e: CustomEvent<Array<string>>) { const languagesToAdd = e.detail; languagesToAdd.forEach(languageCode => { this.languageHelper.setLanguageAlwaysTranslateState(languageCode, true); @@ -228,10 +212,9 @@ /** * Removes a language from the always translate languages list. - * @param {!Event} e - * @private */ - onRemoveAlwaysTranslateLanguageClick_(e) { + private onRemoveAlwaysTranslateLanguageClick_( + e: RepeaterEvent<chrome.languageSettingsPrivate.Language>) { const languageCode = e.model.item.code; this.languageHelper.setLanguageAlwaysTranslateState(languageCode, false); } @@ -239,11 +222,9 @@ /** * Checks if there are supported languages that are not enabled but can be * enabled. - * @param {LanguagesModel|undefined} languages - * @return {boolean} True if there is at least one available language. - * @private + * @return True if there is at least one available language. */ - canEnableSomeSupportedLanguage_(languages) { + private canEnableSomeSupportedLanguage_(languages?: LanguagesModel): boolean { return languages === undefined || languages.supported.some(language => { return this.languageHelper.canEnableLanguage(language); }); @@ -252,30 +233,23 @@ /** * Stamps and opens the Add Languages dialog, registering a listener to * disable the dialog's dom-if again on close. - * @param {!Event} e - * @private */ - onAddNeverTranslateLanguagesClick_(e) { + private onAddNeverTranslateLanguagesClick_(e: Event) { e.preventDefault(); - this.addLanguagesDialogLanguages_ = this.languages.supported.filter( - language => !this.languages.neverTranslate.includes(language)); + this.addLanguagesDialogLanguages_ = this.languages!.supported.filter( + language => !this.languages!.neverTranslate.includes(language)); this.showAddNeverTranslateDialog_ = true; } - /** @private */ - onNeverTranslateDialogClose_() { + private onNeverTranslateDialogClose_() { this.showAddNeverTranslateDialog_ = false; this.addLanguagesDialogLanguages_ = null; focusWithoutInk( - assert(this.shadowRoot.querySelector('#addNeverTranslate'))); + assert(this.shadowRoot!.querySelector('#addNeverTranslate')!)); } - /** - * @param {!CustomEvent<!Array<string>>} e - * @private - */ - onNeverTranslateLanguagesAdded_(e) { + private onNeverTranslateLanguagesAdded_(e: CustomEvent<Array<string>>) { const languagesToAdd = e.detail; languagesToAdd.forEach(languageCode => { this.languageHelper.disableTranslateLanguage(languageCode); @@ -284,10 +258,9 @@ /** * Removes a language from the never translate languages list. - * @param {!Event} e - * @private */ - onRemoveNeverTranslateLanguageClick_(e) { + private onRemoveNeverTranslateLanguageClick_( + e: RepeaterEvent<chrome.languageSettingsPrivate.Language>) { const languageCode = e.model.item.code; this.languageHelper.enableTranslateLanguage(languageCode); } @@ -295,23 +268,19 @@ /** * Used to determine whether to show the separator between checkbox settings * and move buttons in the dialog menu. - * @return {boolean} True if there is currently more than one selected - * language. - * @private + * @return True if there is currently more than one selected language. */ - shouldShowDialogSeparator_() { + private shouldShowDialogSeparator_(): boolean { return this.languages !== undefined && this.languages.enabled.length > 1; } /** * Used to determine which "Move" buttons to show for ordering enabled * languages. - * @param {number} n - * @return {boolean} True if |language| is at the |n|th index in the list of - * enabled languages. - * @private + * @return True if |language| is at the |n|th index in the list of enabled + * languages. */ - isNthLanguage_(n) { + private isNthLanguage_(n: number): boolean { if (this.languages === undefined || this.detailLanguage_ === undefined) { return false; } @@ -325,41 +294,36 @@ } /** - * @return {boolean} True if the "Move to top" option for |language| should - * be visible. - * @private + * @return True if the "Move to top" option for |language| should be visible. */ - showMoveUp_() { + private showMoveUp_(): boolean { // "Move up" is a no-op for the top language, and redundant with // "Move to top" for the 2nd language. return !this.isNthLanguage_(0) && !this.isNthLanguage_(1); } /** - * @return {boolean} True if the "Move down" option for |language| should be - * visible. - * @private + * @return True if the "Move down" option for |language| should be visible. */ - showMoveDown_() { + private showMoveDown_(): boolean { return this.languages !== undefined && !this.isNthLanguage_(this.languages.enabled.length - 1); } /** - * @param {!Object} change Polymer change object for languages.enabled.*. - * @return {boolean} True if there are less than 2 languages. + * @return True if there are less than 2 languages. */ - isHelpTextHidden_(change) { + private isHelpTextHidden_(): boolean { return this.languages !== undefined && this.languages.enabled.length <= 1; } /** - * @param {string} languageCode The language code identifying a language. - * @param {string} translateTarget The target language. - * @return {string} 'target' if |languageCode| matches the target language, - 'non-target' otherwise. + * @param languageCode The language code identifying a language. + * @param translateTarget The target language. + * @return 'target' if |languageCode| matches the target language, + * 'non-target' otherwise. */ - isTranslationTarget_(languageCode, translateTarget) { + isTranslationTarget_(languageCode: string, translateTarget: string): string { if (this.languageHelper.convertLanguageCodeForTranslate(languageCode) === translateTarget) { return 'target'; @@ -368,38 +332,33 @@ } } - /** - * @param {!Event} e - * @private - */ - onTranslateToggleChange_(e) { + private onTranslateToggleChange_(e: Event) { this.languageSettingsMetricsProxy_.recordSettingsMetric( - e.target.checked ? + (e.target as SettingsToggleButtonElement).checked ? LanguageSettingsActionType.ENABLE_TRANSLATE_GLOBALLY : LanguageSettingsActionType.DISABLE_TRANSLATE_GLOBALLY); } // <if expr="is_win"> /** - * @param {string} languageCode The language code identifying a language. - * @param {string} prospectiveUILanguage The prospective UI language. - * @return {boolean} True if the prospective UI language is set to + * @param languageCode The language code identifying a language. + * @param prospectiveUILanguage The prospective UI language. + * @return True if the prospective UI language is set to * |languageCode| but requires a restart to take effect. - * @private */ - isRestartRequired_(languageCode, prospectiveUILanguage) { + private isRestartRequired_( + languageCode: string, prospectiveUILanguage: string): boolean { return prospectiveUILanguage === languageCode && this.languageHelper.requiresRestart(); } - /** @private */ - onCloseMenu_() { + private onCloseMenu_() { if (!this.isChangeInProgress_) { return; } flush(); this.isChangeInProgress_ = false; - const restartButton = this.shadowRoot.querySelector('#restartButton'); + const restartButton = this.shadowRoot!.querySelector('#restartButton'); if (!restartButton) { return; } @@ -407,13 +366,12 @@ } /** - * @param {!LanguageState} languageState - * @param {string} prospectiveUILanguage The chosen UI language. - * @return {boolean} True if the given language cannot be set as the + * @param prospectiveUILanguage The chosen UI language. + * @return True if the given language cannot be set as the * prospective UI language by the user. - * @private */ - disableUILanguageCheckbox_(languageState, prospectiveUILanguage) { + private disableUILanguageCheckbox_( + languageState: LanguageState, prospectiveUILanguage: string): boolean { if (this.detailLanguage_ === undefined) { return true; } @@ -441,17 +399,16 @@ /** * Handler for changes to the UI language checkbox. - * @param {!{target: !Element}} e - * @private */ - onUILanguageChange_(e) { + private onUILanguageChange_(e: Event) { // We don't support unchecking this checkbox. TODO(michaelpg): Ask for a // simpler widget. - assert(e.target.checked); + assert((e.target as CrCheckboxElement).checked); this.isChangeInProgress_ = true; this.languageHelper.setProspectiveUILanguage( - this.detailLanguage_.language.code); - this.languageHelper.moveLanguageToFront(this.detailLanguage_.language.code); + this.detailLanguage_!.language.code); + this.languageHelper.moveLanguageToFront( + this.detailLanguage_!.language.code); this.closeMenuSoon_(); } @@ -461,21 +418,20 @@ * language to use in Chrome) matches the current language. This pref is * used only on Chrome OS and Windows; we don't control the UI language * elsewhere. - * @param {string} languageCode The language code identifying a language. - * @param {string} prospectiveUILanguage The prospective UI language. - * @return {boolean} True if the given language matches the prospective UI - * pref (which may be different from the actual UI language). - * @private + * @param languageCode The language code identifying a language. + * @param prospectiveUILanguage The prospective UI language. + * @return True if the given language matches the prospective UI pref (which + * may be different from the actual UI language). */ - isProspectiveUILanguage_(languageCode, prospectiveUILanguage) { + private isProspectiveUILanguage_( + languageCode: string, prospectiveUILanguage: string): boolean { return languageCode === prospectiveUILanguage; } /** * Handler for the restart button. - * @private */ - onRestartTap_() { + private onRestartTap_() { // <if expr="is_win"> LifetimeBrowserProxyImpl.getInstance().restart(); // </if> @@ -483,12 +439,12 @@ // </if> /** - * @param {!LanguageState|undefined} languageState * @param {string} targetLanguageCode The default translate target language. - * @return {boolean} True if the translate checkbox should be disabled. - * @private + * @return True if the translate checkbox should be disabled. */ - disableTranslateCheckbox_(languageState, targetLanguageCode) { + private disableTranslateCheckbox_( + languageState: LanguageState|undefined, + targetLanguageCode: string): boolean { if (languageState === undefined || languageState.language === undefined || !languageState.language.supportsTranslate) { return true; @@ -504,20 +460,18 @@ /** * Handler for changes to the translate checkbox. - * @param {!{target: !Element}} e - * @private */ - onTranslateCheckboxChange_(e) { - if (e.target.checked) { + private onTranslateCheckboxChange_(e: Event) { + if ((e.target as CrCheckboxElement).checked) { this.languageHelper.enableTranslateLanguage( - this.detailLanguage_.language.code); + this.detailLanguage_!.language.code); this.languageSettingsMetricsProxy_.recordSettingsMetric( LanguageSettingsActionType.ENABLE_TRANSLATE_FOR_SINGLE_LANGUAGE); } else { this.languageHelper.disableTranslateLanguage( - this.detailLanguage_.language.code); + this.detailLanguage_!.language.code); this.languageSettingsMetricsProxy_.recordSettingsMetric( LanguageSettingsActionType.DISABLE_TRANSLATE_FOR_SINGLE_LANGUAGE); @@ -528,10 +482,8 @@ /** * Returns "complex" if the menu includes checkboxes, which should change * the spacing of items and show a separator in the menu. - * @param {boolean} translateEnabled - * @return {string} */ - getMenuClass_(translateEnabled) { + getMenuClass_(translateEnabled: boolean): string { if (translateEnabled || isWindows) { return 'complex'; } @@ -540,74 +492,63 @@ /** * Moves the language to the top of the list. - * @private */ - onMoveToTopTap_() { - /** @type {!CrActionMenuElement} */ ( - this.shadowRoot.querySelector('#menu').get()) - .close(); - if (this.detailLanguage_.isForced) { + private onMoveToTopTap_() { + this.$.menu.get().close(); + if (this.detailLanguage_!.isForced) { // If language is managed, show dialog to inform user it can't be modified this.showManagedLanguageDialog_ = true; return; } - this.languageHelper.moveLanguageToFront(this.detailLanguage_.language.code); + this.languageHelper.moveLanguageToFront( + this.detailLanguage_!.language.code); this.languageSettingsMetricsProxy_.recordSettingsMetric( LanguageSettingsActionType.LANGUAGE_LIST_REORDERED); } /** * Moves the language up in the list. - * @private */ - onMoveUpTap_() { - /** @type {!CrActionMenuElement} */ ( - this.shadowRoot.querySelector('#menu').get()) - .close(); - if (this.detailLanguage_.isForced) { + private onMoveUpTap_() { + this.$.menu.get().close(); + if (this.detailLanguage_!.isForced) { // If language is managed, show dialog to inform user it can't be modified this.showManagedLanguageDialog_ = true; return; } this.languageHelper.moveLanguage( - this.detailLanguage_.language.code, true /* upDirection */); + this.detailLanguage_!.language.code, true /* upDirection */); this.languageSettingsMetricsProxy_.recordSettingsMetric( LanguageSettingsActionType.LANGUAGE_LIST_REORDERED); } /** * Moves the language down in the list. - * @private */ - onMoveDownTap_() { - /** @type {!CrActionMenuElement} */ ( - this.shadowRoot.querySelector('#menu').get()) - .close(); - if (this.detailLanguage_.isForced) { + private onMoveDownTap_() { + this.$.menu.get().close(); + if (this.detailLanguage_!.isForced) { // If language is managed, show dialog to inform user it can't be modified this.showManagedLanguageDialog_ = true; return; } this.languageHelper.moveLanguage( - this.detailLanguage_.language.code, false /* upDirection */); + this.detailLanguage_!.language.code, false /* upDirection */); this.languageSettingsMetricsProxy_.recordSettingsMetric( LanguageSettingsActionType.LANGUAGE_LIST_REORDERED); } /** * Disables the language. - * @private */ - onRemoveLanguageTap_() { - /** @type {!CrActionMenuElement} */ ( - this.shadowRoot.querySelector('#menu').get()) - .close(); - if (this.detailLanguage_.isForced) { + private onRemoveLanguageTap_() { + this.$.menu.get().close(); + if (this.detailLanguage_!.isForced) { // If language is managed, show dialog to inform user it can't be modified this.showManagedLanguageDialog_ = true; return; } - this.languageHelper.disableLanguage(this.detailLanguage_.language.code); + this.languageHelper.disableLanguage(this.detailLanguage_!.language.code); this.languageSettingsMetricsProxy_.recordSettingsMetric( LanguageSettingsActionType.LANGUAGE_REMOVED); } @@ -616,39 +557,24 @@ * Returns either the "selected" class, if the language matches the * prospective UI language, or an empty string. Languages can only be * selected on Chrome OS and Windows. - * @param {string} languageCode The language code identifying a language. - * @param {string} prospectiveUILanguage The prospective UI language. - * @return {string} The class name for the language item. - * @private + * @param languageCode The language code identifying a language. + * @param prospectiveUILanguage The prospective UI language. + * @return The class name for the language item. */ - getLanguageItemClass_(languageCode, prospectiveUILanguage) { + private getLanguageItemClass_( + languageCode: string, prospectiveUILanguage: string): string { if (isWindows && languageCode === prospectiveUILanguage) { return 'selected'; } return ''; } - /** - * @param {!Event} e - * @private - */ - onDotsTap_(e) { + private onDotsTap_(e: RepeaterEvent<LanguageState>) { // Set a copy of the LanguageState object since it is not data-bound to // the languages model directly. - this.detailLanguage_ = /** @type {!LanguageState} */ (Object.assign( - {}, - /** @type {!{model: !{item: !LanguageState}}} */ (e).model.item)); + this.detailLanguage_ = Object.assign({}, e.model.item); - // Ensure the template has been stamped. - let menu = - /** @type {?CrActionMenuElement} */ ( - this.shadowRoot.querySelector('#menu').getIfExists()); - if (!menu) { - menu = /** @type {!CrActionMenuElement} */ ( - this.shadowRoot.querySelector('#menu').get()); - } - - menu.showAt(/** @type {!Element} */ (e.target)); + this.$.menu.get().showAt(e.target as HTMLElement); this.languageSettingsMetricsProxy_.recordPageImpressionMetric( LanguageSettingsPageImpressionType.LANGUAGE_OVERFLOW_MENU_OPENED); } @@ -656,11 +582,9 @@ /** * Closes the shared action menu after a short delay, so when a checkbox is * clicked it can be seen to change state before disappearing. - * @private */ - closeMenuSoon_() { - const menu = /** @type {!CrActionMenuElement} */ ( - this.shadowRoot.querySelector('#menu').get()); + private closeMenuSoon_() { + const menu = this.$.menu.get(); setTimeout(function() { if (menu.open) { menu.close(); @@ -670,31 +594,31 @@ /** * Triggered when the managed language dialog is dismissed. - * @private */ - onManagedLanguageDialogClosed_() { + private onManagedLanguageDialogClosed_() { this.showManagedLanguageDialog_ = false; } /** - * @param {Array<?>} list - * @return {boolean} Returns true if the list is non-null and has items. - * @private + * @return Whether the list is non-null and has items. */ - hasSome_(list) { + private hasSome_(list: Array<any>): boolean { return !!(list && list.length); } /** * Gets the list of languages that chrome can translate - * @private - * @returns {!Array<!chrome.languageSettingsPrivate.Language>} */ - getTranslatableLanguages_() { - return this.languages.supported.filter(language => { + private getTranslatableLanguages_(): + Array<chrome.languageSettingsPrivate.Language> { + return this.languages!.supported.filter(language => { return this.languageHelper.isLanguageTranslatable(language); }); } + + static get template() { + return html`{__html_template__}`; + } } customElements.define(
diff --git a/chrome/browser/resources/settings/lazy_load.ts b/chrome/browser/resources/settings/lazy_load.ts index eada7dd..67ca7d8 100644 --- a/chrome/browser/resources/settings/lazy_load.ts +++ b/chrome/browser/resources/settings/lazy_load.ts
@@ -107,7 +107,7 @@ export {CookieDetails, cookieInfo} from './site_settings/cookie_info.js'; export {SettingsEditExceptionDialogElement} from './site_settings/edit_exception_dialog.js'; export {LocalDataBrowserProxy, LocalDataBrowserProxyImpl, LocalDataItem} from './site_settings/local_data_browser_proxy.js'; -export {HandlerEntry, ProtocolEntry} from './site_settings/protocol_handlers.js'; +export {AppHandlerEntry, AppProtocolEntry, HandlerEntry, ProtocolEntry} from './site_settings/protocol_handlers.js'; export {SettingsCategoryDefaultRadioGroupElement} from './site_settings/settings_category_default_radio_group.js'; export {SiteListElement} from './site_settings/site_list.js'; export {ContentSettingProvider, DefaultContentSetting, RawChooserException, RawSiteException, RecentSitePermissions, SiteException, SiteGroup, SiteSettingsPrefsBrowserProxy, SiteSettingsPrefsBrowserProxyImpl, ZoomLevelEntry} from './site_settings/site_settings_prefs_browser_proxy.js';
diff --git a/chrome/browser/resources/settings/site_settings/protocol_handlers.html b/chrome/browser/resources/settings/site_settings/protocol_handlers.html index 618cd7a..d72e027 100644 --- a/chrome/browser/resources/settings/site_settings/protocol_handlers.html +++ b/chrome/browser/resources/settings/site_settings/protocol_handlers.html
@@ -16,6 +16,10 @@ padding-bottom: 10px; } + #appHandlerSubHeading { + padding-bottom: 10px; + } + settings-collapse-radio-button { --settings-collapse-toggle-min-height: var(--settings-row-min-height); } @@ -114,3 +118,31 @@ </template> </div> </template> + + <div class="column-header" hidden$="[[!showAppsProtocolHandlersTitle_]]"> + <h2>$i18n{siteSettingsAppProtocolHandlers}</h2> + </div> + + <div class="column-header" hidden$="[[!appApprovedProtocols.length]]"> + <div id="appHandlerSubHeading" class="secondary"> + $i18n{siteSettingsAppApprovedProtocolHandlersDescription} + </div> + </div> + + <template is="dom-repeat" items="[[appApprovedProtocols]]" as="appProtocol"> + <div class="column-header">[[appProtocol.protocol_display_name]]</div> + <div class="list-frame menu-content vertical-list"> + <template is="dom-repeat" items="[[appProtocol.handlers]]"> + <div class="list-item"> + <site-favicon url="[[item.host]]"></site-favicon> + <div class="middle protocol-host"> + <span class="url-directionality">[[item.host]]</span> + </div> + <cr-icon-button class="icon-clear" id="removeAppHandlerButton" + on-click="onRemoveAppApprovedHandlerButtonClick_" + title="$i18n{handlerRemove}"> + </cr-icon-button> + </div> + </template> + </div> + </template>
diff --git a/chrome/browser/resources/settings/site_settings/protocol_handlers.ts b/chrome/browser/resources/settings/site_settings/protocol_handlers.ts index a7dbd18..775c6ebe 100644 --- a/chrome/browser/resources/settings/site_settings/protocol_handlers.ts +++ b/chrome/browser/resources/settings/site_settings/protocol_handlers.ts
@@ -52,12 +52,33 @@ protocol_display_name: string, }; +export type AppHandlerEntry = { + host: string, + protocol: string, + protocol_display_name: string, + spec: string, + app_id: string, +}; + +export type AppProtocolEntry = { + handlers: Array<AppHandlerEntry>, + protocol: string, + protocol_display_name: string, +}; + + interface RepeaterEvent extends Event { model: { item: HandlerEntry, } } +interface AppRepeaterEvent extends Event { + model: { + item: AppHandlerEntry, + } +} + const ProtocolHandlersElementBase = mixinBehaviors( [WebUIListenerBehavior], SiteSettingsMixin(PolymerElement)) as { @@ -81,6 +102,19 @@ protocols: Array, /** + * Array of approved app protocols and their handlers. + */ + appApprovedProtocols: Array, + + /** + * Used to determine if the apps title should be shown. + */ + showAppsProtocolHandlersTitle_: { + type: Boolean, + value: false, + }, + + /** * The targeted object for menu operations. */ actionMenuModel_: Object, @@ -108,6 +142,8 @@ } protocols: Array<ProtocolEntry>; + appApprovedProtocols: Array<AppProtocolEntry>; + private showAppsProtocolHandlersTitle_: boolean; private actionMenuModel_: HandlerEntry|null; toggleOffLabel: string; toggleOnLabel: string; @@ -129,6 +165,12 @@ (ignoredProtocols: Array<HandlerEntry>) => this.setIgnoredProtocolHandlers_(ignoredProtocols)); this.browserProxy.observeProtocolHandlers(); + + // Web App Observer + this.addWebUIListener( + 'setAppApprovedProtocolHandlers', + this.setAppApprovedProtocolHandlers_.bind(this)); + this.browserProxy.observeAppProtocolHandlers(); } /** @@ -165,6 +207,17 @@ } /** + * Updates the list of approved app protocol handlers. + * @param appApprovedProtocols The new approved app protocol handler list. + */ + private setAppApprovedProtocolHandlers_(appApprovedProtocols: + Array<AppProtocolEntry>) { + this.appApprovedProtocols = appApprovedProtocols; + this.showAppsProtocolHandlersTitle_ = + (this.appApprovedProtocols && this.appApprovedProtocols.length > 0); + } + + /** * Closes action menu and resets action menu model */ private closeActionMenu_() { @@ -199,6 +252,15 @@ } /** + * Handler for removing web app protocol handlers that were approved. + */ + private onRemoveAppApprovedHandlerButtonClick_(event: AppRepeaterEvent) { + const item = event.model.item; + this.browserProxy.removeAppApprovedHandler( + item.protocol, item.spec, item.app_id); + } + + /** * Handler for removing handlers that were blocked */ private onRemoveIgnored_(event: RepeaterEvent) {
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.ts b/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.ts index 01572546b..80e1517a 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.ts +++ b/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.ts
@@ -327,6 +327,12 @@ observeProtocolHandlers(): void; /** + * observes _all_ of the the app protocol handler state, which includes a + * list that is returned through 'setAppApprovedProtocolHandlers' events. + */ + observeAppProtocolHandlers(): void; + + /** * Observes one aspect of the protocol handler so that updates to the * enabled/disabled state are sent. A 'setHandlersEnabled' will be sent * from C++ immediately after receiving this observe request and updates @@ -359,6 +365,14 @@ removeProtocolHandler(protocol: string, url: string): void; /** + * Deletes a protocol handler by url from the app approved list. + * @param protocol The protocol to delete the url from. + * @param url The url to delete. + * @param appId The web app's ID to delete. + */ + removeAppApprovedHandler(protocol: string, url: string, appId: string): void; + + /** * Fetches the incognito status of the current profile (whether an incognito * profile exists). Returns the results via onIncognitoStatusChanged. */ @@ -494,6 +508,10 @@ chrome.send('observeProtocolHandlers'); } + observeAppProtocolHandlers() { + chrome.send('observeAppProtocolHandlers'); + } + observeProtocolHandlersEnabledState() { chrome.send('observeProtocolHandlersEnabledState'); } @@ -510,6 +528,10 @@ chrome.send('removeHandler', [protocol, url]); } + removeAppApprovedHandler(protocol: string, url: string, appId: string) { + chrome.send('removeAppApprovedHandler', [protocol, url, appId]); + } + updateIncognitoStatus() { chrome.send('updateIncognitoStatus'); }
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index d531165..7785ab9 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -2580,10 +2580,12 @@ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url)); content::WebContents* old_tab = browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_EQ(main_url, old_tab->GetMainFrame()->GetLastCommittedURL()); - EXPECT_EQ(a_origin, old_tab->GetMainFrame()->GetLastCommittedOrigin()); - ASSERT_EQ(2u, old_tab->GetAllFrames().size()); - content::RenderFrameHost* subframe = old_tab->GetAllFrames()[1]; + content::RenderFrameHostWrapper old_tab_main_frame(old_tab->GetMainFrame()); + EXPECT_EQ(main_url, old_tab_main_frame->GetLastCommittedURL()); + EXPECT_EQ(a_origin, old_tab_main_frame->GetLastCommittedOrigin()); + content::RenderFrameHost* subframe = + ChildFrameAt(old_tab_main_frame.get(), 0); + ASSERT_TRUE(subframe); EXPECT_EQ(subframe_url, subframe->GetLastCommittedURL()); EXPECT_EQ(a_origin, subframe->GetLastCommittedOrigin()); @@ -2595,8 +2597,7 @@ content::ExecJs(old_tab, "window.open('about:blank', 'subframe');")); nav_observer.Wait(); } - ASSERT_EQ(2u, old_tab->GetAllFrames().size()); - EXPECT_EQ(subframe, old_tab->GetAllFrames()[1]); + EXPECT_EQ(subframe, ChildFrameAt(old_tab_main_frame.get(), 0)); EXPECT_EQ(GURL(url::kAboutBlankURL), subframe->GetLastCommittedURL()); EXPECT_EQ(a_origin, subframe->GetLastCommittedOrigin()); @@ -2610,8 +2611,8 @@ content::ExecJs(subframe, content::JsReplace("location = $1;", c_url))); nav_observer.Wait(); } - ASSERT_EQ(2u, old_tab->GetAllFrames().size()); - subframe = old_tab->GetAllFrames()[1]; + subframe = ChildFrameAt(old_tab_main_frame.get(), 0); + ASSERT_TRUE(subframe); EXPECT_EQ(c_url, subframe->GetLastCommittedURL()); EXPECT_EQ(c_origin, subframe->GetLastCommittedOrigin()); @@ -2625,17 +2626,18 @@ ASSERT_TRUE(new_tab->GetController().CanGoBack()); old_tab = nullptr; + content::RenderFrameHost* new_tab_main_frame = new_tab->GetMainFrame(); // Verify that the restored tab hosts: a.com(c.com). - EXPECT_EQ(main_url, new_tab->GetMainFrame()->GetLastCommittedURL()); - EXPECT_EQ(a_origin, new_tab->GetMainFrame()->GetLastCommittedOrigin()); - ASSERT_EQ(2u, new_tab->GetAllFrames().size()); - subframe = new_tab->GetAllFrames()[1]; + EXPECT_EQ(main_url, new_tab_main_frame->GetLastCommittedURL()); + EXPECT_EQ(a_origin, new_tab_main_frame->GetLastCommittedOrigin()); + subframe = ChildFrameAt(new_tab_main_frame, 0); + ASSERT_TRUE(subframe); EXPECT_EQ(c_url, subframe->GetLastCommittedURL()); EXPECT_EQ(c_origin, subframe->GetLastCommittedOrigin()); // Check that main frame and subframe are in the same BrowsingInstance. content::SiteInstance* subframe_instance_c = subframe->GetSiteInstance(); - EXPECT_TRUE(new_tab->GetMainFrame()->GetSiteInstance()->IsRelatedSiteInstance( + EXPECT_TRUE(new_tab_main_frame->GetSiteInstance()->IsRelatedSiteInstance( subframe_instance_c)); // Go back - this should reach: a.com(a.com-blank). @@ -2644,13 +2646,13 @@ new_tab->GetController().GoBack(); nav_observer.Wait(); } - ASSERT_EQ(2u, new_tab->GetAllFrames().size()); - subframe = new_tab->GetAllFrames()[1]; + subframe = ChildFrameAt(new_tab_main_frame, 0); + ASSERT_TRUE(subframe); EXPECT_EQ(GURL(url::kAboutBlankURL), subframe->GetLastCommittedURL()); EXPECT_EQ(a_origin, subframe->GetLastCommittedOrigin()); // Check that we're still in the same BrowsingInstance. - EXPECT_TRUE(new_tab->GetMainFrame()->GetSiteInstance()->IsRelatedSiteInstance( + EXPECT_TRUE(new_tab_main_frame->GetSiteInstance()->IsRelatedSiteInstance( subframe->GetSiteInstance())); EXPECT_TRUE( subframe_instance_c->IsRelatedSiteInstance(subframe->GetSiteInstance()));
diff --git a/chrome/browser/signin/ui/android/BUILD.gn b/chrome/browser/signin/ui/android/BUILD.gn index 3f432f7..25fb8811 100644 --- a/chrome/browser/signin/ui/android/BUILD.gn +++ b/chrome/browser/signin/ui/android/BUILD.gn
@@ -66,10 +66,10 @@ "java/src/org/chromium/chrome/browser/signin/ui/account_picker/ExistingAccountRowViewBinder.java", "java/src/org/chromium/chrome/browser/signin/ui/account_picker/OnClickListenerViewBinder.java", "java/src/org/chromium/chrome/browser/signin/ui/fre/FreUMADialogCoordinator.java", - "java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupCoordinator.java", - "java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupMediator.java", - "java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupProperties.java", - "java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupViewBinder.java", + "java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunCoordinator.java", + "java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunMediator.java", + "java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunProperties.java", + "java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunViewBinder.java", ] resources_package = "org.chromium.chrome.browser.signin.ui" }
diff --git a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupCoordinator.java b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunCoordinator.java similarity index 77% rename from chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupCoordinator.java rename to chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunCoordinator.java index db79d90a..87cffab 100644 --- a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupCoordinator.java +++ b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunCoordinator.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.signin.ui.frebottomgroup; +package org.chromium.chrome.browser.signin.ui.fre; import android.content.Context; import android.view.View; @@ -14,12 +14,11 @@ import org.chromium.ui.modelutil.PropertyModelChangeProcessor; /** - * The coordinator handles the update and interaction of the bottom group of the FRE sign-in - * screen. It is composed of a selected account, a continue button and a dismiss button. + * The coordinator handles the update and interaction of the FRE sign-in screen. */ @MainThread -public class FREBottomGroupCoordinator { - /** Listener for FREBottomGroup. */ +public class SigninFirstRunCoordinator { + /** Listener for srignin fist run MVC. */ public interface Listener { /** Notifies when the user clicked the "add account" button. */ void addAccount(); @@ -28,7 +27,7 @@ void advanceToNextPage(); } - private final FREBottomGroupMediator mMediator; + private final SigninFirstRunMediator mMediator; /** * Constructs a coordinator instance. @@ -39,11 +38,11 @@ * @param modalDialogManager is used to open dialogs like account picker dialog and uma dialog. * @param listener is invoked to interact with classes outside the module. */ - public FREBottomGroupCoordinator( + public SigninFirstRunCoordinator( Context context, View view, ModalDialogManager modalDialogManager, Listener listener) { - mMediator = new FREBottomGroupMediator(context, modalDialogManager, listener); + mMediator = new SigninFirstRunMediator(context, modalDialogManager, listener); PropertyModelChangeProcessor.create( - mMediator.getModel(), view, FREBottomGroupViewBinder::bind); + mMediator.getModel(), view, SigninFirstRunViewBinder::bind); } /**
diff --git a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupMediator.java b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunMediator.java similarity index 85% rename from chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupMediator.java rename to chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunMediator.java index 765148ec..f713460 100644 --- a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupMediator.java +++ b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunMediator.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.signin.ui.frebottomgroup; +package org.chromium.chrome.browser.signin.ui.fre; import android.accounts.Account; import android.content.Context; @@ -16,8 +16,8 @@ import org.chromium.chrome.browser.signin.ui.R; import org.chromium.chrome.browser.signin.ui.account_picker.AccountPickerCoordinator; import org.chromium.chrome.browser.signin.ui.account_picker.AccountPickerDialogCoordinator; -import org.chromium.chrome.browser.signin.ui.frebottomgroup.FREBottomGroupCoordinator.Listener; -import org.chromium.chrome.browser.signin.ui.frebottomgroup.FREBottomGroupProperties.FrePolicy; +import org.chromium.chrome.browser.signin.ui.fre.SigninFirstRunCoordinator.Listener; +import org.chromium.chrome.browser.signin.ui.fre.SigninFirstRunProperties.FrePolicy; import org.chromium.components.signin.AccountManagerFacade; import org.chromium.components.signin.AccountManagerFacadeProvider; import org.chromium.components.signin.AccountUtils; @@ -30,7 +30,7 @@ import java.util.List; -class FREBottomGroupMediator implements AccountsChangeObserver, ProfileDataCache.Observer, +class SigninFirstRunMediator implements AccountsChangeObserver, ProfileDataCache.Observer, AccountPickerCoordinator.Listener { private final Context mContext; private final ModalDialogManager mModalDialogManager; @@ -41,13 +41,13 @@ private AccountPickerDialogCoordinator mDialogCoordinator; private String mSelectedAccountName; - FREBottomGroupMediator( + SigninFirstRunMediator( Context context, ModalDialogManager modalDialogManager, Listener listener) { mContext = context; mModalDialogManager = modalDialogManager; mListener = listener; mProfileDataCache = ProfileDataCache.createWithDefaultImageSizeAndNoBadge(mContext); - mModel = FREBottomGroupProperties.createModel( + mModel = SigninFirstRunProperties.createModel( this::onSelectedAccountClicked, this::onContinueAsClicked, this::onDismissClicked); mProfileDataCache.addObserver(this); @@ -68,8 +68,8 @@ } void onNativeAndPolicyLoaded(boolean hasPolicies) { - mModel.set(FREBottomGroupProperties.ARE_NATIVE_AND_POLICY_LOADED, true); - mModel.set(FREBottomGroupProperties.FRE_POLICY, hasPolicies ? new FrePolicy() : null); + mModel.set(SigninFirstRunProperties.ARE_NATIVE_AND_POLICY_LOADED, true); + mModel.set(SigninFirstRunProperties.FRE_POLICY, hasPolicies ? new FrePolicy() : null); } /** @@ -101,7 +101,7 @@ /** * Callback for the PropertyKey - * {@link FREBottomGroupProperties#ON_SELECTED_ACCOUNT_CLICKED}. + * {@link SigninFirstRunProperties#ON_SELECTED_ACCOUNT_CLICKED}. */ private void onSelectedAccountClicked() { mDialogCoordinator = @@ -109,17 +109,17 @@ } /** - * Callback for the PropertyKey {@link FREBottomGroupProperties#ON_CONTINUE_AS_CLICKED}. + * Callback for the PropertyKey {@link SigninFirstRunProperties#ON_CONTINUE_AS_CLICKED}. */ private void onContinueAsClicked() { if (mSelectedAccountName == null) { mListener.addAccount(); return; - } else if (mModel.get(FREBottomGroupProperties.IS_SELECTED_ACCOUNT_SUPERVISED)) { + } else if (mModel.get(SigninFirstRunProperties.IS_SELECTED_ACCOUNT_SUPERVISED)) { mListener.advanceToNextPage(); return; } - assert mModel.get(FREBottomGroupProperties.ARE_NATIVE_AND_POLICY_LOADED) + assert mModel.get(SigninFirstRunProperties.ARE_NATIVE_AND_POLICY_LOADED) : "The continue button shouldn't be visible before the native is not initialized!"; if (IdentityServicesProvider.get() .getIdentityManager(Profile.getLastUsedRegularProfile()) @@ -145,10 +145,10 @@ } /** - * Callback for the PropertyKey {@link FREBottomGroupProperties#ON_DISMISS_CLICKED}. + * Callback for the PropertyKey {@link SigninFirstRunProperties#ON_DISMISS_CLICKED}. */ private void onDismissClicked() { - assert mModel.get(FREBottomGroupProperties.ARE_NATIVE_AND_POLICY_LOADED) + assert mModel.get(SigninFirstRunProperties.ARE_NATIVE_AND_POLICY_LOADED) : "The dismiss button shouldn't be visible before the native is not initialized!"; if (IdentityServicesProvider.get() .getIdentityManager(Profile.getLastUsedRegularProfile()) @@ -169,7 +169,7 @@ private void updateSelectedAccountData(String accountEmail) { if (TextUtils.equals(mSelectedAccountName, accountEmail)) { - mModel.set(FREBottomGroupProperties.SELECTED_ACCOUNT_DATA, + mModel.set(SigninFirstRunProperties.SELECTED_ACCOUNT_DATA, mProfileDataCache.getProfileDataOrDefault(accountEmail)); } } @@ -177,7 +177,7 @@ private void updateAccounts(List<Account> accounts) { if (accounts.isEmpty()) { mSelectedAccountName = null; - mModel.set(FREBottomGroupProperties.SELECTED_ACCOUNT_DATA, null); + mModel.set(SigninFirstRunProperties.SELECTED_ACCOUNT_DATA, null); } else if (mSelectedAccountName == null || AccountUtils.findAccountByName(accounts, mSelectedAccountName) == null) { setSelectedAccountName(accounts.get(0).name); @@ -186,7 +186,7 @@ if (accounts.size() == 1) { mAccountManagerFacade.checkChildAccountStatus(accounts.get(0), status -> { final boolean isChild = ChildAccountStatus.isChild(status); - mModel.set(FREBottomGroupProperties.IS_SELECTED_ACCOUNT_SUPERVISED, isChild); + mModel.set(SigninFirstRunProperties.IS_SELECTED_ACCOUNT_SUPERVISED, isChild); if (isChild && mDialogCoordinator != null) { mDialogCoordinator.dismissDialog(); } @@ -195,7 +195,7 @@ }); } else { mProfileDataCache.setBadge(0); - mModel.set(FREBottomGroupProperties.IS_SELECTED_ACCOUNT_SUPERVISED, false); + mModel.set(SigninFirstRunProperties.IS_SELECTED_ACCOUNT_SUPERVISED, false); } } } \ No newline at end of file
diff --git a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupProperties.java b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunProperties.java similarity index 95% rename from chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupProperties.java rename to chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunProperties.java index dbde817..aec859e7 100644 --- a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupProperties.java +++ b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunProperties.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.signin.ui.frebottomgroup; +package org.chromium.chrome.browser.signin.ui.fre; import android.view.View.OnClickListener; @@ -13,7 +13,7 @@ import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey; -class FREBottomGroupProperties { +class SigninFirstRunProperties { /** This class regroups the policies supported by FRE. */ static class FrePolicy { // TODO(crbug/1246960): Support the policy |BrowserSignin| @@ -66,5 +66,5 @@ .build(); } - private FREBottomGroupProperties() {} + private SigninFirstRunProperties() {} }
diff --git a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupViewBinder.java b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunViewBinder.java similarity index 76% rename from chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupViewBinder.java rename to chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunViewBinder.java index 84f3f18..33a4904 100644 --- a/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/frebottomgroup/FREBottomGroupViewBinder.java +++ b/chrome/browser/signin/ui/android/java/src/org/chromium/chrome/browser/signin/ui/fre/SigninFirstRunViewBinder.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser.signin.ui.frebottomgroup; +package org.chromium.chrome.browser.signin.ui.fre; import android.view.View; @@ -19,21 +19,21 @@ * Stateless FREBottomGroup view binder. * TODO(crbug/1248083): Create a customised view class for the view here */ -class FREBottomGroupViewBinder { +class SigninFirstRunViewBinder { static void bind(PropertyModel model, View view, PropertyKey propertyKey) { - if (propertyKey == FREBottomGroupProperties.ON_CONTINUE_AS_CLICKED) { + if (propertyKey == SigninFirstRunProperties.ON_CONTINUE_AS_CLICKED) { view.findViewById(R.id.signin_fre_continue_button) - .setOnClickListener(model.get(FREBottomGroupProperties.ON_CONTINUE_AS_CLICKED)); - } else if (propertyKey == FREBottomGroupProperties.ON_DISMISS_CLICKED) { + .setOnClickListener(model.get(SigninFirstRunProperties.ON_CONTINUE_AS_CLICKED)); + } else if (propertyKey == SigninFirstRunProperties.ON_DISMISS_CLICKED) { view.findViewById(R.id.signin_fre_dismiss_button) - .setOnClickListener(model.get(FREBottomGroupProperties.ON_DISMISS_CLICKED)); - } else if (propertyKey == FREBottomGroupProperties.ON_SELECTED_ACCOUNT_CLICKED) { + .setOnClickListener(model.get(SigninFirstRunProperties.ON_DISMISS_CLICKED)); + } else if (propertyKey == SigninFirstRunProperties.ON_SELECTED_ACCOUNT_CLICKED) { view.findViewById(R.id.signin_fre_selected_account) .setOnClickListener( - model.get(FREBottomGroupProperties.ON_SELECTED_ACCOUNT_CLICKED)); - } else if (propertyKey == FREBottomGroupProperties.SELECTED_ACCOUNT_DATA) { + model.get(SigninFirstRunProperties.ON_SELECTED_ACCOUNT_CLICKED)); + } else if (propertyKey == SigninFirstRunProperties.SELECTED_ACCOUNT_DATA) { final @Nullable DisplayableProfileData profileData = - model.get(FREBottomGroupProperties.SELECTED_ACCOUNT_DATA); + model.get(SigninFirstRunProperties.SELECTED_ACCOUNT_DATA); if (profileData == null) { ButtonCompat button = view.findViewById(R.id.signin_fre_continue_button); button.setText(R.string.signin_add_account_to_device); @@ -45,17 +45,17 @@ profileData.getGivenNameOrFullNameOrEmail())); } updateVisibility(view, model); - } else if (propertyKey == FREBottomGroupProperties.IS_SELECTED_ACCOUNT_SUPERVISED) { + } else if (propertyKey == SigninFirstRunProperties.IS_SELECTED_ACCOUNT_SUPERVISED) { final boolean isSelectedAccountSupervised = - model.get(FREBottomGroupProperties.IS_SELECTED_ACCOUNT_SUPERVISED); + model.get(SigninFirstRunProperties.IS_SELECTED_ACCOUNT_SUPERVISED); view.findViewById(R.id.signin_fre_selected_account) .setEnabled(!isSelectedAccountSupervised); updateVisibility(view, model); - } else if (propertyKey == FREBottomGroupProperties.ARE_NATIVE_AND_POLICY_LOADED) { + } else if (propertyKey == SigninFirstRunProperties.ARE_NATIVE_AND_POLICY_LOADED) { updateVisibility(view, model); - } else if (propertyKey == FREBottomGroupProperties.FRE_POLICY) { + } else if (propertyKey == SigninFirstRunProperties.FRE_POLICY) { view.findViewById(R.id.fre_browser_managed_by_organization) - .setVisibility(model.get(FREBottomGroupProperties.FRE_POLICY) != null + .setVisibility(model.get(SigninFirstRunProperties.FRE_POLICY) != null ? View.VISIBLE : View.GONE); } else { @@ -65,18 +65,18 @@ private static void updateVisibility(View view, PropertyModel model) { final boolean areNativeAndPolicyLoaded = - model.get(FREBottomGroupProperties.ARE_NATIVE_AND_POLICY_LOADED); + model.get(SigninFirstRunProperties.ARE_NATIVE_AND_POLICY_LOADED); view.findViewById(R.id.signin_fre_progress_spinner) .setVisibility(areNativeAndPolicyLoaded ? View.GONE : View.VISIBLE); if (areNativeAndPolicyLoaded) { view.findViewById(R.id.signin_fre_selected_account) - .setVisibility(model.get(FREBottomGroupProperties.SELECTED_ACCOUNT_DATA) == null + .setVisibility(model.get(SigninFirstRunProperties.SELECTED_ACCOUNT_DATA) == null ? View.GONE : View.VISIBLE); view.findViewById(R.id.signin_fre_dismiss_button) .setVisibility( - model.get(FREBottomGroupProperties.IS_SELECTED_ACCOUNT_SUPERVISED) + model.get(SigninFirstRunProperties.IS_SELECTED_ACCOUNT_SUPERVISED) ? View.GONE : View.VISIBLE); } else { @@ -88,5 +88,5 @@ view.findViewById(R.id.signin_fre_footer).setVisibility(otherElementsVisibility); } - private FREBottomGroupViewBinder() {} + private SigninFirstRunViewBinder() {} }
diff --git a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc index 78ee687..268d082 100644 --- a/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc +++ b/chrome/browser/site_isolation/site_per_process_interactive_browsertest.cc
@@ -1571,8 +1571,8 @@ content::WebContents* old_contents = browser()->tab_strip_model()->GetWebContentsAt(0); ASSERT_TRUE(NavigateIframeToURL(old_contents, "test", subframe_url)); - EXPECT_LE(2u, old_contents->GetAllFrames().size()); - content::RenderFrameHost* subframe = old_contents->GetAllFrames()[1]; + content::RenderFrameHost* subframe = ChildFrameAt(old_contents, 0); + ASSERT_TRUE(subframe); EXPECT_EQ(subframe_url, subframe->GetLastCommittedURL()); // Simulate the ctrl-return to open the anchor's link in a new background tab.
diff --git a/chrome/browser/tab_contents/view_source_browsertest.cc b/chrome/browser/tab_contents/view_source_browsertest.cc index 497d9381a..81ccdab5 100644 --- a/chrome/browser/tab_contents/view_source_browsertest.cc +++ b/chrome/browser/tab_contents/view_source_browsertest.cc
@@ -258,9 +258,9 @@ browser()->tab_strip_model()->GetActiveWebContents(); content::RenderFrameHost* original_main_frame = original_contents->GetMainFrame(); - ASSERT_LE(2u, original_contents->GetAllFrames().size()); content::RenderFrameHost* original_child_frame = - original_contents->GetAllFrames()[1]; + ChildFrameAt(original_main_frame, 0); + ASSERT_TRUE(original_child_frame); // Do a sanity check that in this particular test page the main frame and the // subframe are cross-site. @@ -520,9 +520,9 @@ "b.com", "/form_that_posts_to_echoall.html")); EXPECT_TRUE( content::NavigateIframeToURL(original_contents, "frame1", form_url)); - EXPECT_LE(2u, original_contents->GetAllFrames().size()); content::RenderFrameHost* original_child_frame = - original_contents->GetAllFrames()[1]; + ChildFrameAt(original_contents, 0); + ASSERT_TRUE(original_child_frame); // Submit the form and verify that we arrived at the expected location. content::TestNavigationObserver form_post_observer(original_contents, 1); @@ -643,7 +643,7 @@ // 3. View-source the subframe content::WebContentsAddedObserver view_source_contents_observer; - original_contents->GetAllFrames()[1]->ViewSource(); + ChildFrameAt(original_contents, 0)->ViewSource(); content::WebContents* view_source_contents = view_source_contents_observer.GetWebContents(); EXPECT_TRUE(WaitForLoadStop(view_source_contents));
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc index d136076..0ef9f61c 100644 --- a/chrome/browser/task_manager/task_manager_browsertest.cc +++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -1022,7 +1022,7 @@ // https://crbug.com/642958 wouldn't repro in presence of process swaps). navigation_observer.Wait(); auto* b_frame = - browser()->tab_strip_model()->GetActiveWebContents()->GetAllFrames()[1]; + ChildFrameAt(browser()->tab_strip_model()->GetActiveWebContents(), 0); GURL b_url = b_frame->GetLastCommittedURL(); ASSERT_EQ(b_url.host(), "b.com"); // Sanity check of test code / setup. ASSERT_TRUE(b_frame->GetSiteInstance()->RequiresDedicatedProcess());
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb index 0a3fabe..6d04dcb7 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_gu.xtb
@@ -66,6 +66,7 @@ <translation id="1360432990279830238">સાઇન આઉટ કરી સિંકનો વિકલ્પ બંધ કરવો છે?</translation> <translation id="1373696734384179344">પસંદ કરેલ કન્ટેન્ટ ડાઉનલોડ કરવા માટે મેમરી અપૂરતી છે.</translation> <translation id="1376578503827013741">ગણતરી કરી રહ્યાં છે…</translation> +<translation id="1382912999714108023">તમારી હાલની માહિતી દેખાઈ રહી નથી? તેને અપડેટ કરવા માટે, કૃપા કરીને તમારી બેંકનો સંપર્ક કરો.</translation> <translation id="1383876407941801731">શોધો</translation> <translation id="1384704387250346179">Google Lensથી છબીનો અનુવાદ કરો <ph name="BEGIN_NEW" />નવું<ph name="END_NEW" /></translation> <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> દિવસ પહેલાં સક્રિય હતું</translation> @@ -351,6 +352,7 @@ <translation id="3214996641768123781">જ્યારે તમે સાઇન ઇન કર્યુ હોય, ત્યારે તમારા Google એકાઉન્ટમાં <ph name="BEGIN_LINK1" />શોધ ઇતિહાસ<ph name="END_LINK1" /> અને <ph name="BEGIN_LINK2" />પ્રવૃત્તિના અન્ય પ્રકારો<ph name="END_LINK2" /> સાચવવામાં આવી શકે છે. તમે તેમને કોઈપણ સમયે ડિલીટ કરી શકો છો.</translation> <translation id="321773570071367578">જો તમે તમારો પાસફ્રેઝ ભૂલી ગયાં હોવ અથવા આ સેટિંગ બદલવા માંગતા હોવ, તો <ph name="BEGIN_LINK" />સમન્વયનને ફરીથી સેટ કરો<ph name="END_LINK" /></translation> <translation id="3220943972464248773">તમારો પાસવર્ડ સિંક કરવા માટે, આ તમે જ છો તેની ચકાસણી કરો</translation> +<translation id="3223522355830797639">તમારી બેંક કન્ફર્મ કરવા માગે છે કે તે તમે જ છો.</translation> <translation id="3227557059438308877">સિક્યુરિટી કી તરીકે Google Chrome</translation> <translation id="3232754137068452469">વેબ ઍપ</translation> <translation id="3234978181857588512">ડિવાઇસમાં સાચવો</translation> @@ -817,6 +819,7 @@ <translation id="605721222689873409">YY</translation> <translation id="6059830886158432458">તમારી સ્ટોરી અને પ્રવૃત્તિને અહીં નિયંત્રિત કરો</translation> <translation id="6069177176307973611">પ્રાઇવસી અને સુરક્ષા માટેના સેટિંગનો રિવ્યૂ કરો</translation> +<translation id="6070730414166672373">તમારી બેંકનો સંપર્ક કરી રહ્યાં છીએ</translation> <translation id="6085886413119427067">સુરક્ષિત કનેક્શન પર વેબસાઇટ સાથે કેવી રીતે કનેક્ટ કરવું તે નક્કી કરે છે</translation> <translation id="60923314841986378"><ph name="HOURS" /> કલાક બાકી</translation> <translation id="6108923351542677676">સેટઅપની પ્રક્રિયા ચાલુ છે...</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb index 5134109..a073f15f 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ja.xtb
@@ -66,6 +66,7 @@ <translation id="1360432990279830238">ログアウトして同期をオフにしますか?</translation> <translation id="1373696734384179344">選択したコンテンツをダウンロードするにはメモリが不足しています。</translation> <translation id="1376578503827013741">計算中...</translation> +<translation id="1382912999714108023">現在の情報が表示されていない場合は、カード発行会社に連絡して更新してください。</translation> <translation id="1383876407941801731">検索</translation> <translation id="1384704387250346179">Google レンズで画像を翻訳 <ph name="BEGIN_NEW" />New<ph name="END_NEW" /></translation> <translation id="1386674309198842382">最終同期: <ph name="LAST_UPDATED" /> 日前</translation> @@ -351,6 +352,7 @@ <translation id="3214996641768123781">ログイン中は Google アカウントに<ph name="BEGIN_LINK1" />検索履歴<ph name="END_LINK1" />や<ph name="BEGIN_LINK2" />その他のアクティビティ<ph name="END_LINK2" />が保存される可能性があります。これらのデータはいつでも削除できます。</translation> <translation id="321773570071367578">パスフレーズを忘れた場合や、この設定を変更する場合は、<ph name="BEGIN_LINK" />同期をリセット<ph name="END_LINK" />します</translation> <translation id="3220943972464248773">パスワードを同期するには、本人確認を行ってください</translation> +<translation id="3223522355830797639">ご利用の銀行またはカード発行会社が本人確認をもとめています。</translation> <translation id="3227557059438308877">Google Chrome をセキュリティ キーとして使用</translation> <translation id="3232754137068452469">ウェブアプリ</translation> <translation id="3234978181857588512">デバイスに保存</translation> @@ -817,6 +819,7 @@ <translation id="605721222689873409">YY</translation> <translation id="6059830886158432458">ここで記事やアクティビティを管理します</translation> <translation id="6069177176307973611">プライバシーとセキュリティの設定を確認します</translation> +<translation id="6070730414166672373">カード発行会社に問い合わせています…</translation> <translation id="6085886413119427067">ウェブサイトに安全に接続する方法を決定します</translation> <translation id="60923314841986378">残り <ph name="HOURS" /> 時間</translation> <translation id="6108923351542677676">設定しています...</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 b6bd2cd..fb58919b 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
@@ -1090,7 +1090,7 @@ <translation id="7606077192958116810">'အပေါ့စားမုဒ်' ဖွင့်ထားသည်။ 'ဆက်တင်များ' တွင် စီမံခန့်ခွဲပါ။</translation> <translation id="7612619742409846846">အဖြစ် Google သို့လက်မှတ်ထိုးဝင်ရန်</translation> <translation id="7619072057915878432"><ph name="FILE_NAME" /> ဒေါင်းလုဒ်မှာ ကွန်ရက် ပြဿနာများကြောင့် မအောင်မြင်ခဲ့ပါ။</translation> -<translation id="7626032353295482388">Chrome မှ ကြိုဆိုပါသည်</translation> +<translation id="7626032353295482388">Chrome က ကြိုဆိုပါသည်</translation> <translation id="7630202231528827509">ပံ့ပိုးသူ URL</translation> <translation id="7638584964844754484">စကားဝှက် မမှန်</translation> <translation id="7641339528570811325">ဖွင့်ကြည့်ထားသည့် မှတ်တမ်းဒေတာများကို ရှင်းလင်းရန်…</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb index 350f449..3af37e9 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_ta.xtb
@@ -66,6 +66,7 @@ <translation id="1360432990279830238">வெளியேறி, ஒத்திசைவை முடக்கவா?</translation> <translation id="1373696734384179344">தேர்ந்தெடுத்ததைப் பதிவிறக்க, போதுமான நினைவகம் இல்லை.</translation> <translation id="1376578503827013741">கணக்கிடுகிறது…</translation> +<translation id="1382912999714108023">சமீபத்திய தகவல்கள் காட்டப்படவில்லையா? பேங்கைத் தொடர்புகொண்டு அவற்றைச் சேர்க்குமாறு கேட்கவும்.</translation> <translation id="1383876407941801731">Search</translation> <translation id="1384704387250346179">படத்திலுள்ளதை Google Lens மூலம் மொழிபெயர் <ph name="BEGIN_NEW" />புதிது<ph name="END_NEW" /></translation> <translation id="1386674309198842382"><ph name="LAST_UPDATED" /> நாட்களுக்கு முன் பயன்படுத்தியுள்ளார்</translation> @@ -351,6 +352,7 @@ <translation id="3214996641768123781">நீங்கள் உள்நுழைந்திருக்கும்போது <ph name="BEGIN_LINK1" />தேடல் விவரங்களும்<ph name="END_LINK1" /> <ph name="BEGIN_LINK2" />பிற வகையான செயல்பாடுகளும்<ph name="END_LINK2" /> உங்கள் Google கணக்கில் சேமிக்கப்பட்டிருக்கலாம். அவற்றை எப்போது வேண்டுமானாலும் நீக்கலாம்.</translation> <translation id="321773570071367578">கடவுச்சொற்றொடரை மறந்துவிட்டால் அல்லது இந்த அமைப்பை மாற்ற விரும்பினால், <ph name="BEGIN_LINK" />ஒத்திசைவை மீட்டமைக்கவும்<ph name="END_LINK" /></translation> <translation id="3220943972464248773">கடவுச்சொற்களை ஒத்திசைக்க இது நீங்கள்தான் என உறுதிசெய்யவும்</translation> +<translation id="3223522355830797639">இது நீங்கள்தான் என்பதை பேங்க் உறுதிசெய்ய விரும்புகிறது.</translation> <translation id="3227557059438308877">Google Chromeமைப் பாதுகாப்பு விசையாகப் பயன்படுத்தும் வசதி</translation> <translation id="3232754137068452469">இணைய ஆப்ஸ்</translation> <translation id="3234978181857588512">சாதனத்தில் சேமி</translation> @@ -817,6 +819,7 @@ <translation id="605721222689873409">YY</translation> <translation id="6059830886158432458">உங்கள் செய்திகளையும் செயல்பாட்டையும் இங்கே கட்டுப்படுத்தலாம்</translation> <translation id="6069177176307973611">தனியுரிமை & பாதுகாப்பு அமைப்புகளைப் பார்க்கலாம் மாற்றலாம்</translation> +<translation id="6070730414166672373">பேங்கைத் தொடர்புகொள்கிறோம்\u2026</translation> <translation id="6085886413119427067">பாதுகாப்பான இணைப்பின் மூலம் இணையதளங்களில் இணைவது எப்படி என்பதைக் கண்டறியும்</translation> <translation id="60923314841986378"><ph name="HOURS" /> மணிநேரம் மீதமுள்ளது</translation> <translation id="6108923351542677676">அமைவு செயலிலுள்ளது...</translation>
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h index 7d09374..8ce4f31f 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h
@@ -413,7 +413,7 @@ bool IsDefaultPackage(const std::string& package_name) const; private: - friend class ChromeShelfControllerTest; + friend class ChromeShelfControllerTestBase; friend class ArcAppModelBuilderTest; friend class app_list::ArcAppShortcutsSearchProviderTest;
diff --git a/chrome/browser/ui/ash/chrome_shelf_prefs.cc b/chrome/browser/ui/ash/chrome_shelf_prefs.cc index ac28f56..2bffcd2 100644 --- a/chrome/browser/ui/ash/chrome_shelf_prefs.cc +++ b/chrome/browser/ui/ash/chrome_shelf_prefs.cc
@@ -164,7 +164,7 @@ // If App sync is not yet started, don't apply default pin apps once synced // apps is likely override it. There is a case when App sync is disabled and // in last case local cache is available immediately. - if (chromeos::features::IsSplitSettingsSyncEnabled()) { + if (chromeos::features::IsSyncSettingsCategorizationEnabled()) { if (settings->IsOsSyncFeatureEnabled() && settings->GetSelectedOsTypes().Has(UserSelectableOsType::kOsApps) && !app_list::AppListSyncableServiceFactory::GetForProfile(profile) @@ -182,7 +182,7 @@ // If shelf pin layout rolls preference is not started yet then we cannot say // if we rolled layout or not. - if (chromeos::features::IsSplitSettingsSyncEnabled()) { + if (chromeos::features::IsSyncSettingsCategorizationEnabled()) { if (settings->IsOsSyncFeatureEnabled() && settings->GetSelectedOsTypes().Has( UserSelectableOsType::kOsPreferences) &&
diff --git a/chrome/browser/ui/ash/chrome_shelf_prefs.h b/chrome/browser/ui/ash/chrome_shelf_prefs.h index b196028..4f750fa 100644 --- a/chrome/browser/ui/ash/chrome_shelf_prefs.h +++ b/chrome/browser/ui/ash/chrome_shelf_prefs.h
@@ -63,7 +63,7 @@ const std::vector<ash::ShelfID>& shelf_ids_after); // Makes GetPinnedAppsFromSync() return an empty list. Avoids test failures with -// SplitSettingsSync due to an untitled Play Store icon in the shelf. +// SyncSettingsCategorization due to an untitled Play Store icon in the shelf. // https://crbug.com/1085597 void SkipPinnedAppsFromSyncForTest();
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc index 630886fe..73859f7 100644 --- a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc +++ b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc
@@ -708,9 +708,6 @@ base::TimeDelta::FromMilliseconds(80); is_bubble_closing_ = true; - if (close_callback_) { - std::move(close_callback_).Run(closed_reason); - } ui::Layer* layer = View::GetWidget()->GetLayer(); auto scoped_settings = @@ -733,6 +730,10 @@ views::Widget::ClosedReason closed_reason) { View::GetWidget()->CloseWithReason(closed_reason); + // Run |close_callback_| after the widget closes. + if (close_callback_) { + std::move(close_callback_).Run(closed_reason); + } // Bubble is deleted here. delegate_->OnBubbleClosed(active_target_); }
diff --git a/chrome/browser/ui/ash/shelf/app_window_shelf_item_controller.h b/chrome/browser/ui/ash/shelf/app_window_shelf_item_controller.h index aaae1ea..f5b8d6a 100644 --- a/chrome/browser/ui/ash/shelf/app_window_shelf_item_controller.h +++ b/chrome/browser/ui/ash/shelf/app_window_shelf_item_controller.h
@@ -78,7 +78,7 @@ AppWindowBase* GetLastActiveWindow(); private: - friend class ChromeShelfControllerTest; + friend class ChromeShelfControllerTestBase; WindowList::iterator GetFromNativeWindow(aura::Window* window, WindowList& list);
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc index 06dbc5b2..1dbe911 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.cc
@@ -1121,7 +1121,7 @@ // Wait until the initial sync happens. auto* pref_service = PrefServiceSyncableFromProfile(profile()); - bool is_syncing = chromeos::features::IsSplitSettingsSyncEnabled() + bool is_syncing = chromeos::features::IsSyncSettingsCategorizationEnabled() ? pref_service->AreOsPrefsSyncing() : pref_service->IsSyncing(); if (!is_syncing)
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h index 2c4c641..30e78cef 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller.h
@@ -314,7 +314,7 @@ const std::u16string& title = std::u16string()); private: - friend class ChromeShelfControllerTest; + friend class ChromeShelfControllerTestBase; friend class ShelfAppBrowserTest; friend class ShelfPlatformAppBrowserTest; friend class TestChromeShelfController;
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc index 1f36492..310f497 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
@@ -336,15 +336,15 @@ } // namespace -class ChromeShelfControllerTest : public BrowserWithTestWindowTest { +class ChromeShelfControllerTestBase : public BrowserWithTestWindowTest { protected: - ChromeShelfControllerTest() + ChromeShelfControllerTestBase() : BrowserWithTestWindowTest(Browser::TYPE_NORMAL) {} - ChromeShelfControllerTest(const ChromeShelfControllerTest&) = delete; - ChromeShelfControllerTest& operator=(const ChromeShelfControllerTest&) = - delete; - ~ChromeShelfControllerTest() override = default; + ChromeShelfControllerTestBase(const ChromeShelfControllerTestBase&) = delete; + ChromeShelfControllerTestBase& operator=( + const ChromeShelfControllerTestBase&) = delete; + ~ChromeShelfControllerTestBase() override = default; void SetUp() override { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); @@ -412,7 +412,7 @@ run_loop.Run(); // Many pinned app tests assume OS sync is enabled. - if (chromeos::features::IsSplitSettingsSyncEnabled()) { + if (chromeos::features::IsSyncSettingsCategorizationEnabled()) { syncer::SyncService* sync_service = SyncServiceFactory::GetForProfile(profile()); sync_service->GetUserSettings()->SetOsSyncFeatureEnabled(true); @@ -609,8 +609,8 @@ // static syncer::ModelType GetPreferencesModelType() { - // SplitSettingsSync makes shelf prefs into OS prefs. - return chromeos::features::IsSplitSettingsSyncEnabled() + // SyncSettingsCategorization makes shelf prefs into OS prefs. + return chromeos::features::IsSyncSettingsCategorizationEnabled() ? syncer::OS_PREFERENCES : syncer::PREFERENCES; } @@ -1105,7 +1105,7 @@ apps::AppServiceTest app_service_test_; }; -class ChromeShelfControllerWithArcTest : public ChromeShelfControllerTest { +class ChromeShelfControllerWithArcTest : public ChromeShelfControllerTestBase { protected: ChromeShelfControllerWithArcTest() { auto_start_arc_test_ = true; } @@ -1119,27 +1119,58 @@ // To prevent crash on test exit and pending decode request. ArcAppIcon::DisableSafeDecodingForTesting(); - ChromeShelfControllerTest::SetUp(); + ChromeShelfControllerTestBase::SetUp(); } }; -// Tests for feature SplitSettingsSync. Exists as a separate class because the -// feature must be initialized before ChromeShelfControllerTest::SetUp(). -class ChromeShelfControllerSplitSettingsSyncTest - : public ChromeShelfControllerTest { +// Parameterized test for ChromeShelfController. Parameterized to tests +// the feature with SyncSettingsCategorization enabled/disabled. +class ChromeShelfControllerTest : public ChromeShelfControllerTestBase, + public ::testing::WithParamInterface<bool> { public: - ChromeShelfControllerSplitSettingsSyncTest() { - feature_list_.InitAndEnableFeature(chromeos::features::kSplitSettingsSync); + ChromeShelfControllerTest() { + if (ShouldEnableSyncSettingsCategorization()) { + feature_list_.InitWithFeatures( + /*enabled_features=*/{chromeos::features:: + kSyncSettingsCategorization}, + /*disabled_features=*/{chromeos::features::kSyncConsentOptional}); + } else { + feature_list_.InitWithFeatures( + /*enabled_features=*/{}, + /*disabled_features=*/{ + chromeos::features::kSyncSettingsCategorization, + chromeos::features::kSyncConsentOptional}); + } } - ~ChromeShelfControllerSplitSettingsSyncTest() override = default; + ~ChromeShelfControllerTest() override = default; + + bool ShouldEnableSyncSettingsCategorization() const { return GetParam(); } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +// Tests for feature SyncConsentOptional. Exists as a separate class +// because the feature must be initialized before +// ChromeShelfControllerTestBase::SetUp(). +class ChromeShelfControllerSyncConsentOptionalTest + : public ChromeShelfControllerTestBase { + public: + ChromeShelfControllerSyncConsentOptionalTest() { + feature_list_.InitWithFeatures( + /*enabled_features=*/{chromeos::features::kSyncSettingsCategorization, + chromeos::features::kSyncConsentOptional}, + /*disabled_features=*/{}); + } + ~ChromeShelfControllerSyncConsentOptionalTest() override = default; private: base::test::ScopedFeatureList feature_list_; }; // Tests for Lacros integration. Exists as a separate class because the feature -// must be initialized before ChromeShelfControllerTest::SetUp(). -class ChromeShelfControllerLacrosTest : public ChromeShelfControllerTest { +// must be initialized before ChromeShelfControllerTestBase::SetUp(). +class ChromeShelfControllerLacrosTest : public ChromeShelfControllerTestBase { public: ChromeShelfControllerLacrosTest() { feature_list_.InitAndEnableFeature(chromeos::features::kLacrosSupport); @@ -1165,7 +1196,7 @@ fake_user_manager->LoginUser(account_id); // Creates profile(). - ChromeShelfControllerTest::SetUp(); + ChromeShelfControllerTestBase::SetUp(); ASSERT_TRUE(chromeos::ProfileHelper::Get()->IsPrimaryProfile(profile())); } @@ -1246,7 +1277,7 @@ // The testing framework to test multi profile scenarios. class MultiProfileMultiBrowserShelfLayoutChromeShelfControllerTest - : public ChromeShelfControllerTest { + : public ChromeShelfControllerTestBase { protected: MultiProfileMultiBrowserShelfLayoutChromeShelfControllerTest() = default; MultiProfileMultiBrowserShelfLayoutChromeShelfControllerTest( @@ -1265,7 +1296,7 @@ std::make_unique<ash::FakeChromeUserManager>()); // Initialize the rest. - ChromeShelfControllerTest::SetUp(); + ChromeShelfControllerTestBase::SetUp(); // Ensure there are multiple profiles. User 0 is created during setup. CreateMultiUserProfile("user1"); @@ -1273,7 +1304,7 @@ } void TearDown() override { - ChromeShelfControllerTest::TearDown(); + ChromeShelfControllerTestBase::TearDown(); user_manager_enabler_.reset(); // A Task is leaked if we don't destroy everything, then run the message @@ -1380,7 +1411,7 @@ ~ChromeShelfControllerMultiProfileWithArcTest() override = default; }; -TEST_F(ChromeShelfControllerTest, PreinstalledApps) { +TEST_P(ChromeShelfControllerTest, PreinstalledApps) { InitShelfController(); // The model should only contain the browser shortcut item. @@ -1429,7 +1460,7 @@ } } -TEST_F(ChromeShelfControllerSplitSettingsSyncTest, PreinstalledApps) { +TEST_F(ChromeShelfControllerSyncConsentOptionalTest, PreinstalledApps) { // Simulate a user who opted out of sync. syncer::SyncService* sync_service = SyncServiceFactory::GetForProfile(profile()); @@ -1586,7 +1617,7 @@ } // Ensure correct merging of policy pinned apps and user pinned apps. -TEST_F(ChromeShelfControllerTest, MergePolicyAndUserPrefPinnedApps) { +TEST_P(ChromeShelfControllerTest, MergePolicyAndUserPrefPinnedApps) { InitShelfController(); AddWebApp(web_app::kGoogleDocsAppId); @@ -1634,7 +1665,7 @@ // Check that the restoration of shelf items is happening in the same order // as the user has pinned them (on another system) when they are synced reverse // order. -TEST_F(ChromeShelfControllerTest, RestorePreinstalledAppsReverseOrder) { +TEST_P(ChromeShelfControllerTest, RestorePreinstalledAppsReverseOrder) { InitShelfController(); syncer::SyncChangeList sync_list; @@ -1672,7 +1703,7 @@ // Check that the restoration of shelf items is happening in the same order // as the user has pinned them (on another system) when they are synced random // order. -TEST_F(ChromeShelfControllerTest, RestorePreinstalledAppsRandomOrder) { +TEST_P(ChromeShelfControllerTest, RestorePreinstalledAppsRandomOrder) { InitShelfController(); syncer::SyncChangeList sync_list; @@ -1709,7 +1740,7 @@ // Check that the restoration of shelf items is happening in the same order // as the user has pinned / moved them (on another system) when they are synced // random order - including the chrome icon. -TEST_F(ChromeShelfControllerTest, +TEST_P(ChromeShelfControllerTest, RestorePreinstalledAppsRandomOrderChromeMoved) { InitShelfController(); @@ -1747,7 +1778,7 @@ } // Check that syncing to a different state does the correct thing. -TEST_F(ChromeShelfControllerTest, RestorePreinstalledAppsResyncOrder) { +TEST_P(ChromeShelfControllerTest, RestorePreinstalledAppsResyncOrder) { InitShelfController(); syncer::SyncChangeList sync_list0; @@ -1800,7 +1831,7 @@ } // Test the V1 app interaction flow: run it, activate it, close it. -TEST_F(ChromeShelfControllerTest, V1AppRunActivateClose) { +TEST_P(ChromeShelfControllerTest, V1AppRunActivateClose) { InitShelfController(); // The model should only contain the browser shortcut item. EXPECT_EQ(1, model_->item_count()); @@ -1835,7 +1866,7 @@ } // Test the V1 app interaction flow: pin it, run it, close it, unpin it. -TEST_F(ChromeShelfControllerTest, V1AppPinRunCloseUnpin) { +TEST_P(ChromeShelfControllerTest, V1AppPinRunCloseUnpin) { InitShelfController(); // The model should only contain the browser shortcut. EXPECT_EQ(1, model_->item_count()); @@ -1879,7 +1910,7 @@ } // Test the V1 app interaction flow: run it, pin it, close it, unpin it. -TEST_F(ChromeShelfControllerTest, V1AppRunPinCloseUnpin) { +TEST_P(ChromeShelfControllerTest, V1AppRunPinCloseUnpin) { InitShelfController(); // The model should only contain the browser shortcut. @@ -1924,7 +1955,7 @@ } // Test the V1 app interaction flow: pin it, run it, unpin it, close it. -TEST_F(ChromeShelfControllerTest, V1AppPinRunUnpinClose) { +TEST_P(ChromeShelfControllerTest, V1AppPinRunUnpinClose) { InitShelfController(); // The model should only contain the browser shortcut item. @@ -1969,7 +2000,7 @@ } // Ensure unpinned V1 app ordering is properly restored after user changes. -TEST_F(ChromeShelfControllerTest, CheckRunningV1AppOrder) { +TEST_P(ChromeShelfControllerTest, CheckRunningV1AppOrder) { InitShelfController(); // The model should only contain the browser shortcut item. @@ -2899,7 +2930,7 @@ // Check that a running windowed V1 application will be properly pinned and // unpinned when the order gets changed through a profile / policy change. -TEST_F(ChromeShelfControllerTest, RestoreDefaultAndRunningV1AppsResyncOrder) { +TEST_P(ChromeShelfControllerTest, RestoreDefaultAndRunningV1AppsResyncOrder) { InitShelfController(); StartPrefSyncService(syncer::SyncDataList()); @@ -2948,7 +2979,7 @@ // Check that a running unpinned V2 application will be properly pinned and // unpinned when the order gets changed through a profile / policy change. -TEST_F(ChromeShelfControllerTest, RestoreDefaultAndRunningV2AppsResyncOrder) { +TEST_P(ChromeShelfControllerTest, RestoreDefaultAndRunningV2AppsResyncOrder) { InitShelfController(); syncer::SyncChangeList sync_list0; InsertAddPinChange(&sync_list0, 0, extension1_->id()); @@ -2992,7 +3023,7 @@ // Each user has a different set of applications pinned. Check that when // switching between the two users, the state gets properly set. -TEST_F(ChromeShelfControllerTest, UserSwitchIconRestore) { +TEST_P(ChromeShelfControllerTest, UserSwitchIconRestore) { syncer::SyncChangeList user_a; syncer::SyncChangeList user_b; @@ -3020,7 +3051,7 @@ // Each user has a different set of applications pinned, and one user has an // application running. Check that when switching between the two users, the // state gets properly set. -TEST_F(ChromeShelfControllerTest, UserSwitchIconRestoreWithRunningV2App) { +TEST_P(ChromeShelfControllerTest, UserSwitchIconRestoreWithRunningV2App) { syncer::SyncChangeList user_a; syncer::SyncChangeList user_b; @@ -3052,7 +3083,7 @@ // application running. The chrome icon is not the last item in the list. // Check that when switching between the two users, the state gets properly set. // There was once a bug associated with this. -TEST_F(ChromeShelfControllerTest, +TEST_P(ChromeShelfControllerTest, UserSwitchIconRestoreWithRunningV2AppChromeInMiddle) { syncer::SyncChangeList user_a; syncer::SyncChangeList user_b; @@ -3079,7 +3110,7 @@ GetPinnedAppStatus()); } -TEST_F(ChromeShelfControllerTest, Policy) { +TEST_P(ChromeShelfControllerTest, Policy) { extension_service_->AddExtension(extension2_.get()); AddWebApp(web_app::kGmailAppId); @@ -3112,7 +3143,7 @@ EXPECT_EQ("Chrome, App1, App2", GetPinnedAppStatus()); } -TEST_F(ChromeShelfControllerTest, UnpinWithUninstall) { +TEST_P(ChromeShelfControllerTest, UnpinWithUninstall) { AddWebApp(web_app::kGmailAppId); AddWebApp(web_app::kYoutubeAppId); @@ -3128,7 +3159,7 @@ EXPECT_TRUE(shelf_controller_->IsAppPinned(web_app::kYoutubeAppId)); } -TEST_F(ChromeShelfControllerTest, SyncUpdates) { +TEST_P(ChromeShelfControllerTest, SyncUpdates) { extension_service_->AddExtension(extension2_.get()); AddWebApp(web_app::kGmailAppId); AddWebApp(web_app::kGoogleDocsAppId); @@ -3196,7 +3227,7 @@ EXPECT_EQ(expected_pinned_apps, actual_pinned_apps); } -TEST_F(ChromeShelfControllerTest, PendingInsertionOrder) { +TEST_P(ChromeShelfControllerTest, PendingInsertionOrder) { extension_service_->AddExtension(extension1_.get()); AddWebApp(web_app::kGmailAppId); @@ -3236,7 +3267,7 @@ } // Check that browsers get reflected correctly in the shelf menu. -TEST_F(ChromeShelfControllerTest, BrowserMenuGeneration) { +TEST_P(ChromeShelfControllerTest, BrowserMenuGeneration) { EXPECT_EQ(1U, chrome::GetTotalBrowserCount()); chrome::NewTab(browser()); @@ -3323,7 +3354,7 @@ // refocus logic. // Note that the extension matching logic is tested by the extension system // and does not need a separate test here. -TEST_F(ChromeShelfControllerTest, V1AppMenuGeneration) { +TEST_P(ChromeShelfControllerTest, V1AppMenuGeneration) { EXPECT_EQ(1U, chrome::GetTotalBrowserCount()); EXPECT_EQ(0, browser()->tab_strip_model()->count()); @@ -3508,7 +3539,7 @@ EXPECT_EQ(1, model_->item_count()); } -TEST_F(ChromeShelfControllerTest, Active) { +TEST_P(ChromeShelfControllerTest, Active) { InitShelfController(); // Creates a new app window. @@ -3823,7 +3854,7 @@ } // Checks that the generated menu list properly activates items. -TEST_F(ChromeShelfControllerTest, V1AppMenuExecution) { +TEST_P(ChromeShelfControllerTest, V1AppMenuExecution) { InitShelfControllerWithBrowser(); StartPrefSyncService(syncer::SyncDataList()); @@ -3873,7 +3904,7 @@ } // Checks that the generated menu list properly deletes items. -TEST_F(ChromeShelfControllerTest, V1AppMenuDeletionExecution) { +TEST_P(ChromeShelfControllerTest, V1AppMenuDeletionExecution) { InitShelfControllerWithBrowser(); StartPrefSyncService(syncer::SyncDataList()); @@ -3917,7 +3948,7 @@ } // Verify that the shelf item positions are persisted and restored. -TEST_F(ChromeShelfControllerTest, PersistShelfItemPositions) { +TEST_P(ChromeShelfControllerTest, PersistShelfItemPositions) { InitShelfController(); TestShelfControllerHelper* helper = new TestShelfControllerHelper; @@ -3962,7 +3993,7 @@ } // Verifies pinned apps are persisted and restored. -TEST_F(ChromeShelfControllerTest, PersistPinned) { +TEST_P(ChromeShelfControllerTest, PersistPinned) { InitShelfControllerWithBrowser(); size_t initial_size = model_->items().size(); @@ -4012,7 +4043,7 @@ // Verifies that ShelfID property is updated for browsers that are present when // ChromeShelfController is created. -TEST_F(ChromeShelfControllerTest, ExistingBrowserWindowShelfIDSet) { +TEST_P(ChromeShelfControllerTest, ExistingBrowserWindowShelfIDSet) { InitShelfControllerWithBrowser(); PinAppWithIDToShelf("1"); @@ -4036,7 +4067,7 @@ ash::kShelfIDKey))); } -TEST_F(ChromeShelfControllerTest, MultipleAppIconLoaders) { +TEST_P(ChromeShelfControllerTest, MultipleAppIconLoaders) { InitShelfControllerWithBrowser(); const ash::ShelfID shelf_id1(extension1_->id()); @@ -4235,7 +4266,7 @@ namespace { class ChromeShelfControllerArcDefaultAppsTest - : public ChromeShelfControllerTest { + : public ChromeShelfControllerTestBase { public: ChromeShelfControllerArcDefaultAppsTest() = default; ChromeShelfControllerArcDefaultAppsTest( @@ -4248,12 +4279,12 @@ void SetUp() override { ArcAppIcon::DisableSafeDecodingForTesting(); ArcDefaultAppList::UseTestAppsDirectory(); - ChromeShelfControllerTest::SetUp(); + ChromeShelfControllerTestBase::SetUp(); } }; class ChromeShelfControllerPlayStoreAvailabilityTest - : public ChromeShelfControllerTest, + : public ChromeShelfControllerTestBase, public ::testing::WithParamInterface<bool> { public: ChromeShelfControllerPlayStoreAvailabilityTest() = default; @@ -4270,7 +4301,7 @@ // To prevent crash on test exit and pending decode request. ArcAppIcon::DisableSafeDecodingForTesting(); ArcDefaultAppList::UseTestAppsDirectory(); - ChromeShelfControllerTest::SetUp(); + ChromeShelfControllerTestBase::SetUp(); } }; @@ -4433,7 +4464,7 @@ // Checks the case when several app items have the same ordinal position (which // is valid case). -TEST_F(ChromeShelfControllerTest, CheckPositionConflict) { +TEST_P(ChromeShelfControllerTest, CheckPositionConflict) { InitShelfController(); extension_service_->AddExtension(extension1_.get()); @@ -4483,7 +4514,7 @@ // Test the case when sync app is turned off and we need to use local copy to // support user's pins. -TEST_F(ChromeShelfControllerTest, SyncOffLocalUpdate) { +TEST_P(ChromeShelfControllerTest, SyncOffLocalUpdate) { InitShelfController(); extension_service_->AddExtension(extension1_.get()); @@ -4514,7 +4545,7 @@ } // Test the Settings can be pinned and unpinned. -TEST_F(ChromeShelfControllerTest, InternalAppPinUnpin) { +TEST_P(ChromeShelfControllerTest, InternalAppPinUnpin) { InitShelfController(); // The model should only contain the browser shortcut item. EXPECT_EQ(1, model_->item_count()); @@ -4536,7 +4567,7 @@ } // Test that internal app can be added and removed on shelf. -TEST_F(ChromeShelfControllerTest, InternalAppWindowRecreation) { +TEST_P(ChromeShelfControllerTest, InternalAppWindowRecreation) { InitShelfController(); // Only test the first internal app. The others should be the same. @@ -4567,7 +4598,7 @@ // Test that internal app can be added and removed by SetProperty of // ash::kShelfIDKey. -TEST_F(ChromeShelfControllerTest, InternalAppWindowPropertyChanged) { +TEST_P(ChromeShelfControllerTest, InternalAppWindowPropertyChanged) { InitShelfController(); // Only test the first internal app. The others should be the same. @@ -4604,7 +4635,7 @@ } // TODO(b/194627475): Move these tests to chrome_shelf_controller_browsertest.cc -class ChromeShelfControllerDemoModeTest : public ChromeShelfControllerTest { +class ChromeShelfControllerDemoModeTest : public ChromeShelfControllerTestBase { protected: ChromeShelfControllerDemoModeTest() { auto_start_arc_test_ = true; } ChromeShelfControllerDemoModeTest(const ChromeShelfControllerDemoModeTest&) = @@ -4617,7 +4648,7 @@ // To prevent crash on test exit and pending decode request. ArcAppIcon::DisableSafeDecodingForTesting(); - ChromeShelfControllerTest::SetUp(); + ChromeShelfControllerTestBase::SetUp(); // Fake Demo Mode. demo_mode_test_helper_ = std::make_unique<ash::DemoModeTestHelper>(); @@ -4627,7 +4658,7 @@ void TearDown() override { demo_mode_test_helper_.reset(); - ChromeShelfControllerTest::TearDown(); + ChromeShelfControllerTestBase::TearDown(); } web_app::AppId InstallExternalWebApp(std::string start_url) { @@ -4792,7 +4823,7 @@ GetPinnableForAppID(web_app_id, profile())); } -TEST_F(ChromeShelfControllerTest, CrostiniTerminalPinUnpin) { +TEST_P(ChromeShelfControllerTest, CrostiniTerminalPinUnpin) { InitShelfController(); // Load pinned Terminal from prefs without Crostini UI being allowed @@ -4819,7 +4850,7 @@ } // Tests behavior for ensuring some component apps can be marked unpinnable. -TEST_F(ChromeShelfControllerTest, UnpinnableComponentApps) { +TEST_P(ChromeShelfControllerTest, UnpinnableComponentApps) { InitShelfController(); const char* kPinnableApp = file_manager::kFileManagerAppId; @@ -4833,7 +4864,7 @@ } } -TEST_F(ChromeShelfControllerTest, DoNotShowInShelf) { +TEST_P(ChromeShelfControllerTest, DoNotShowInShelf) { syncer::SyncChangeList sync_list; InsertAddPinChange(&sync_list, 0, extension1_->id()); InsertAddPinChange(&sync_list, 0, extension2_->id()); @@ -4947,7 +4978,7 @@ EXPECT_EQ(3, shelf_controller_->PinnedItemIndexByAppID(arc_app_id1)); } -class ChromeShelfControllerWebAppTest : public ChromeShelfControllerTest { +class ChromeShelfControllerWebAppTest : public ChromeShelfControllerTestBase { protected: ChromeShelfControllerWebAppTest() {} @@ -5002,7 +5033,7 @@ } // Test the app status when the paused app is blocked, un-blocked, and un-paused -TEST_F(ChromeShelfControllerTest, VerifyAppStatusForPausedApp) { +TEST_P(ChromeShelfControllerTest, VerifyAppStatusForPausedApp) { AddExtension(extension1_.get()); // Set the app as paused @@ -5037,7 +5068,7 @@ // Test the app status when the blocked app is paused, un-paused, hidden, // visible and un-blocked -TEST_F(ChromeShelfControllerTest, VerifyAppStatusForBlockedApp) { +TEST_P(ChromeShelfControllerTest, VerifyAppStatusForBlockedApp) { AddExtension(extension1_.get()); // Set the app as blocked @@ -5089,6 +5120,11 @@ EXPECT_EQ(ash::AppStatus::kReady, model_->items()[1].app_status); } +INSTANTIATE_TEST_SUITE_P( + /* no label */, + ChromeShelfControllerTest, + /*sync_settings_categorization_enabled=*/::testing::Bool()); + INSTANTIATE_TEST_SUITE_P(All, ChromeShelfControllerPlayStoreAvailabilityTest, ::testing::Values(false, true));
diff --git a/chrome/browser/ui/intent_picker_tab_helper.cc b/chrome/browser/ui/intent_picker_tab_helper.cc index c22cdbf..ea1acd5 100644 --- a/chrome/browser/ui/intent_picker_tab_helper.cc +++ b/chrome/browser/ui/intent_picker_tab_helper.cc
@@ -131,14 +131,11 @@ // For a http/https scheme URL navigation, we will check if the // url can be handled by some apps, and show intent picker icon // or bubble if there are some apps available. We only want to check this if - // the navigation happens in the main frame, and the navigation is not the - // same document with same URL. + // the navigation happens in the primary main frame, and the navigation is not + // the same document with same URL. // TODO(crbug.com/826982): Check is not error page here. Adding this check // will break the browser test, given this is a refactor CL, will add check in // follow up CL. - // TODO(https://crbug.com/1218946): With MPArch there may be multiple main - // frames. This caller was converted automatically to the primary main frame - // to preserve its semantics. Follow up to confirm correctness. if (navigation_handle->IsInPrimaryMainFrame() && navigation_handle->HasCommitted() && (!navigation_handle->IsSameDocument() ||
diff --git a/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc b/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc index 6403d1f..4acd581 100644 --- a/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc +++ b/chrome/browser/ui/javascript_dialogs/javascript_dialog_browsertest.cc
@@ -422,9 +422,9 @@ nav_observer.Wait(); } - ASSERT_EQ(2u, tab->GetAllFrames().size()); content::RenderFrameHost* subframe = content::ChildFrameAt(tab->GetMainFrame(), 0); + ASSERT_TRUE(subframe); // Verify the title that would be used for a dialog spawned by that subframe. javascript_dialogs::AppModalDialogManager* dialog_manager =
diff --git a/chrome/browser/ui/search/third_party_ntp_browsertest.cc b/chrome/browser/ui/search/third_party_ntp_browsertest.cc index 83b9bf0..f370c307 100644 --- a/chrome/browser/ui/search/third_party_ntp_browsertest.cc +++ b/chrome/browser/ui/search/third_party_ntp_browsertest.cc
@@ -73,8 +73,8 @@ nav_observer.WaitForNavigationFinished(); // Verify that the subframe exists and has the expected origin. - ASSERT_EQ(2u, contents->GetAllFrames().size()); - content::RenderFrameHost* subframe = contents->GetAllFrames()[1]; + content::RenderFrameHost* subframe = ChildFrameAt(contents, 0); + ASSERT_TRUE(subframe); std::string subframe_origin; ASSERT_TRUE(content::ExecuteScriptAndExtractString( subframe, "domAutomationController.send(window.origin)",
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index 30041d7..3e0cb91 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -2506,7 +2506,7 @@ web_app::AppId app_id = InstallWebAppWithProtocolHandlers({protocol_handler}); bool approved_protocols_notified = false; web_app::WebAppTestRegistryObserverAdapter observer(browser()->profile()); - observer.SetWebAppApprovedProtocolsChangedDelegate(base::BindLambdaForTesting( + observer.SetWebAppProtocolSettingsChangedDelegate(base::BindLambdaForTesting( [&]() { approved_protocols_notified = true; })); WebAppProtocolHandlerIntentPickerView::SetDefaultRememberSelectionForTesting(
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc b/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc index a257d08..49b88df 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_view_interactive_uitest.cc
@@ -713,10 +713,17 @@ browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL()); } +#if defined(OS_LINUX) +// TODO(crbug.com/1251961): Flaky on Linux (CFI) +#define MAYBE_ClickingContextMenuButton DISABLED_ClickingContextMenuButton +#else +#define MAYBE_ClickingContextMenuButton ClickingContextMenuButton +#endif + // Tests that clicking on the context menu button of an extension item opens the // context menu. IN_PROC_BROWSER_TEST_F(ExtensionsMenuViewInteractiveUITest, - ClickingContextMenuButton) { + MAYBE_ClickingContextMenuButton) { LoadTestExtension("extensions/uitest/window_open"); ClickExtensionsMenuButton();
diff --git a/chrome/browser/ui/views/file_system_access/file_system_access_browsertest.cc b/chrome/browser/ui/views/file_system_access/file_system_access_browsertest.cc index 6a0c2b65..691b3ef7 100644 --- a/chrome/browser/ui/views/file_system_access/file_system_access_browsertest.cc +++ b/chrome/browser/ui/views/file_system_access/file_system_access_browsertest.cc
@@ -497,9 +497,9 @@ content::WebContents* third_party_web_contents = second_window->tab_strip_model()->GetActiveWebContents(); - ASSERT_EQ(3u, third_party_web_contents->GetAllFrames().size()); content::RenderFrameHost* third_party_iframe = - third_party_web_contents->GetAllFrames()[1]; + ChildFrameAt(third_party_web_contents, 0); + ASSERT_TRUE(third_party_iframe); ASSERT_EQ( third_party_iframe->GetLastCommittedOrigin(), url::Origin::Create(first_party_web_contents->GetLastCommittedURL())); @@ -641,9 +641,9 @@ content::WebContents* third_party_web_contents = second_window->tab_strip_model()->GetActiveWebContents(); - ASSERT_EQ(3u, third_party_web_contents->GetAllFrames().size()); content::RenderFrameHost* third_party_iframe = - third_party_web_contents->GetAllFrames()[1]; + ChildFrameAt(third_party_web_contents, 0); + ASSERT_TRUE(third_party_iframe); ASSERT_EQ( third_party_iframe->GetLastCommittedOrigin(), url::Origin::Create(first_party_web_contents->GetLastCommittedURL()));
diff --git a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc index a0533ac..411a9db 100644 --- a/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/intent_picker_bubble_view_browsertest.cc
@@ -21,6 +21,8 @@ #include "chrome/test/base/ui_test_utils.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" +#include "content/public/test/prerender_test_util.h" +#include "net/dns/mock_host_resolver.h" #include "third_party/blink/public/common/features.h" #include "ui/events/base_event_utils.h" #include "ui/views/widget/any_widget_observer.h" @@ -30,10 +32,9 @@ : public web_app::WebAppNavigationBrowserTest, public ::testing::WithParamInterface<std::string> { public: - void SetUp() override { + IntentPickerBubbleViewBrowserTest() { // TODO(schenney): Stop disabling Paint Holding. crbug.com/1001189 scoped_feature_list_.InitAndDisableFeature(blink::features::kPaintHolding); - web_app::WebAppNavigationBrowserTest::SetUp(); } void OpenNewTab(const GURL& url) { @@ -291,3 +292,75 @@ All, IntentPickerBubbleViewBrowserTest, testing::Values("", "noopener", "noreferrer", "nofollow")); + +class IntentPickerBubbleViewPrerenderingBrowserTest + : public IntentPickerBubbleViewBrowserTest { + public: + IntentPickerBubbleViewPrerenderingBrowserTest() + : prerender_helper_(base::BindRepeating( + &IntentPickerBubbleViewPrerenderingBrowserTest::GetWebContents, + base::Unretained(this))) {} + ~IntentPickerBubbleViewPrerenderingBrowserTest() override = default; + IntentPickerBubbleViewPrerenderingBrowserTest( + const IntentPickerBubbleViewPrerenderingBrowserTest&) = delete; + + IntentPickerBubbleViewPrerenderingBrowserTest& operator=( + const IntentPickerBubbleViewPrerenderingBrowserTest&) = delete; + + void SetUp() override { + prerender_helper_.SetUp(embedded_test_server()); + IntentPickerBubbleViewBrowserTest::SetUp(); + } + + void SetUpOnMainThread() override { + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(embedded_test_server()->Start()); + IntentPickerBubbleViewBrowserTest::SetUpOnMainThread(); + } + + content::test::PrerenderTestHelper& prerender_test_helper() { + return prerender_helper_; + } + + content::WebContents* GetWebContents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + + private: + content::test::PrerenderTestHelper prerender_helper_; +}; + +IN_PROC_BROWSER_TEST_P(IntentPickerBubbleViewPrerenderingBrowserTest, + PrerenderingShouldNotShowIntentPicker) { + InstallTestWebApp(); + + PageActionIconView* intent_picker_view = GetIntentPickerIcon(); + + const GURL initial_url = + https_server().GetURL(GetAppUrlHost(), "/empty.html"); + OpenNewTab(initial_url); + EXPECT_FALSE(intent_picker_view->GetVisible()); + + // Load a prerender page and prerendering should not try to show the + // intent picker. + const GURL prerender_url = https_server().GetURL( + GetAppUrlHost(), std::string(GetAppScopePath()) + "index1.html"); + int host_id = prerender_test_helper().AddPrerender(prerender_url); + content::test::PrerenderHostObserver host_observer(*GetWebContents(), + host_id); + EXPECT_FALSE(host_observer.was_activated()); + EXPECT_FALSE(intent_picker_view->GetVisible()); + + // Activate the prerender page. + prerender_test_helper().NavigatePrimaryPage(prerender_url); + EXPECT_TRUE(host_observer.was_activated()); + + // After activation, IntentPickerTabHelper should show the + // intent picker. + EXPECT_TRUE(intent_picker_view->GetVisible()); +} + +INSTANTIATE_TEST_SUITE_P( + All, + IntentPickerBubbleViewPrerenderingBrowserTest, + testing::Values("", "noopener", "noreferrer", "nofollow"));
diff --git a/chrome/browser/ui/webui/chromeos/diagnostics_dialog.cc b/chrome/browser/ui/webui/chromeos/diagnostics_dialog.cc index d91285f..e1a5909 100644 --- a/chrome/browser/ui/webui/chromeos/diagnostics_dialog.cc +++ b/chrome/browser/ui/webui/chromeos/diagnostics_dialog.cc
@@ -18,8 +18,8 @@ switch (page) { case DiagnosticsDialog::DiagnosticsPage::kDefault: return kChromeUIDiagnosticsAppUrl; - case DiagnosticsDialog::DiagnosticsPage::kOverview: - return base::StrCat({kChromeUIDiagnosticsAppUrl, "?overview"}); + case DiagnosticsDialog::DiagnosticsPage::kSystem: + return base::StrCat({kChromeUIDiagnosticsAppUrl, "?system"}); case DiagnosticsDialog::DiagnosticsPage::kConnectivity: return base::StrCat({kChromeUIDiagnosticsAppUrl, "?connectivity"}); case DiagnosticsDialog::DiagnosticsPage::kInput:
diff --git a/chrome/browser/ui/webui/chromeos/diagnostics_dialog.h b/chrome/browser/ui/webui/chromeos/diagnostics_dialog.h index 99ba2fc..f16cd824 100644 --- a/chrome/browser/ui/webui/chromeos/diagnostics_dialog.h +++ b/chrome/browser/ui/webui/chromeos/diagnostics_dialog.h
@@ -16,8 +16,8 @@ enum class DiagnosticsPage { // The default page. kDefault, - // The overview page. - kOverview, + // The system page. + kSystem, // The connectivity page. kConnectivity, // The input page.
diff --git a/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc b/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc index de35fdd..a520f8f 100644 --- a/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc +++ b/chrome/browser/ui/webui/settings/protocol_handlers_handler.cc
@@ -15,6 +15,8 @@ #include "base/values.h" #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/web_applications/os_integration_manager.h" +#include "chrome/browser/web_applications/web_app_sync_bridge.h" #include "chrome/common/url_constants.h" #include "components/google/core/common/google_util.h" #include "components/prefs/pref_service.h" @@ -24,20 +26,22 @@ namespace { +// TODO(https://crbug.com/1251039): Remove usages of base::ListValue void GetHandlersAsListValue( - const ProtocolHandlerRegistry& registry, + const ProtocolHandlerRegistry* registry, const ProtocolHandlerRegistry::ProtocolHandlerList& handlers, base::ListValue* handler_list) { - ProtocolHandlerRegistry::ProtocolHandlerList::const_iterator handler; - for (handler = handlers.begin(); handler != handlers.end(); ++handler) { - std::unique_ptr<base::DictionaryValue> handler_value( - new base::DictionaryValue()); - handler_value->SetString("protocol_display_name", - handler->GetProtocolDisplayName()); - handler_value->SetString("protocol", handler->protocol()); - handler_value->SetString("spec", handler->url().spec()); - handler_value->SetString("host", handler->url().host()); - handler_value->SetBoolean("is_default", registry.IsDefault(*handler)); + for (const auto& handler : handlers) { + base::DictionaryValue handler_value; + handler_value.SetStringPath("protocol_display_name", + handler.GetProtocolDisplayName()); + handler_value.SetStringPath("protocol", handler.protocol()); + handler_value.SetStringPath("spec", handler.url().spec()); + handler_value.SetStringPath("host", handler.url().host()); + if (registry) + handler_value.SetBoolPath("is_default", registry->IsDefault(handler)); + if (handler.web_app_id().has_value()) + handler_value.SetStringPath("app_id", handler.web_app_id().value()); handler_list->Append(std::move(handler_value)); } } @@ -49,10 +53,12 @@ void ProtocolHandlersHandler::OnJavascriptAllowed() { registry_observation_.Observe(GetProtocolHandlerRegistry()); + app_observation_.Observe(&GetWebAppProvider()->registrar()); } void ProtocolHandlersHandler::OnJavascriptDisallowed() { registry_observation_.Reset(); + app_observation_.Reset(); } void ProtocolHandlersHandler::RegisterMessages() { @@ -78,6 +84,18 @@ "setDefault", base::BindRepeating(&ProtocolHandlersHandler::HandleSetDefault, base::Unretained(this))); + + // Web App Protocol Handlers register message callbacks: + web_ui()->RegisterMessageCallback( + "observeAppProtocolHandlers", + base::BindRepeating( + &ProtocolHandlersHandler::HandleObserveAppProtocolHandlers, + base::Unretained(this))); + web_ui()->RegisterMessageCallback( + "removeAppApprovedHandler", + base::BindRepeating( + &ProtocolHandlersHandler::HandleRemoveApprovedAppHandler, + base::Unretained(this))); } void ProtocolHandlersHandler::OnProtocolHandlerRegistryChanged() { @@ -85,6 +103,15 @@ UpdateHandlerList(); } +void ProtocolHandlersHandler::OnWebAppProtocolSettingsChanged() { + UpdateAllApprovedLaunchProtocols(); +} + +void ProtocolHandlersHandler::OnWebAppUninstalled( + const web_app::AppId& app_id) { + OnWebAppProtocolSettingsChanged(); +} + void ProtocolHandlersHandler::GetHandlersForProtocol( const std::string& protocol, base::DictionaryValue* handlers_value) { @@ -94,7 +121,7 @@ handlers_value->SetString("protocol", protocol); base::ListValue handlers_list; - GetHandlersAsListValue(*registry, registry->GetHandlersFor(protocol), + GetHandlersAsListValue(registry, registry->GetHandlersFor(protocol), &handlers_list); handlers_value->SetKey("handlers", std::move(handlers_list)); } @@ -103,7 +130,7 @@ ProtocolHandlerRegistry* registry = GetProtocolHandlerRegistry(); ProtocolHandlerRegistry::ProtocolHandlerList ignored_handlers = registry->GetIgnoredHandlers(); - return GetHandlersAsListValue(*registry, ignored_handlers, handlers); + return GetHandlersAsListValue(registry, ignored_handlers, handlers); } void ProtocolHandlersHandler::UpdateHandlerList() { @@ -186,4 +213,76 @@ Profile::FromWebUI(web_ui())); } +// App Protocol Handler specific functions + +std::unique_ptr<base::DictionaryValue> +ProtocolHandlersHandler::GetAppHandlersForProtocol( + const std::string& protocol) { + auto handlers_value = std::make_unique<base::DictionaryValue>(); + web_app::OsIntegrationManager& os_integration_manager = + GetWebAppProvider()->os_integration_manager(); + + ProtocolHandlerRegistry::ProtocolHandlerList handlers = + os_integration_manager.GetApprovedHandlersForProtocol(protocol); + + if (!handlers.empty()) { + handlers_value->SetStringPath( + "protocol_display_name", + content::ProtocolHandler::GetProtocolDisplayName(protocol)); + handlers_value->SetStringPath("protocol", protocol); + + base::ListValue handlers_list; + GetHandlersAsListValue(nullptr, handlers, &handlers_list); + handlers_value->SetKey("handlers", std::move(handlers_list)); + } + return handlers_value; +} + +void ProtocolHandlersHandler::UpdateAllApprovedLaunchProtocols() { + base::flat_set<std::string> protocols( + GetWebAppProvider()->registrar().GetAllApprovedLaunchProtocols()); + + base::Value handlers(base::Value::Type::LIST); + for (auto& protocol : protocols) { + auto handler_value(GetAppHandlersForProtocol(protocol)); + handlers.Append(std::move(*handler_value)); + } + + FireWebUIListener("setAppApprovedProtocolHandlers", handlers); +} + +void ProtocolHandlersHandler::HandleObserveAppProtocolHandlers( + base::Value::ConstListView args) { + AllowJavascript(); + UpdateAllApprovedLaunchProtocols(); +} + +void ProtocolHandlersHandler::HandleRemoveApprovedAppHandler( + base::Value::ConstListView args) { + content::ProtocolHandler handler(ParseAppHandlerFromArgs(args)); + CHECK(!handler.IsEmpty()); + + GetWebAppProvider()->sync_bridge().RemoveApprovedLaunchProtocol( + handler.web_app_id().value(), handler.protocol()); + + // No need to call UpdateAllApprovedLaunchProtocols() - we should receive a + // notification that the Web App Protocol Settings has changed and we will + // update the view then. +} + +content::ProtocolHandler ProtocolHandlersHandler::ParseAppHandlerFromArgs( + base::Value::ConstListView args) const { + const std::string* protocol = args[0].GetIfString(); + const std::string* url = args[1].GetIfString(); + const std::string* app_id = args[2].GetIfString(); + if (!protocol || !url || !app_id) + return content::ProtocolHandler::EmptyProtocolHandler(); + return content::ProtocolHandler::CreateWebAppProtocolHandler( + *protocol, GURL(*url), *app_id); +} + +web_app::WebAppProvider* ProtocolHandlersHandler::GetWebAppProvider() { + return web_app::WebAppProvider::GetForWebApps(Profile::FromWebUI(web_ui())); +} + } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/protocol_handlers_handler.h b/chrome/browser/ui/webui/settings/protocol_handlers_handler.h index a57ca0cf..b867423 100644 --- a/chrome/browser/ui/webui/settings/protocol_handlers_handler.h +++ b/chrome/browser/ui/webui/settings/protocol_handlers_handler.h
@@ -11,14 +11,19 @@ #include "base/scoped_observation.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" #include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" +#include "chrome/browser/web_applications/app_registrar_observer.h" +#include "chrome/browser/web_applications/web_app_id.h" +#include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/browser/web_applications/web_app_registrar.h" #include "content/public/common/custom_handlers/protocol_handler.h" //////////////////////////////////////////////////////////////////////////////// // ProtocolHandlersHandler -// Listen for changes to protocol handlers (i.e. registerProtocolHandler()). -// This get triggered whenever a user allows a specific website or application -// to handle clicks on a link with a specified protocol (i.e. mailto: -> Gmail). +// Listen for changes to protocol handlers registrations. +// This get triggered whenever a user allows or disallows a specific website or +// application to handle clicks on a link with a specified protocol (i.e. +// mailto: -> Gmail). namespace base { class DictionaryValue; @@ -29,7 +34,8 @@ namespace settings { class ProtocolHandlersHandler : public SettingsPageUIHandler, - public ProtocolHandlerRegistry::Observer { + public ProtocolHandlerRegistry::Observer, + public web_app::AppRegistrarObserver { public: ProtocolHandlersHandler(); @@ -46,6 +52,10 @@ // ProtocolHandlerRegistry::Observer: void OnProtocolHandlerRegistryChanged() override; + // web_app::AppRegistrarObserver: + void OnWebAppUninstalled(const web_app::AppId& app_id) override; + void OnWebAppProtocolSettingsChanged() override; + private: // Called to fetch the state of the protocol handlers. If the full list of // handlers is not needed, consider HandleObserveProtocolHandlersEnabledState @@ -90,6 +100,34 @@ base::ScopedObservation<ProtocolHandlerRegistry, ProtocolHandlerRegistry::Observer> registry_observation_{this}; + + // Web App Protocol Handler specific functions: + + // Called to fetch the state of the app protocol handlers. + void HandleObserveAppProtocolHandlers(base::Value::ConstListView args); + + // Parses an App ProtocolHandler out of |args|, which is a list of [protocol, + // url, app_id]. + content::ProtocolHandler ParseAppHandlerFromArgs( + base::Value::ConstListView args) const; + + // Returns a DictionaryValue describing the set of app protocol handlers for + // the given |protocol|. + std::unique_ptr<base::DictionaryValue> GetAppHandlersForProtocol( + const std::string& protocol); + + // Called when OnWebAppProtocolSettingsChanged() is notified or on page load. + void UpdateAllApprovedLaunchProtocols(); + + // Remove a handler. + // |args| is a list of [protocol, url, app_id]. + void HandleRemoveApprovedAppHandler(base::Value::ConstListView args); + + web_app::WebAppProvider* GetWebAppProvider(); + + base::ScopedObservation<web_app::WebAppRegistrar, + web_app::AppRegistrarObserver> + app_observation_{this}; }; } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index f0723b9..105e141 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -1910,6 +1910,10 @@ IDS_SETTINGS_SITE_SETTINGS_ALL_SITES_SORT_METHOD_NAME}, {"siteSettingsSiteRepresentationSeparator", IDS_SETTINGS_SITE_SETTINGS_SITE_REPRESENTATION_SEPARATOR}, + {"siteSettingsAppProtocolHandlers", + IDS_SETTINGS_SITE_SETTINGS_APP_PROTOCOL_HANDLERS}, + {"siteSettingsAppApprovedProtocolHandlersDescription", + IDS_SETTINGS_SITE_SETTINGS_APP_APPROVED_PROTOCOL_HANDLERS_DESCRIPTION}, {"siteSettingsAutomaticDownloads", IDS_SITE_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS}, {"siteSettingsAutomaticDownloadsMidSentence",
diff --git a/chrome/browser/web_applications/app_registrar_observer.h b/chrome/browser/web_applications/app_registrar_observer.h index b9e5f60..9f3fa241 100644 --- a/chrome/browser/web_applications/app_registrar_observer.h +++ b/chrome/browser/web_applications/app_registrar_observer.h
@@ -53,11 +53,7 @@ // Called after remembering the user choice to always launch an app via // a given protocol. - virtual void OnWebAppApprovedProtocolsChanged() {} - - // Called after remembering the user choice to never launch an app via - // a given protocol. - virtual void OnWebAppDisallowedProtocolsChanged() {} + virtual void OnWebAppProtocolSettingsChanged() {} virtual void OnWebAppLocallyInstalledStateChanged(const AppId& app_id, bool is_locally_installed) {
diff --git a/chrome/browser/web_applications/os_integration_manager.cc b/chrome/browser/web_applications/os_integration_manager.cc index 13d2b76..eed7fc7b 100644 --- a/chrome/browser/web_applications/os_integration_manager.cc +++ b/chrome/browser/web_applications/os_integration_manager.cc
@@ -340,6 +340,15 @@ return protocol_handler_manager_->GetAppProtocolHandlers(app_id); } +std::vector<ProtocolHandler> +OsIntegrationManager::GetApprovedHandlersForProtocol( + const std::string& protocol) { + if (!protocol_handler_manager_) + return std::vector<ProtocolHandler>(); + + return protocol_handler_manager_->GetApprovedHandlersForProtocol(protocol); +} + WebAppFileHandlerManager& OsIntegrationManager::file_handler_manager_for_testing() { DCHECK(file_handler_manager_);
diff --git a/chrome/browser/web_applications/os_integration_manager.h b/chrome/browser/web_applications/os_integration_manager.h index e6937f0..28a6ddc0 100644 --- a/chrome/browser/web_applications/os_integration_manager.h +++ b/chrome/browser/web_applications/os_integration_manager.h
@@ -155,6 +155,8 @@ const std::string& protocol); virtual std::vector<ProtocolHandler> GetAppProtocolHandlers( const AppId& app_id); + virtual std::vector<ProtocolHandler> GetApprovedHandlersForProtocol( + const std::string& protocol); // Getter for testing WebAppFileHandlerManager WebAppFileHandlerManager& file_handler_manager_for_testing();
diff --git a/chrome/browser/web_applications/test/web_app_test_observers.cc b/chrome/browser/web_applications/test/web_app_test_observers.cc index 719f05e..610aac98 100644 --- a/chrome/browser/web_applications/test/web_app_test_observers.cc +++ b/chrome/browser/web_applications/test/web_app_test_observers.cc
@@ -80,15 +80,9 @@ } void WebAppTestRegistryObserverAdapter:: - SetWebAppApprovedProtocolsChangedDelegate( - WebAppApprovedProtocolsChangedDelegate delegate) { - app_approved_protocols_changed_delegate_ = delegate; -} - -void WebAppTestRegistryObserverAdapter:: - SetWebAppDisallowedProtocolsChangedDelegate( - WebAppDisallowedProtocolsChangedDelegate delegate) { - app_disallowed_protocols_changed_delegate_ = delegate; + SetWebAppProtocolSettingsChangedDelegate( + WebAppProtocolSettingsChangedDelegate delegate) { + app_protocol_settings_changed_delegate_ = delegate; } void WebAppTestRegistryObserverAdapter::OnWebAppInstalled(const AppId& app_id) { @@ -140,14 +134,9 @@ app_last_badging_time_changed_delegate_.Run(app_id, time); } -void WebAppTestRegistryObserverAdapter::OnWebAppApprovedProtocolsChanged() { - if (app_approved_protocols_changed_delegate_) - app_approved_protocols_changed_delegate_.Run(); -} - -void WebAppTestRegistryObserverAdapter::OnWebAppDisallowedProtocolsChanged() { - if (app_disallowed_protocols_changed_delegate_) - app_disallowed_protocols_changed_delegate_.Run(); +void WebAppTestRegistryObserverAdapter::OnWebAppProtocolSettingsChanged() { + if (app_protocol_settings_changed_delegate_) + app_protocol_settings_changed_delegate_.Run(); } void WebAppTestRegistryObserverAdapter::SignalRunLoopAndStoreAppId(
diff --git a/chrome/browser/web_applications/test/web_app_test_observers.h b/chrome/browser/web_applications/test/web_app_test_observers.h index 4b42d63..e1e62323 100644 --- a/chrome/browser/web_applications/test/web_app_test_observers.h +++ b/chrome/browser/web_applications/test/web_app_test_observers.h
@@ -72,15 +72,9 @@ void SetWebAppLastBadgingTimeChangedDelegate( WebAppLastBadgingTimeChangedDelegate delegate); - using WebAppApprovedProtocolsChangedDelegate = - base::RepeatingCallback<void()>; - void SetWebAppApprovedProtocolsChangedDelegate( - WebAppApprovedProtocolsChangedDelegate delegate); - - using WebAppDisallowedProtocolsChangedDelegate = - base::RepeatingCallback<void()>; - void SetWebAppDisallowedProtocolsChangedDelegate( - WebAppDisallowedProtocolsChangedDelegate delegate); + using WebAppProtocolSettingsChangedDelegate = base::RepeatingCallback<void()>; + void SetWebAppProtocolSettingsChangedDelegate( + WebAppProtocolSettingsChangedDelegate delegate); // AppRegistrarObserver: void OnWebAppInstalled(const AppId& app_id) override; @@ -94,8 +88,7 @@ void OnWebAppProfileWillBeDeleted(const AppId& app_id) override; void OnWebAppLastBadgingTimeChanged(const web_app::AppId& app_id, const base::Time& time) override; - void OnWebAppApprovedProtocolsChanged() override; - void OnWebAppDisallowedProtocolsChanged() override; + void OnWebAppProtocolSettingsChanged() override; protected: // Helper method for subclasses to allow easy waiting on `wait_loop_`. @@ -118,10 +111,7 @@ WebAppWillBeUninstalledDelegate app_will_be_uninstalled_delegate_; WebAppProfileWillBeDeletedDelegate app_profile_will_be_deleted_delegate_; WebAppLastBadgingTimeChangedDelegate app_last_badging_time_changed_delegate_; - WebAppApprovedProtocolsChangedDelegate - app_approved_protocols_changed_delegate_; - WebAppDisallowedProtocolsChangedDelegate - app_disallowed_protocols_changed_delegate_; + WebAppProtocolSettingsChangedDelegate app_protocol_settings_changed_delegate_; base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver> observation_{ this};
diff --git a/chrome/browser/web_applications/web_app_protocol_handler_manager.cc b/chrome/browser/web_applications/web_app_protocol_handler_manager.cc index 861bdf2..dd8f680 100644 --- a/chrome/browser/web_applications/web_app_protocol_handler_manager.cc +++ b/chrome/browser/web_applications/web_app_protocol_handler_manager.cc
@@ -93,6 +93,30 @@ return protocol_handlers; } +std::vector<ProtocolHandler> +WebAppProtocolHandlerManager::GetApprovedHandlersForProtocol( + const std::string& protocol) const { + std::vector<ProtocolHandler> protocol_handlers; + + for (const WebApp& web_app : app_registrar_->GetApps()) { + web_app::AppId app_id = web_app.app_id(); + + if (!app_registrar_->IsApprovedLaunchProtocol(app_id, protocol)) + continue; + + for (const auto& info : web_app.protocol_handlers()) { + if (info.protocol != protocol) + continue; + + ProtocolHandler handler = ProtocolHandler::CreateWebAppProtocolHandler( + info.protocol, GURL(info.url), app_id); + protocol_handlers.push_back(handler); + } + } + + return protocol_handlers; +} + void WebAppProtocolHandlerManager::RegisterOsProtocolHandlers( const AppId& app_id, base::OnceCallback<void(bool)> callback) {
diff --git a/chrome/browser/web_applications/web_app_protocol_handler_manager.h b/chrome/browser/web_applications/web_app_protocol_handler_manager.h index 9fc766d..069c69d3 100644 --- a/chrome/browser/web_applications/web_app_protocol_handler_manager.h +++ b/chrome/browser/web_applications/web_app_protocol_handler_manager.h
@@ -40,10 +40,14 @@ absl::optional<GURL> TranslateProtocolUrl(const AppId& app_id, const GURL& protocol_url) const; - // Get the list of handlers for the given protocol. + // Gets the list of handlers for a given protocol. std::vector<ProtocolHandler> GetHandlersFor( const std::string& protocol) const; + // Gets the list of handlers with launch permissions for a given protocol. + std::vector<ProtocolHandler> GetApprovedHandlersForProtocol( + const std::string& protocol) const; + // Gets the protocol handlers for `app_id`. Any protocols that the user // has explicitly disallowed, will be excluded. // `virtual` for testing.
diff --git a/chrome/browser/web_applications/web_app_registrar.cc b/chrome/browser/web_applications/web_app_registrar.cc index ae253db..71c13e5 100644 --- a/chrome/browser/web_applications/web_app_registrar.cc +++ b/chrome/browser/web_applications/web_app_registrar.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/web_applications/web_app_registrar.h" +#include <algorithm> #include <utility> #include <vector> @@ -78,14 +79,9 @@ observers_.RemoveObserver(observer); } -void WebAppRegistrar::NotifyWebAppApprovedProtocolsChanged() { +void WebAppRegistrar::NotifyWebAppProtocolSettingsChanged() { for (AppRegistrarObserver& observer : observers_) - observer.OnWebAppApprovedProtocolsChanged(); -} - -void WebAppRegistrar::NotifyWebAppDisallowedProtocolsChanged() { - for (AppRegistrarObserver& observer : observers_) - observer.OnWebAppDisallowedProtocolsChanged(); + observer.OnWebAppProtocolSettingsChanged(); } void WebAppRegistrar::NotifyWebAppInstalled(const AppId& app_id) { @@ -477,6 +473,16 @@ protocol_scheme); } +base::flat_set<std::string> WebAppRegistrar::GetAllApprovedLaunchProtocols() + const { + base::flat_set<std::string> protocols; + for (const WebApp& web_app : GetApps()) { + protocols.insert(web_app.approved_launch_protocols().begin(), + web_app.approved_launch_protocols().end()); + } + return protocols; +} + int WebAppRegistrar::CountUserInstalledApps() const { int num_user_installed = 0; for (const WebApp& app : GetAppsIncludingStubs()) {
diff --git a/chrome/browser/web_applications/web_app_registrar.h b/chrome/browser/web_applications/web_app_registrar.h index e4e8bb92..6e953f8 100644 --- a/chrome/browser/web_applications/web_app_registrar.h +++ b/chrome/browser/web_applications/web_app_registrar.h
@@ -114,6 +114,9 @@ bool IsDisallowedLaunchProtocol(const AppId& app_id, std::string protocol_scheme) const; + // Gets all approved launch protocols from all installed apps. + base::flat_set<std::string> GetAllApprovedLaunchProtocols() const; + // Count a number of all apps which are installed by user (non-default). // Requires app registry to be in a ready state. int CountUserInstalledApps() const; @@ -227,11 +230,10 @@ void AddObserver(AppRegistrarObserver* observer); void RemoveObserver(AppRegistrarObserver* observer); - void NotifyWebAppApprovedProtocolsChanged(); - void NotifyWebAppDisallowedProtocolsChanged(); void NotifyWebAppInstalled(const AppId& app_id); void NotifyWebAppManifestUpdated(const AppId& app_id, base::StringPiece old_name); + void NotifyWebAppProtocolSettingsChanged(); void NotifyWebAppsWillBeUpdatedFromSync( const std::vector<const WebApp*>& new_apps_state); void NotifyWebAppUninstalled(const AppId& app_id);
diff --git a/chrome/browser/web_applications/web_app_registrar_unittest.cc b/chrome/browser/web_applications/web_app_registrar_unittest.cc index 14cf608..280fcce 100644 --- a/chrome/browser/web_applications/web_app_registrar_unittest.cc +++ b/chrome/browser/web_applications/web_app_registrar_unittest.cc
@@ -929,21 +929,44 @@ TEST_F(WebAppRegistrarTest, ApprovedLaunchProtocols) { controller().Init(); - auto web_app = test::CreateWebApp(); - const AppId app_id = web_app->app_id(); + auto web_app = test::CreateWebApp(GURL("https://example.com/path")); + const AppId app_id1 = web_app->app_id(); + const std::string protocol_scheme1 = "test"; RegisterApp(std::move(web_app)); - const std::string protocol_scheme = "test"; + auto web_app2 = test::CreateWebApp(GURL("https://example.com/path2")); + const AppId app_id2 = web_app2->app_id(); + const std::string protocol_scheme2 = "test2"; + RegisterApp(std::move(web_app2)); + + // Test we can add and remove approved protocols. EXPECT_EQ(false, - registrar().IsApprovedLaunchProtocol(app_id, protocol_scheme)); + registrar().IsApprovedLaunchProtocol(app_id1, protocol_scheme1)); - sync_bridge().AddApprovedLaunchProtocol(app_id, protocol_scheme); + sync_bridge().AddApprovedLaunchProtocol(app_id1, protocol_scheme1); EXPECT_EQ(true, - registrar().IsApprovedLaunchProtocol(app_id, protocol_scheme)); + registrar().IsApprovedLaunchProtocol(app_id1, protocol_scheme1)); - sync_bridge().RemoveApprovedLaunchProtocol(app_id, protocol_scheme); + sync_bridge().RemoveApprovedLaunchProtocol(app_id1, protocol_scheme1); EXPECT_EQ(false, - registrar().IsApprovedLaunchProtocol(app_id, protocol_scheme)); + registrar().IsApprovedLaunchProtocol(app_id1, protocol_scheme1)); + + // Test that we can get approved protocols from multiple web apps. + sync_bridge().AddApprovedLaunchProtocol(app_id1, protocol_scheme1); + sync_bridge().AddApprovedLaunchProtocol(app_id2, protocol_scheme2); + + { + auto approved_protocols = registrar().GetAllApprovedLaunchProtocols(); + EXPECT_TRUE(base::Contains(approved_protocols, protocol_scheme1)); + EXPECT_TRUE(base::Contains(approved_protocols, protocol_scheme2)); + + sync_bridge().RemoveApprovedLaunchProtocol(app_id2, protocol_scheme2); + } + { + auto approved_protocols = registrar().GetAllApprovedLaunchProtocols(); + EXPECT_TRUE(base::Contains(approved_protocols, protocol_scheme1)); + EXPECT_FALSE(base::Contains(approved_protocols, protocol_scheme2)); + } } TEST_F(WebAppRegistrarTest, DisallowedLaunchProtocols) {
diff --git a/chrome/browser/web_applications/web_app_sync_bridge.cc b/chrome/browser/web_applications/web_app_sync_bridge.cc index bc0d3e0..45f526b 100644 --- a/chrome/browser/web_applications/web_app_sync_bridge.cc +++ b/chrome/browser/web_applications/web_app_sync_bridge.cc
@@ -349,57 +349,77 @@ void WebAppSyncBridge::AddApprovedLaunchProtocol( const AppId& app_id, const std::string& protocol_scheme) { - ScopedRegistryUpdate update(this); - web_app::WebApp* app_to_update = update->UpdateApp(app_id); - base::flat_set<std::string> protocol_handlers( - app_to_update->approved_launch_protocols()); + // Use a scope here, so that the web app registry is updated when + // `update` goes out of scope. If it doesn't then observers will + // examine stale data. + { + ScopedRegistryUpdate update(this); + web_app::WebApp* app_to_update = update->UpdateApp(app_id); + base::flat_set<std::string> protocol_handlers( + app_to_update->approved_launch_protocols()); - DCHECK(!base::Contains(protocol_handlers, protocol_scheme)); - protocol_handlers.insert(protocol_scheme); - app_to_update->SetApprovedLaunchProtocols(std::move(protocol_handlers)); + DCHECK(!base::Contains(protocol_handlers, protocol_scheme)); + protocol_handlers.insert(protocol_scheme); + app_to_update->SetApprovedLaunchProtocols(std::move(protocol_handlers)); + } // Notify observers that the list of approved protocols was updated. - registrar_->NotifyWebAppApprovedProtocolsChanged(); + registrar_->NotifyWebAppProtocolSettingsChanged(); } void WebAppSyncBridge::RemoveApprovedLaunchProtocol( const AppId& app_id, const std::string& protocol_scheme) { - ScopedRegistryUpdate update(this); - web_app::WebApp* app_to_update = update->UpdateApp(app_id); - base::flat_set<std::string> protocol_handlers( - app_to_update->approved_launch_protocols()); - protocol_handlers.erase(protocol_scheme); - app_to_update->SetApprovedLaunchProtocols(std::move(protocol_handlers)); + // Use a scope here, so that the web app registry is updated when + // `update` goes out of scope. If it doesn't then observers will + // examine stale data. + { + ScopedRegistryUpdate update(this); + web_app::WebApp* app_to_update = update->UpdateApp(app_id); + base::flat_set<std::string> protocol_handlers( + app_to_update->approved_launch_protocols()); + protocol_handlers.erase(protocol_scheme); + app_to_update->SetApprovedLaunchProtocols(std::move(protocol_handlers)); + } // Notify observers that the list of approved protocols was updated. - registrar_->NotifyWebAppApprovedProtocolsChanged(); + registrar_->NotifyWebAppProtocolSettingsChanged(); } void WebAppSyncBridge::AddDisallowedLaunchProtocol( const AppId& app_id, const std::string& protocol_scheme) { - ScopedRegistryUpdate update(this); - web_app::WebApp* app_to_update = update->UpdateApp(app_id); - base::flat_set<std::string> protocol_handlers( - app_to_update->disallowed_launch_protocols()); + // Use a scope here, so that the web app registry is updated when + // `update` goes out of scope. If it doesn't then observers will + // examine stale data. + { + ScopedRegistryUpdate update(this); + web_app::WebApp* app_to_update = update->UpdateApp(app_id); + base::flat_set<std::string> protocol_handlers( + app_to_update->disallowed_launch_protocols()); - DCHECK(!base::Contains(protocol_handlers, protocol_scheme)); - protocol_handlers.insert(protocol_scheme); - app_to_update->SetDisallowedLaunchProtocols(std::move(protocol_handlers)); + DCHECK(!base::Contains(protocol_handlers, protocol_scheme)); + protocol_handlers.insert(protocol_scheme); + app_to_update->SetDisallowedLaunchProtocols(std::move(protocol_handlers)); + } // Notify observers that the list of disallowed protocols was updated. - registrar_->NotifyWebAppDisallowedProtocolsChanged(); + registrar_->NotifyWebAppProtocolSettingsChanged(); } void WebAppSyncBridge::RemoveDisallowedLaunchProtocol( const AppId& app_id, const std::string& protocol_scheme) { - ScopedRegistryUpdate update(this); - web_app::WebApp* app_to_update = update->UpdateApp(app_id); - base::flat_set<std::string> protocol_handlers( - app_to_update->disallowed_launch_protocols()); - protocol_handlers.erase(protocol_scheme); - app_to_update->SetDisallowedLaunchProtocols(std::move(protocol_handlers)); + // Use a scope here, so that the web app registry is updated when + // `update` goes out of scope. If it doesn't then observers will + // examine stale data. + { + ScopedRegistryUpdate update(this); + web_app::WebApp* app_to_update = update->UpdateApp(app_id); + base::flat_set<std::string> protocol_handlers( + app_to_update->disallowed_launch_protocols()); + protocol_handlers.erase(protocol_scheme); + app_to_update->SetDisallowedLaunchProtocols(std::move(protocol_handlers)); + } // Notify observers that the list of disallowed protocols was updated. - registrar_->NotifyWebAppDisallowedProtocolsChanged(); + registrar_->NotifyWebAppProtocolSettingsChanged(); } void WebAppSyncBridge::CheckRegistryUpdateData(
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index ea38df4..ecc7011 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1632287417-ac511baa87b0d6ac3bb26fdb93f5680e38a96d9f.profdata +chrome-linux-main-1632311929-cb3dc9d89600f38a2ad0bd6b7e36196324f593f3.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index c67a49f..1d593ae3 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1632287417-43f48902caa07e02109bac370cfac87feea03394.profdata +chrome-mac-main-1632311929-e14285d2cfbadc01189fb036e5b9a5705365af76.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 00ff3ef..a32d9f9 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1632279442-e119a820a19f6d33d16600e5a677626800a516ae.profdata +chrome-win32-main-1632311929-105d3e8781f17ca94ef572f4c77e012f35cfe9ac.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index b2d9e235..0048300 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1632279442-56f2d6d458ac4516b976e38482c24a9afd4e35dd.profdata +chrome-win64-main-1632311929-f09deebcdbfea1b7306092c75b6288d39cb8bac9.profdata
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index cdf4682..cae569ce 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1134,6 +1134,12 @@ // only using an account that belongs to one of the domains from this pref. const char kAllowedDomainsForApps[] = "settings.allowed_domains_for_apps"; +#if BUILDFLAG(IS_CHROMEOS_LACROS) +// A boolean pref that controls whether proxy settings from Ash-Chrome are +// applied or ignored. Always true for the primary profile. +const char kUseAshProxy[] = "lacros.proxy.use_ash_proxy"; +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete. #if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 1ff96143..e00513c 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -360,6 +360,9 @@ extern const char kForceGoogleSafeSearch[]; extern const char kForceYouTubeRestrict[]; extern const char kAllowedDomainsForApps[]; +#if BUILDFLAG(IS_CHROMEOS_LACROS) +extern const char kUseAshProxy[]; +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete. #if defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/installer/util/OWNERS b/chrome/installer/util/OWNERS new file mode 100644 index 0000000..90977f8 --- /dev/null +++ b/chrome/installer/util/OWNERS
@@ -0,0 +1,2 @@ +per-file shell_util*=davidbienvenu@chromium.org +per-file shell_util*=jessemckenna@google.com
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 394e0b4..0718709 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1256,6 +1256,7 @@ "//components/unified_consent", "//components/user_manager", "//components/variations/service", + "//components/variations/service:constants", "//components/webapps/browser", "//components/webrtc", "//components/webrtc_logging/browser", @@ -3982,6 +3983,7 @@ "../browser/lacros/media_session_lacros_browsertest.cc", "../browser/lacros/message_center_lacros_browsertest.cc", "../browser/lacros/metrics_reporting_lacros_browsertest.cc", + "../browser/lacros/net/proxy_config_service_lacros_browsertest.cc", "../browser/lacros/networking_attributes_lacros_browsertest.cc", "../browser/lacros/popup_lacros_browsertest.cc", "../browser/lacros/screen_manager_lacros_browsertest.cc", @@ -3996,6 +3998,7 @@ "//chromeos/services/machine_learning/public/cpp", "//chromeos/services/machine_learning/public/cpp:stub", "//chromeos/services/machine_learning/public/mojom", + "//components/proxy_config:proxy_config", "//ui/platform_window", ] @@ -6256,6 +6259,7 @@ "../browser/lacros/client_cert_store_lacros_unittest.cc", "../browser/lacros/lacros_memory_pressure_evaluator_unittest.cc", "../browser/lacros/metrics_reporting_observer_unittest.cc", + "../browser/lacros/net/network_settings_translation_unittest.cc", "../browser/lacros/prefs_ash_observer_unittest.cc", "../browser/metrics/lacros_metrics_provider_unittest.cc", "../browser/notifications/notification_platform_bridge_lacros_unittest.cc",
diff --git a/chrome/test/data/extensions/api_test/file_browser/app_file_handler_multi/manifest.json b/chrome/test/data/extensions/api_test/file_browser/app_file_handler_multi/manifest.json index 8fde887..1b42012 100644 --- a/chrome/test/data/extensions/api_test/file_browser/app_file_handler_multi/manifest.json +++ b/chrome/test/data/extensions/api_test/file_browser/app_file_handler_multi/manifest.json
@@ -13,6 +13,7 @@ "file_handlers": { "textAction": { "extensions": ["txt"], + "verb": "add_to", "include_directories": true } },
diff --git a/chrome/test/data/webui/chromeos/diagnostics/connectivity_card_test.js b/chrome/test/data/webui/chromeos/diagnostics/connectivity_card_test.js index 65eb43a..6edf101 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/connectivity_card_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/connectivity_card_test.js
@@ -158,22 +158,6 @@ }); }); - test( - 'ConnectivityCardPopulated', () => { - return initializeConnectivityCard('ethernetGuid').then(() => { - const ethernetInfoElement = dx_utils.getEthernetInfoElement( - connectivityCardElement.$$('network-info')); - const linkSpeedDataPoint = - dx_utils.getDataPoint(ethernetInfoElement, '#linkSpeed'); - assertTrue(isVisible(linkSpeedDataPoint)); - assertEquals(linkSpeedDataPoint.header, 'Link Speed'); - // TODO(ashleydp): Update expectation when link speed data added. - dx_utils.assertTextContains( - dx_utils.getDataPointValue(ethernetInfoElement, '#linkSpeed'), - ''); - }); - }); - test('TestsRunAutomaticallyWhenPageIsActive', () => { return initializeConnectivityCard('ethernetGuid', true) .then(
diff --git a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js index ccae1744..ac65e47b 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/diagnostics_app_test.js
@@ -108,7 +108,7 @@ fakeBatteryInfo, fakeCpuUsage, fakeMemoryUsage) .then(() => { const systemPage = - dx_utils.getNavigationViewPanelElement(page, 'overview'); + dx_utils.getNavigationViewPanelElement(page, 'system'); assertTrue(!!systemPage); assertTrue(isVisible(systemPage)); });
diff --git a/chrome/test/data/webui/chromeos/diagnostics/ethernet_info_test.js b/chrome/test/data/webui/chromeos/diagnostics/ethernet_info_test.js index 52d693d..cb186c8 100644 --- a/chrome/test/data/webui/chromeos/diagnostics/ethernet_info_test.js +++ b/chrome/test/data/webui/chromeos/diagnostics/ethernet_info_test.js
@@ -58,15 +58,6 @@ }); } - test('EthernetInfoPopulated', () => { - return initializeEthernetInfo(fakeEthernetNetwork).then(() => { - // Element expected on screen but data currently missing in api. - // TODO(ashleydp): Update test when link speed data-point value provided. - assertTextContains( - getDataPointValue(ethernetInfoElement, '#linkSpeed'), ''); - }); - }); - test('EthernetInfoIpAddressBasedOnNetwork', () => { return initializeEthernetInfo(fakeEthernetNetwork).then(() => { const expectedHeader = ethernetInfoElement.i18n('networkIpAddressLabel'); @@ -103,13 +94,4 @@ expectedValue); }); }); - - test('EthernetInfoLinkSpeedBasedOnNetwork', () => { - return initializeEthernetInfo(fakeEthernetNetwork).then(() => { - const expectedHeader = ethernetInfoElement.i18n('networkLinkSpeedLabel'); - // TODO(ashleydp): Update test when Ethernet link speed data provided. - assertDataPointHasExpectedHeaderAndValue( - ethernetInfoElement, '#linkSpeed', expectedHeader, ''); - }); - }); }
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn index 7487d16..d4ab1b9e 100644 --- a/chrome/test/data/webui/settings/BUILD.gn +++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -153,7 +153,6 @@ if (!is_chromeos_ash) { deps += [ ":fake_language_settings_private", - ":languages_page_metrics_test_browser", ":test_languages_browser_proxy", ] } @@ -188,19 +187,6 @@ ] } -js_library("languages_page_metrics_test_browser") { - deps = [ - ":fake_language_settings_private", - ":fake_settings_private", - ":test_languages_browser_proxy", - "..:chai_assert", - "..:test_util", - "//chrome/browser/resources/settings:lazy_load", - "//chrome/browser/resources/settings:settings", - ] - externs_list = [ "$externs_path/mocha-2.5.js" ] -} - js_library("privacy_sandbox_test") { deps = [ ":test_open_window_proxy",
diff --git a/chrome/test/data/webui/settings/chromeos/input_page_test.js b/chrome/test/data/webui/settings/chromeos/input_page_test.js index 11f3686a..658bc9a9c 100644 --- a/chrome/test/data/webui/settings/chromeos/input_page_test.js +++ b/chrome/test/data/webui/settings/chromeos/input_page_test.js
@@ -100,7 +100,7 @@ return CrSettingsPrefs.initialized.then(() => { // Set up test browser proxy. browserProxy = new settings.TestLanguagesBrowserProxy(); - settings.LanguagesBrowserProxyImpl.instance_ = browserProxy; + settings.LanguagesBrowserProxyImpl.setInstance(browserProxy); // Sets up test metrics proxy. metricsProxy = new settings.TestLanguagesMetricsProxy();
diff --git a/chrome/test/data/webui/settings/chromeos/os_edit_dictionary_page_test.js b/chrome/test/data/webui/settings/chromeos/os_edit_dictionary_page_test.js index fc6e2b4..1aaa186 100644 --- a/chrome/test/data/webui/settings/chromeos/os_edit_dictionary_page_test.js +++ b/chrome/test/data/webui/settings/chromeos/os_edit_dictionary_page_test.js
@@ -73,7 +73,7 @@ languageSettingsPrivate = new settings.FakeLanguageSettingsPrivate(); languageSettingsPrivate.setSettingsPrefs(settingsPrefs); const browserProxy = new settings.TestLanguagesBrowserProxy(); - settings.LanguagesBrowserProxyImpl.instance_ = browserProxy; + settings.LanguagesBrowserProxyImpl.setInstance(browserProxy); browserProxy.setLanguageSettingsPrivate(languageSettingsPrivate); editDictPage = document.createElement('os-settings-edit-dictionary-page');
diff --git a/chrome/test/data/webui/settings/chromeos/os_languages_page_v2_tests.js b/chrome/test/data/webui/settings/chromeos/os_languages_page_v2_tests.js index e0d5fa8..82ad9cd 100644 --- a/chrome/test/data/webui/settings/chromeos/os_languages_page_v2_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_languages_page_v2_tests.js
@@ -54,7 +54,7 @@ await CrSettingsPrefs.initialized; // Sets up test browser proxy. browserProxy = new settings.TestLanguagesBrowserProxy(); - settings.LanguagesBrowserProxyImpl.instance_ = browserProxy; + settings.LanguagesBrowserProxyImpl.setInstance(browserProxy); lifetimeProxy = new settings.TestLifetimeBrowserProxy(); settings.LifetimeBrowserProxyImpl.setInstance(lifetimeProxy);
diff --git a/chrome/test/data/webui/settings/edit_dictionary_page_test.js b/chrome/test/data/webui/settings/edit_dictionary_page_test.js index 1bbba15..55e31111 100644 --- a/chrome/test/data/webui/settings/edit_dictionary_page_test.js +++ b/chrome/test/data/webui/settings/edit_dictionary_page_test.js
@@ -59,7 +59,7 @@ languageSettingsPrivate = new FakeLanguageSettingsPrivate(); languageSettingsPrivate.setSettingsPrefs(settingsPrefs); const browserProxy = new TestLanguagesBrowserProxy(); - LanguagesBrowserProxyImpl.instance_ = browserProxy; + LanguagesBrowserProxyImpl.setInstance(browserProxy); browserProxy.setLanguageSettingsPrivate(languageSettingsPrivate); editDictPage = document.createElement('settings-edit-dictionary-page');
diff --git a/chrome/test/data/webui/settings/languages_page_metrics_test_browser.js b/chrome/test/data/webui/settings/languages_page_metrics_test_browser.js index 85677ba8..1d021e1 100644 --- a/chrome/test/data/webui/settings/languages_page_metrics_test_browser.js +++ b/chrome/test/data/webui/settings/languages_page_metrics_test_browser.js
@@ -4,7 +4,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {LanguageHelper, LanguagesBrowserProxyImpl, LanguageSettingsActionType, LanguageSettingsMetricsProxy, LanguageSettingsMetricsProxyImpl, LanguageSettingsPageImpressionType, SettingsLanguagesSubpageElement} from 'chrome://settings/lazy_load.js'; +import {LanguageHelper, LanguagesBrowserProxyImpl, LanguageSettingsActionType, LanguageSettingsMetricsProxyImpl, LanguageSettingsPageImpressionType, SettingsLanguagesSubpageElement} from 'chrome://settings/lazy_load.js'; import {CrSettingsPrefs} from 'chrome://settings/settings.js'; import {assertEquals, assertFalse, assertTrue} from '../chai_assert.js'; @@ -63,11 +63,12 @@ return CrSettingsPrefs.initialized.then(function() { // Sets up test browser proxy. browserProxy = new TestLanguagesBrowserProxy(); - LanguagesBrowserProxyImpl.instance_ = browserProxy; + LanguagesBrowserProxyImpl.setInstance(browserProxy); // Sets up test browser proxy. languageSettingsMetricsProxy = new TestLanguageSettingsMetricsProxy(); - LanguageSettingsMetricsProxyImpl.instance_ = languageSettingsMetricsProxy; + LanguageSettingsMetricsProxyImpl.setInstance( + languageSettingsMetricsProxy); // Sets up fake languageSettingsPrivate API. const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate();
diff --git a/chrome/test/data/webui/settings/languages_page_tests.js b/chrome/test/data/webui/settings/languages_page_tests.js index 10e2bbd..773550a 100644 --- a/chrome/test/data/webui/settings/languages_page_tests.js +++ b/chrome/test/data/webui/settings/languages_page_tests.js
@@ -51,7 +51,7 @@ return CrSettingsPrefs.initialized.then(function() { // Set up test browser proxy. browserProxy = new TestLanguagesBrowserProxy(); - LanguagesBrowserProxyImpl.instance_ = browserProxy; + LanguagesBrowserProxyImpl.setInstance(browserProxy); // Set up fake languageSettingsPrivate API. const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate(); @@ -374,7 +374,7 @@ return CrSettingsPrefs.initialized.then(function() { // Set up test browser proxy. browserProxy = new TestLanguagesBrowserProxy(); - LanguagesBrowserProxyImpl.instance_ = browserProxy; + LanguagesBrowserProxyImpl.setInstance(browserProxy); // Set up fake languageSettingsPrivate API. const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate();
diff --git a/chrome/test/data/webui/settings/languages_subpage_details_tests.js b/chrome/test/data/webui/settings/languages_subpage_details_tests.js index c880ab4..11cfb14c 100644 --- a/chrome/test/data/webui/settings/languages_subpage_details_tests.js +++ b/chrome/test/data/webui/settings/languages_subpage_details_tests.js
@@ -55,7 +55,7 @@ return CrSettingsPrefs.initialized.then(function() { // Set up test browser proxy. browserProxy = new TestLanguagesBrowserProxy(); - LanguagesBrowserProxyImpl.instance_ = browserProxy; + LanguagesBrowserProxyImpl.setInstance(browserProxy); // Set up fake languageSettingsPrivate API. const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate();
diff --git a/chrome/test/data/webui/settings/languages_subpage_tests.js b/chrome/test/data/webui/settings/languages_subpage_tests.js index 3bfc0c8d..f5a7b1d 100644 --- a/chrome/test/data/webui/settings/languages_subpage_tests.js +++ b/chrome/test/data/webui/settings/languages_subpage_tests.js
@@ -55,7 +55,7 @@ return CrSettingsPrefs.initialized.then(function() { // Set up test browser proxy. browserProxy = new TestLanguagesBrowserProxy(); - LanguagesBrowserProxyImpl.instance_ = browserProxy; + LanguagesBrowserProxyImpl.setInstance(browserProxy); // Set up fake languageSettingsPrivate API. const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate();
diff --git a/chrome/test/data/webui/settings/languages_tests.js b/chrome/test/data/webui/settings/languages_tests.js index 14789ab..fe6cde863 100644 --- a/chrome/test/data/webui/settings/languages_tests.js +++ b/chrome/test/data/webui/settings/languages_tests.js
@@ -44,7 +44,7 @@ // Setup test browser proxy. browserProxy = new TestLanguagesBrowserProxy(); - LanguagesBrowserProxyImpl.instance_ = browserProxy; + LanguagesBrowserProxyImpl.setInstance(browserProxy); // Setup fake languageSettingsPrivate API. const languageSettingsPrivate = browserProxy.getLanguageSettingsPrivate();
diff --git a/chrome/test/data/webui/settings/protocol_handlers_tests.js b/chrome/test/data/webui/settings/protocol_handlers_tests.js index cf752cb..f77a437 100644 --- a/chrome/test/data/webui/settings/protocol_handlers_tests.js +++ b/chrome/test/data/webui/settings/protocol_handlers_tests.js
@@ -55,7 +55,43 @@ ]; /** - * A list of IngnoredProtocolEntry fixtures. + * A list of AppProtocolEntry fixtures. + * @type {!Array<!AppProtocolEntry>} + */ + const appProtocols = [ + { + handlers: [{ + host: 'www.google.com', + protocol: 'mailto', + protocol_name: 'email', + spec: 'http://www.google.com/%s', + app_id: 'testID' + }], + protocol: 'mailto' + }, + { + handlers: [ + { + host: 'www.google1.com', + protocol: 'webcal', + protocol_name: 'web calendar', + spec: 'http://www.google1.com/%s', + app_id: 'testID1' + }, + { + host: 'www.google2.com', + protocol: 'webcal', + protocol_name: 'web calendar', + spec: 'http://www.google2.com/%s', + app_id: 'testID2' + } + ], + protocol: 'webcal' + } + ]; + + /** + * A list of IgnoredProtocolEntry fixtures. * @type {!Array<!HandlerEntry}>} */ const ignoredProtocols = [{ @@ -88,9 +124,10 @@ PolymerTest.clearBody(); testElement = document.createElement('protocol-handlers'); document.body.appendChild(testElement); - return browserProxy.whenCalled('observeProtocolHandlers').then(function() { - flush(); - }); + return browserProxy.whenCalled('observeAppProtocolHandlers') + .then(function() { + flush(); + }); } test('set protocol handlers default called', () => { @@ -227,4 +264,35 @@ assertEquals(ignoredProtocols[0].spec, url); }); }); + + test('non-empty web app protocols', async () => { + browserProxy.setAppApprovedProtocolHandlers(appProtocols); + await initPage(); + const listFrames = testElement.root.querySelectorAll('.list-frame'); + const listItems = testElement.root.querySelectorAll('.list-item'); + // There are two protocols: ["mailto", "webcal"]. + assertEquals(2, listFrames.length); + // There are three total handlers within the two protocols. + assertEquals(3, listItems.length); + + // Check that item hosts are rendered correctly. + const hosts = testElement.root.querySelectorAll('.protocol-host'); + assertEquals('www.google.com', hosts[0].textContent.trim()); + assertEquals('www.google1.com', hosts[1].textContent.trim()); + assertEquals('www.google2.com', hosts[2].textContent.trim()); + }); + + test('remove web app protocols', async () => { + browserProxy.setAppApprovedProtocolHandlers(appProtocols); + await initPage(); + // Remove the first app protocol + testElement.$$('#removeAppHandlerButton').click(); + const args = await browserProxy.whenCalled('removeAppApprovedHandler'); + + // BrowserProxy's handler is expected to be called with + // arguments as [protocol, url, app_id]. + assertEquals(appProtocols[0].protocol, args[0]); + assertEquals(appProtocols[0].handlers[0].spec, args[1]); + assertEquals(appProtocols[0].handlers[0].app_id, args[2]); + }); });
diff --git a/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js b/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js index 084df4a..f39af5d5 100644 --- a/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js +++ b/chrome/test/data/webui/settings/test_site_settings_prefs_browser_proxy.js
@@ -34,8 +34,10 @@ 'getOriginPermissions', 'isOriginValid', 'isPatternValidForType', + 'observeAppProtocolHandlers', 'observeProtocolHandlers', 'observeProtocolHandlersEnabledState', + 'removeAppApprovedHandler', 'removeIgnoredHandler', 'removeProtocolHandler', 'removeZoomLevel', @@ -95,6 +97,9 @@ /** @private {!Array<ZoomLevelEntry>} */ this.zoomList_ = []; + /** @private {!Array<!AppProtocolEntry>} */ + this.appApprovedProtocolHandlers_ = []; + /** @private {!Array<!ProtocolEntry>} */ this.protocolHandlers_ = []; @@ -203,6 +208,16 @@ /** * Sets the prefs to use when testing. + * @param {!Array<AppProtocolEntry>} list The web app protocol handlers + * list to set. + */ + setAppApprovedProtocolHandlers(list) { + // Shallow copy of the passed-in array so mutation won't impact the source + this.appApprovedProtocolHandlers_ = list.slice(); + } + + /** + * Sets the prefs to use when testing. * @param {!Array<!HandlerEntry>} list */ setIgnoredProtocols(list) { @@ -487,6 +502,14 @@ } /** @override */ + observeAppProtocolHandlers() { + webUIListenerCallback( + 'setAppApprovedProtocolHandlers', + this.appApprovedProtocolHandlers_); + this.methodCalled('observeAppProtocolHandlers'); + } + + /** @override */ observeProtocolHandlersEnabledState() { webUIListenerCallback('setHandlersEnabled', true); this.methodCalled('observeProtocolHandlersEnabledState'); @@ -501,6 +524,10 @@ removeProtocolHandler() { this.methodCalled('removeProtocolHandler', arguments); } + /** @override */ + removeAppApprovedHandler() { + this.methodCalled('removeAppApprovedHandler', arguments); + } /** @override */ updateIncognitoStatus() {
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 623fcd89..bffdcba 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -968,8 +968,8 @@ <message name="IDS_DIAGNOSTICS_TROUBLESHOOTING_TEXT" desc="The label for the text displayed when an internet network is not in a connected or connecting state."> No <ph name="NETWORK_NAME">$1<ex>Ethernet</ex></ph> connection detected </message> - <message name="IDS_DIAGNOSTICS_OVERVIEW" desc="The label for the overview navigation panel item."> - Overview + <message name="IDS_DIAGNOSTICS_SYSTEM" desc="The label for the system navigation panel item."> + System </message> <message name="IDS_DIAGNOSTICS_CONNECTIVITY" desc="The label for the connectivity navigation panel item."> Connectivity @@ -1731,9 +1731,6 @@ <message name="IDS_NETWORK_DIAGNOSTICS_AUTHENTICATION" desc="Label for `Authentication` type data-point in network card."> Authentication </message> - <message name="IDS_NETWORK_DIAGNOSTICS_LINK_SPEED" desc="Label for Ethernet `Link Speed` type data-point in network card."> - Link Speed - </message> <message name="IDS_NETWORK_DIAGNOSTICS_SECURITY" desc="Label for `Security` type data-point in network card."> Security </message>
diff --git a/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_OVERVIEW.png.sha1 b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_OVERVIEW.png.sha1 deleted file mode 100644 index 5a01d53..0000000 --- a/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_OVERVIEW.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -cc40055130fdba6aec5141fbb40958a2f5e2fae4 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_SYSTEM.png.sha1 b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_SYSTEM.png.sha1 new file mode 100644 index 0000000..882e4cc4 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_SYSTEM.png.sha1
@@ -0,0 +1 @@ +7cb3aeecce6c301f6e84537bf52b6ee8a9f6e743 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_LINK_SPEED.png.sha1 b/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_LINK_SPEED.png.sha1 deleted file mode 100644 index 2b0f10d0..0000000 --- a/chromeos/chromeos_strings_grd/IDS_NETWORK_DIAGNOSTICS_LINK_SPEED.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -6b976ea36225d92f0e5a7b5788f8cb73656a0795 \ No newline at end of file
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_gu.xtb b/chromeos/components/camera_app_ui/resources/strings/camera_strings_gu.xtb index 615f6fd..91c11304 100644 --- a/chromeos/components/camera_app_ui/resources/strings/camera_strings_gu.xtb +++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_gu.xtb
@@ -9,6 +9,7 @@ <translation id="1467231725790366244"><ph name="CAMERA" /> અનપ્લગ કરેલું છે.</translation> <translation id="1473110567575736769">3 સેકન્ડનું ટાઇમર</translation> <translation id="1545749641540134597">QR કોડ સ્કેન કરો</translation> +<translation id="1560052704389894104">GIF</translation> <translation id="1588438908519853928">સામાન્ય</translation> <translation id="1620510694547887537">કૅમેરો</translation> <translation id="1627744224761163218">4 x 4</translation> @@ -71,6 +72,7 @@ <translation id="520537883758714667">દસ્તાવેજ સ્કૅન કરવાની સુવિધા હવે ઉપલબ્ધ છે</translation> <translation id="5268823927180092501">બધા કૅમેરામાં 'દસ્તાવેજ મોડ' ચાલુ કરો</translation> <translation id="5444515100983837161">દસ્તાવેજના બધા ખૂણાઓને ફ્રેમની અંદર રાખો. જો દસ્તાવેજ અને બૅકગ્રાઉન્ડ અલગ-અલગ રંગોના હોય, તો સ્કૅન શ્રેષ્ઠ રીતે કામ કરે છે.</translation> +<translation id="5588258280684580073">GIF રેકોર્ડિંગ ચાલુ કરો</translation> <translation id="5671277269877808209">ચોરસ</translation> <translation id="5746169159649715125">PDF તરીકે સાચવો</translation> <translation id="5753488212459587150">નિષ્ણાત મોડ ચાલુ કરો</translation> @@ -98,12 +100,14 @@ <translation id="7243947652761655814">વીડિયો રિઝોલ્યુશન</translation> <translation id="7337660886763914220">ફાઇલ સિસ્ટમની ભૂલો.</translation> <translation id="7450541714075000668">ટેક્સ્ટ કૉપિ કરી</translation> +<translation id="7488619942230388918">GIF વીડિયો રેકોર્ડ કરો</translation> <translation id="7557677699350329807">આગલા કૅમેરા પર સ્વિચ કરો</translation> <translation id="7607002721634913082">થોભાવેલું</translation> <translation id="7608223098072244877">4 બાય 4</translation> <translation id="7649070708921625228">સહાય</translation> <translation id="7658239707568436148">રદ કરો</translation> <translation id="7670511624014457267">60 FPS</translation> +<translation id="7726641833034062494">સામાન્ય વીડિયો રેકોર્ડ કરો</translation> <translation id="7983668134180549431">ટેક્સ્ટની જાણકારી મળી.</translation> <translation id="8067883171444229417">વીડિયો ચલાવો</translation> <translation id="8120146556401698679">ફેરવો ટિલ્ટ કરો નાનું-મોટું કરો</translation>
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_ja.xtb b/chromeos/components/camera_app_ui/resources/strings/camera_strings_ja.xtb index 1ddabc3..68a29f9 100644 --- a/chromeos/components/camera_app_ui/resources/strings/camera_strings_ja.xtb +++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_ja.xtb
@@ -9,6 +9,7 @@ <translation id="1467231725790366244"><ph name="CAMERA" /> が外されました。</translation> <translation id="1473110567575736769">3 秒タイマー</translation> <translation id="1545749641540134597">QR コードをスキャンします</translation> +<translation id="1560052704389894104">GIF</translation> <translation id="1588438908519853928">ノーマル</translation> <translation id="1620510694547887537">カメラ</translation> <translation id="1627744224761163218">4x4</translation> @@ -71,6 +72,7 @@ <translation id="520537883758714667">ドキュメント スキャンをご利用いただけるようになりました</translation> <translation id="5268823927180092501">すべてのカメラでドキュメント モードを有効にする</translation> <translation id="5444515100983837161">ドキュメントのすべての端をフレーム内に収めてください。ドキュメントと背景を異なる色にすると、うまくスキャンできます。</translation> +<translation id="5588258280684580073">GIF の録画を有効にする</translation> <translation id="5671277269877808209">スクエア</translation> <translation id="5746169159649715125">PDF に保存</translation> <translation id="5753488212459587150">エキスパート モードを有効にする</translation> @@ -98,12 +100,14 @@ <translation id="7243947652761655814">動画の解像度</translation> <translation id="7337660886763914220">ファイル システムのエラーが発生しました。</translation> <translation id="7450541714075000668">テキストをコピーしました</translation> +<translation id="7488619942230388918">GIF 動画を録画する</translation> <translation id="7557677699350329807">次のカメラに切り替え</translation> <translation id="7607002721634913082">一時停止中</translation> <translation id="7608223098072244877">4x4</translation> <translation id="7649070708921625228">ヘルプ</translation> <translation id="7658239707568436148">キャンセル</translation> <translation id="7670511624014457267">60 FPS</translation> +<translation id="7726641833034062494">通常の動画を録画する</translation> <translation id="7983668134180549431">テキストが検出されました。</translation> <translation id="8067883171444229417">動画を再生します</translation> <translation id="8120146556401698679">パン、チルト、ズーム</translation>
diff --git a/chromeos/components/camera_app_ui/resources/strings/camera_strings_ta.xtb b/chromeos/components/camera_app_ui/resources/strings/camera_strings_ta.xtb index 25fa879..7c2bffd 100644 --- a/chromeos/components/camera_app_ui/resources/strings/camera_strings_ta.xtb +++ b/chromeos/components/camera_app_ui/resources/strings/camera_strings_ta.xtb
@@ -9,6 +9,7 @@ <translation id="1467231725790366244"><ph name="CAMERA" /> அகற்றப்பட்டது.</translation> <translation id="1473110567575736769">3 வினாடிகள் டைமர்</translation> <translation id="1545749641540134597">QR குறியீட்டை ஸ்கேன் செய்க</translation> +<translation id="1560052704389894104">GIF</translation> <translation id="1588438908519853928">இயல்பு</translation> <translation id="1620510694547887537">கேமரா</translation> <translation id="1627744224761163218">4 x 4</translation> @@ -71,6 +72,7 @@ <translation id="520537883758714667">இப்போது ஆவணத்தை ஸ்கேன் செய்யலாம்</translation> <translation id="5268823927180092501">அனைத்துக் கேமராவிலும் ஆவணப் பயன்முறையை இயக்கு</translation> <translation id="5444515100983837161">ஃபிரேமிற்குள் இருக்கும் வகையில் ஆவணத்தைச் சரிசெய்யவும். ஆவணமும் அதன் பின்புலமும் வெவ்வேறு வண்ணங்களாக இருந்தால் நன்றாக ஸ்கேன் செய்யலாம்.</translation> +<translation id="5588258280684580073">GIF ரெக்கார்டிங்கை இயக்கு</translation> <translation id="5671277269877808209">சதுரம்</translation> <translation id="5746169159649715125">PDFஆக சேமி</translation> <translation id="5753488212459587150">எக்ஸ்பெர்ட் பயன்முறையை இயக்கு</translation> @@ -98,12 +100,14 @@ <translation id="7243947652761655814">வீடியோ தெளிவுத்திறன்</translation> <translation id="7337660886763914220">ஃபைல் அமைப்புப் பிழைகள்.</translation> <translation id="7450541714075000668">உரை நகலெடுக்கப்பட்டது</translation> +<translation id="7488619942230388918">GIF வீடியோவை ரெக்கார்டு செய்யும்</translation> <translation id="7557677699350329807">அடுத்த கேமராவுக்கு மாறு</translation> <translation id="7607002721634913082">இடைநிறுத்தப்பட்டது</translation> <translation id="7608223098072244877">4 x 4</translation> <translation id="7649070708921625228">உதவி</translation> <translation id="7658239707568436148">ரத்து செய்</translation> <translation id="7670511624014457267">60 FPS</translation> +<translation id="7726641833034062494">சாதாரண வீடியோவை ரெக்கார்டு செய்யும்</translation> <translation id="7983668134180549431">உரை கண்டறியப்பட்டது.</translation> <translation id="8067883171444229417">வீடியோவை பிளே செய்</translation> <translation id="8120146556401698679">நகர்வு சாய்வு அளவை மாற்று</translation>
diff --git a/chromeos/crosapi/mojom/app_service_types.mojom b/chromeos/crosapi/mojom/app_service_types.mojom index 6e611bd..700c183 100644 --- a/chromeos/crosapi/mojom/app_service_types.mojom +++ b/chromeos/crosapi/mojom/app_service_types.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Next MinVersion: 6 +// Next MinVersion: 5 module crosapi.mojom; @@ -168,7 +168,6 @@ kGlob, kMimeType, [MinVersion=1] kFileExtension, - [MinVersion=5] kIsDirectory, }; // For pattern type of condition, the value match will be based on the pattern
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc index 64f6896..5adddc11 100644 --- a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc +++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
@@ -474,8 +474,6 @@ return crosapi::mojom::PatternMatchType::kMimeType; case apps::mojom::PatternMatchType::kFileExtension: return crosapi::mojom::PatternMatchType::kFileExtension; - case apps::mojom::PatternMatchType::kIsDirectory: - return crosapi::mojom::PatternMatchType::kIsDirectory; } NOTREACHED(); @@ -504,9 +502,6 @@ case crosapi::mojom::PatternMatchType::kFileExtension: *output = apps::mojom::PatternMatchType::kFileExtension; return true; - case crosapi::mojom::PatternMatchType::kIsDirectory: - *output = apps::mojom::PatternMatchType::kIsDirectory; - return true; } NOTREACHED();
diff --git a/chromeos/strings/chromeos_strings_am.xtb b/chromeos/strings/chromeos_strings_am.xtb index 4a2ccbda..5f33dac1 100644 --- a/chromeos/strings/chromeos_strings_am.xtb +++ b/chromeos/strings/chromeos_strings_am.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">አልተሳካም - ተቋርጧል</translation> <translation id="3102119246920354026">መሸጎጫ</translation> <translation id="3122464029669770682">ሲፒዩ</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{ገፅ ይወገድ?}=1{ገፅ {PAGE_NUMBER} ይወገድ?}one{ገፅ {PAGE_NUMBER} ይወገድ?}other{ገፅ {PAGE_NUMBER} ይወገድ?}}</translation> <translation id="315116470104423982">የተንቀሳቃሽ ስልክ ውሂብ</translation> <translation id="3156846309055100599">ገጽ <ph name="PAGE_NUMBER" />ን በመቃኘት ላይ...</translation> <translation id="315738237743207937">ተያዥ መግቢያ ተገኝቷል</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">ሲም ተቆልፏል (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">የቡድን ስም</translation> +<translation id="5051044138948155788">ይህ ብቸኛው ገጽ ነው። ይህ ወደ መቃኘት መጀመሪያው ማያ ገጽ ይወስደዎታል።</translation> <translation id="5088172560898466307">የአገልጋይ አስተናጋጅ ስም</translation> <translation id="5089810972385038852">ግዛት</translation> <translation id="5142961317498132443">ማረጋገጥ</translation> @@ -269,6 +271,7 @@ <translation id="5499114900554609492">ቅኝቱን ማጠናቀቅ አልተቻለም</translation> <translation id="5502931783115429516">Android እያሄደ አይደለም</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">ዳግም ቃኝ</translation> <translation id="5669267381087807207">በማግበር ላይ</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">ቤተሰብ</translation> @@ -319,6 +322,7 @@ <translation id="641081527798843608">የርዕሰ ጉዳይ ተዛማጅ</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">ጥሩ</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{ገጽ ዳግም ይቃኝ?}=1{ገጽ {PAGE_NUMBER} ዳግም ይቃኝ?}one{ገጽ {PAGE_NUMBER} ዳግም ይቃኝ?}other{ገጽ {PAGE_NUMBER} ዳግም ይቃኝ?}}</translation> <translation id="6472207088655375767">ኦቲፒ</translation> <translation id="6480327114083866287">በ<ph name="MANAGER" /> የሚተዳደር</translation> <translation id="649050271426829538">ቆሟል - የወረቀት መታጨቅ</translation>
diff --git a/chromeos/strings/chromeos_strings_as.xtb b/chromeos/strings/chromeos_strings_as.xtb index 4e1eadf..8880f59 100644 --- a/chromeos/strings/chromeos_strings_as.xtb +++ b/chromeos/strings/chromeos_strings_as.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">বিফল হৈছে - বন্ধ হৈছে</translation> <translation id="3102119246920354026">কেশ্ব</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{পৃষ্ঠাখন আঁতৰাবনে?}=1{{PAGE_NUMBER} নম্বৰ পৃষ্ঠাখন আঁতৰাবনে?}one{{PAGE_NUMBER} নম্বৰ পৃষ্ঠাখন আঁতৰাবনে?}other{{PAGE_NUMBER} নম্বৰ পৃষ্ঠাখন আঁতৰাবনে?}}</translation> <translation id="315116470104423982">ম’বাইল ডেটা</translation> <translation id="3156846309055100599"><ph name="PAGE_NUMBER" /> নম্বৰৰ পৃষ্ঠাখন স্কেন কৰি থকা হৈছে…</translation> <translation id="315738237743207937">কেপ্টিভ প’ৰ্টেল চিনাক্ত কৰা হৈছে</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">ছিম লক কৰা হ’ল (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">গোটৰ নাম</translation> +<translation id="5051044138948155788">এইখনেই একমাত্ৰ পৃষ্ঠা। এইটোৱে আপোনাক স্কেন আৰম্ভ হোৱা পৃষ্ঠাখনলৈ লৈ যাব।</translation> <translation id="5088172560898466307">ছার্ভাৰ হ‘ষ্টনে‘ম</translation> <translation id="5089810972385038852">ৰাজ্য</translation> <translation id="5142961317498132443">বিশ্বাসযোগ্যতাৰ প্ৰমাণীকৰণ</translation> @@ -269,6 +271,7 @@ <translation id="5499114900554609492">স্কেন সম্পূৰ্ণ কৰিব পৰা নগ’ল</translation> <translation id="5502931783115429516">Android চলি থকা নাই</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">পুনৰ স্কেন কৰক</translation> <translation id="5669267381087807207">সক্ৰিয় কৰা হৈছে</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">পৰিয়াল</translation> @@ -319,6 +322,7 @@ <translation id="641081527798843608">বিষয়ৰ মিল</translation> <translation id="6423239382391657905">VPN খোলক</translation> <translation id="6456394469623773452">ভাল</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{পৃষ্ঠাখন পুনৰ স্কেন কৰিবনে?}=1{{PAGE_NUMBER} নম্বৰ পৃষ্ঠাখন পুনৰ স্কেন কৰিবনে?}one{{PAGE_NUMBER} নম্বৰ পৃষ্ঠাখন পুনৰ স্কেন কৰিবনে?}other{{PAGE_NUMBER} নম্বৰ পৃষ্ঠাখন পুনৰ স্কেন কৰিবনে?}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287"><ph name="MANAGER" />এ পৰিচালনা কৰে</translation> <translation id="649050271426829538">বন্ধ হৈছে - কাগজ ঠাহ খাই গৈছে</translation>
diff --git a/chromeos/strings/chromeos_strings_az.xtb b/chromeos/strings/chromeos_strings_az.xtb index b41168c..5e8b3c63 100644 --- a/chromeos/strings/chromeos_strings_az.xtb +++ b/chromeos/strings/chromeos_strings_az.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">Alınmadı - Dayandırılıb</translation> <translation id="3102119246920354026">Keş</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{Səhifə silinsin?}=1{{PAGE_NUMBER} saylı səhifə silinsin?}other{{PAGE_NUMBER} saylı səhifə silinsin?}}</translation> <translation id="315116470104423982">Mobil data</translation> <translation id="3156846309055100599"><ph name="PAGE_NUMBER" /> saylı səhifə skanlanır...</translation> <translation id="315738237743207937">Avtorizasiya portalı aşkarlanıb</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">SIM Kilidlənib (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">Qrup adı</translation> +<translation id="5051044138948155788">Bu, yeganə səhifədir. Bu, sizi skanlamanı başlatma ekranına aparacaq.</translation> <translation id="5088172560898466307">Serverin host adı</translation> <translation id="5089810972385038852">Dövlət</translation> <translation id="5142961317498132443">İdentifikasiya</translation> @@ -268,6 +270,7 @@ <translation id="5499114900554609492">Skanı tamamlamaq olmadı</translation> <translation id="5502931783115429516">Android işləmir</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">Yenidən skan edin</translation> <translation id="5669267381087807207">Aktivləşir</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">Ailə</translation> @@ -318,6 +321,7 @@ <translation id="641081527798843608">Subyekt uyğunluğu</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">Yaxşı</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{Səhifə yenidən skanlansın?}=1{{PAGE_NUMBER} saylı səhifə yenidən skanlansın?}other{{PAGE_NUMBER} saylı səhifə yenidən skanlansın?}}</translation> <translation id="6472207088655375767">Birdəfəlik parol (OTP)</translation> <translation id="6480327114083866287"><ph name="MANAGER" /> tərəfindən idarə edilir</translation> <translation id="649050271426829538">Dayanıb - Kağız ilişib</translation>
diff --git a/chromeos/strings/chromeos_strings_cs.xtb b/chromeos/strings/chromeos_strings_cs.xtb index 928c50f..fea0b2f 100644 --- a/chromeos/strings/chromeos_strings_cs.xtb +++ b/chromeos/strings/chromeos_strings_cs.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">Tisk selhal – zastaveno</translation> <translation id="3102119246920354026">Mezipaměť</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{Odstranit stránku?}=1{Odstranit stránku {PAGE_NUMBER}?}few{Odstranit stránku {PAGE_NUMBER}?}many{Odstranit stránku {PAGE_NUMBER}?}other{Odstranit stránku {PAGE_NUMBER}?}}</translation> <translation id="315116470104423982">Mobilní datové přenosy</translation> <translation id="3156846309055100599">Skenování stránky <ph name="PAGE_NUMBER" />…</translation> <translation id="315738237743207937">Byl nalezen captive portál</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">Zamknutá SIM karta (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">Název skupiny</translation> +<translation id="5051044138948155788">Toto je jediná stránka. Touto akcí přejdete na obrazovku zahájení skenování.</translation> <translation id="5088172560898466307">Název hostitele serveru</translation> <translation id="5089810972385038852">Stát/kraj</translation> <translation id="5142961317498132443">Ověření</translation> @@ -269,6 +271,7 @@ <translation id="5499114900554609492">Skenování se nepodařilo dokončit</translation> <translation id="5502931783115429516">Android neběží</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">Naskenovat znovu</translation> <translation id="5669267381087807207">Aktivování</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">Rodina</translation> @@ -319,6 +322,7 @@ <translation id="641081527798843608">Shoda předmětu</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">Průměrný</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{Znovu naskenovat stránku?}=1{Znovu naskenovat stránku {PAGE_NUMBER}?}few{Znovu naskenovat stránku {PAGE_NUMBER}?}many{Znovu naskenovat stránku {PAGE_NUMBER}?}other{Znovu naskenovat stránku {PAGE_NUMBER}?}}</translation> <translation id="6472207088655375767">Jednorázové heslo</translation> <translation id="6480327114083866287">Spravováno doménou <ph name="MANAGER" /></translation> <translation id="649050271426829538">Zastaveno – zasekl se papír</translation>
diff --git a/chromeos/strings/chromeos_strings_de.xtb b/chromeos/strings/chromeos_strings_de.xtb index 1f7c3ef..a6739a1 100644 --- a/chromeos/strings/chromeos_strings_de.xtb +++ b/chromeos/strings/chromeos_strings_de.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">Fehlgeschlagen – Angehalten</translation> <translation id="3102119246920354026">Cache</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{Seite entfernen?}=1{Seite {PAGE_NUMBER} entfernen?}other{Seite {PAGE_NUMBER} entfernen?}}</translation> <translation id="315116470104423982">Mobile Daten</translation> <translation id="3156846309055100599">Seite <ph name="PAGE_NUMBER" /> wird gescannt…</translation> <translation id="315738237743207937">Captive Portal erkannt</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">SIM-Karte gesperrt (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">Gruppenname</translation> +<translation id="5051044138948155788">Das ist die einzige Seite. Sie gelangen dann zum Startbildschirm für den Scanvorgang.</translation> <translation id="5088172560898466307">Hostname des Servers</translation> <translation id="5089810972385038852">Bundesstaat</translation> <translation id="5142961317498132443">Authentifizierung</translation> @@ -269,6 +271,7 @@ <translation id="5499114900554609492">Scanvorgang konnte nicht abgeschlossen werden</translation> <translation id="5502931783115429516">Android wird nicht ausgeführt</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">Neu scannen</translation> <translation id="5669267381087807207">Wird aktiviert</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">Familie</translation> @@ -319,6 +322,7 @@ <translation id="641081527798843608">subject-match</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">In Ordnung</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{Seite neu scannen?}=1{Seite {PAGE_NUMBER} neu scannen?}other{Seite {PAGE_NUMBER} neu scannen?}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287">Verwaltet von <ph name="MANAGER" /></translation> <translation id="649050271426829538">Angehalten – Papierstau</translation>
diff --git a/chromeos/strings/chromeos_strings_fa.xtb b/chromeos/strings/chromeos_strings_fa.xtb index 3f29414..128ddebbb 100644 --- a/chromeos/strings/chromeos_strings_fa.xtb +++ b/chromeos/strings/chromeos_strings_fa.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">انجام نشد - متوقف شده است</translation> <translation id="3102119246920354026">حافظه پنهان</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{صفحه حذف شود؟}=1{{PAGE_NUMBER} صفحه حذف شود؟}one{{PAGE_NUMBER} صفحه حذف شود؟}other{{PAGE_NUMBER} صفحه حذف شود؟}}</translation> <translation id="315116470104423982">دادههای تلفن همراه</translation> <translation id="3156846309055100599">درحال اسکن کردن صفحه <ph name="PAGE_NUMBER" />…</translation> <translation id="315738237743207937">درگاه مهمان شناسایی شد</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">سیمکارت قفل است (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">نام گروه</translation> +<translation id="5051044138948155788">فقط این صفحه باقی مانده است. با این کار، به صفحه شروع اسکن هدایت میشوید.</translation> <translation id="5088172560898466307">نام سرور میزبان</translation> <translation id="5089810972385038852">ایالت</translation> <translation id="5142961317498132443">اصالتسنجی</translation> @@ -269,6 +271,7 @@ <translation id="5499114900554609492">اسکن کامل نشد</translation> <translation id="5502931783115429516">Android اجرا نمیشود</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">اسکن مجدد</translation> <translation id="5669267381087807207">فعالسازی</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">خانواده</translation> @@ -319,6 +322,7 @@ <translation id="641081527798843608">مطابقت موضوع</translation> <translation id="6423239382391657905">باز کردن VPN</translation> <translation id="6456394469623773452">عالی</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{صفحه مجدداً اسکن شود؟}=1{{PAGE_NUMBER} صفحه مجدداً اسکن شود؟}one{{PAGE_NUMBER} صفحه مجدداً اسکن شود؟}other{{PAGE_NUMBER} صفحه مجدداً اسکن شود؟}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287">تحت مدیریت <ph name="MANAGER" /></translation> <translation id="649050271426829538">متوقف شد - کاغذ گیر کرده است</translation>
diff --git a/chromeos/strings/chromeos_strings_fr-CA.xtb b/chromeos/strings/chromeos_strings_fr-CA.xtb index e69dc63..5a279bf4 100644 --- a/chromeos/strings/chromeos_strings_fr-CA.xtb +++ b/chromeos/strings/chromeos_strings_fr-CA.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">Échec : imprimante arrêtée</translation> <translation id="3102119246920354026">Cache</translation> <translation id="3122464029669770682">Processeur</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{Retirer la page?}=1{Retirer la page {PAGE_NUMBER}?}one{Retirer la page {PAGE_NUMBER}?}other{Retirer la page {PAGE_NUMBER}?}}</translation> <translation id="315116470104423982">Données mobiles</translation> <translation id="3156846309055100599">Numérisation de la page <ph name="PAGE_NUMBER" /> en cours…</translation> <translation id="315738237743207937">Un portail captif a été détecté</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">Carte SIM verrouillée (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">Nom du groupe</translation> +<translation id="5051044138948155788">C'est la seule page. Cette action vous redirigera vers l'écran du lancement de la numérisation.</translation> <translation id="5088172560898466307">Nom d'hôte du serveur</translation> <translation id="5089810972385038852">État/province</translation> <translation id="5142961317498132443">Authentification</translation> @@ -269,6 +271,7 @@ <translation id="5499114900554609492">Impossible de terminer la numérisation</translation> <translation id="5502931783115429516">Android n'est pas en cours d'exécution</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">Numériser de nouveau</translation> <translation id="5669267381087807207">Activation…</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">Famille</translation> @@ -319,6 +322,7 @@ <translation id="641081527798843608">Correspondance d'objet</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">Acceptable</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{Numériser de nouveau la page?}=1{Numériser de nouveau la page {PAGE_NUMBER}?}one{Numériser de nouveau la page {PAGE_NUMBER}?}other{Numériser de nouveau les pages {PAGE_NUMBER}?}}</translation> <translation id="6472207088655375767">Phr passe usage uniq</translation> <translation id="6480327114083866287">Géré par <ph name="MANAGER" /></translation> <translation id="649050271426829538">Tâche arrêtée : bourrage de papier</translation>
diff --git a/chromeos/strings/chromeos_strings_gu.xtb b/chromeos/strings/chromeos_strings_gu.xtb index 02391eddd..9e98558 100644 --- a/chromeos/strings/chromeos_strings_gu.xtb +++ b/chromeos/strings/chromeos_strings_gu.xtb
@@ -57,6 +57,7 @@ <translation id="1908234395526491708">UDP વિનંતી નિષ્ફળ થઈ</translation> <translation id="1930797645656624981">Chrome OS ઇનપુટ પદ્ધતિ સેવા</translation> <translation id="1947737735496445907">પ્રિન્ટ થઈ ગયું</translation> +<translation id="197386857804679933">ફરીથી કનેક્ટ કરવા માટે, સેટિંગ પર જાઓ</translation> <translation id="1979103255016296513">પાસવર્ડ બદલવાની તારીખ નીકળી ગઈ છે</translation> <translation id="1999615961760456652">કૅપ્ટિવ પોર્ટલ</translation> <translation id="2006864819935886708">કનેક્ટિવિટી</translation> @@ -96,6 +97,7 @@ <translation id="2783010256799387990">પરીક્ષણ પાસ કર્યુ</translation> <translation id="2789486458103222910">બરાબર, સમજાઇ ગયું</translation> <translation id="2805756323405976993">ઍપ</translation> +<translation id="2860473693272905224">બીજા પેજને સ્કૅનર પર મૂકો</translation> <translation id="2872961005593481000">શટ ડાઉન કરો</translation> <translation id="2878387241690264070"><ph name="NUM_SECONDS" /> સેકન્ડમાં <ph name="RATE" /> ડિસ્ચાર્જ.</translation> <translation id="3008341117444806826">રિફ્રેશ કરો</translation> @@ -110,6 +112,7 @@ <translation id="315116470104423982">મોબાઇલ ડેટા</translation> <translation id="3156846309055100599"><ph name="PAGE_NUMBER" /> નંબરનું પેજ સ્કૅન કરી રહ્યાં છીએ...</translation> <translation id="315738237743207937">કૅપ્ટિવ પોર્ટલની જાણકારી મળી</translation> +<translation id="3170673040743561620">તમારા દસ્તાવેજને સ્કૅનર પર મૂકો</translation> <translation id="3188257591659621405">મારી ફાઇલો</translation> <translation id="3199982728237701504">દસ્તાવેજનું ફીડર (બન્ને બાજુથી)</translation> <translation id="3226405216343213872">સ્કૅનર શોધી રહ્યાં છીએ</translation> @@ -210,6 +213,7 @@ <translation id="4813345808229079766">કનેક્શન</translation> <translation id="4832079907277790330">Files ઍપમાં ફોલ્ડર પસંદ કરો...</translation> <translation id="4835901797422965222">કોઈ નેટવર્ક સક્રિય નથી</translation> +<translation id="484790837831576105">(Android) DNS રિઝોલ્યુશન</translation> <translation id="4848429997038228357">ચાલુ છે</translation> <translation id="4861758251032006121">{ATTEMPTS_LEFT,plural, =1{<ph name="ERROR_MESSAGE" /> {0} પ્રયત્ન બાકી}one{<ph name="ERROR_MESSAGE" /> {0} પ્રયત્ન બાકી}other{<ph name="ERROR_MESSAGE" /> {0} પ્રયત્ન બાકી}}</translation> <translation id="4880328057631981605">ઍક્સેસ પૉઇન્ટનું નામ</translation> @@ -289,6 +293,7 @@ <translation id="6050189528197190982">ગ્રેસ્કેલ</translation> <translation id="6058625436358447366">સમાપ્ત કરવા માટે, તમારા જૂના અને નવા પાસવર્ડ દાખલ કરો</translation> <translation id="6061772781719867950">HTTPSની નિષ્ફળ વિનંતીઓ</translation> +<translation id="6075872808778243331">(Android) HTTPની વિલંબતા</translation> <translation id="6104112872696127344">સ્કૅન કરવાનું કાર્ય રદ કરવામાં આવ્યું છે</translation> <translation id="6106186594183574873">સમાપ્ત કરવા માટે, તમારો જૂનો પાસવર્ડ દાખલ કરો</translation> <translation id="6108689792487843350">ગેટવેથી કનેક્ટ કરી શકાતું નથી</translation> @@ -331,6 +336,7 @@ <translation id="6643016212128521049">સાફ કરો</translation> <translation id="6657585470893396449">પાસવર્ડ</translation> <translation id="6704062477274546131">DNSનો ઉકેલ</translation> +<translation id="6714650824879092633"><ph name="NETWORK_NAME" /> બંધ કરવામાં આવ્યું છે</translation> <translation id="6747215703636344499">બંધ - આઉટપુટ ભરાઈ ગયું છે</translation> <translation id="6756731097889387912">સ્કૅન કરવાનું કાર્ય રદ કરી શક્યા નથી</translation> <translation id="6766275201586212568">નિષ્ફળ રહેલા DNS રિઝોલ્યુશન</translation> @@ -340,11 +346,13 @@ <translation id="6910312834584889076">સ્કૅનરનું કવર ખુલ્લું છે. કવર બંધ કરો અને ફરી પ્રયાસ કરો.</translation> <translation id="6911383237894364323">મીડિયા સર્વર સાથે કનેક્ટ કરી શકાયું નથી</translation> <translation id="6957231940976260713">સેવાનું નામ</translation> +<translation id="6961170852793647506">શરૂ કરવા માટે, તમારા દસ્તાવેજને સ્કૅનર પર મૂકો</translation> <translation id="6977381486153291903">ફર્મવેયર પુનરાવર્તન</translation> <translation id="6982876849933694860">નવા કનેક્શનનું સેટઅપ કરવા માટે, <ph name="BEGIN_LINK" />સેટિંગ<ph name="END_LINK" /> પર જાઓ.</translation> <translation id="7028979494427204405"><ph name="MANAGER" /> આ ડિવાઇસને મેનેજ કરે છે અને મુલાકાત લીધેલા વેબપેજ, પાસવર્ડ અને ઇમેઇલ સહિત, બધી વપરાશકર્તા પ્રવૃત્તિઓનો ઍક્સેસ ધરાવે છે.</translation> <translation id="7039041976777695848"><ph name="CONNECTION_TYPE" /> કીબોર્ડ</translation> <translation id="7040230719604914234">ઑપરેટર</translation> +<translation id="7058278511608979688">બંધ કરો અને સાચવો</translation> <translation id="7059230779847288458">ચાર્જ થઈ રહી છે, પૂર્ણ ચાર્જ થવામાં <ph name="TIME_VALUE" /> બાકી</translation> <translation id="708426984172631313">રોકવામાં આવ્યું</translation> <translation id="7086440545492620869"><ph name="VALUE" /> <ph name="DISPLAY_NAME" /></translation> @@ -408,6 +416,7 @@ <translation id="8041089156583427627">પ્રતિસાદ મોકલો</translation> <translation id="8075838845814659848">બાકી રહેલું બૅટરી ચાર્જિંગ</translation> <translation id="808894953321890993">પાસવર્ડ બદલો</translation> +<translation id="811820734797650957">(Android) ગેટવેને પિંગ કરી શકાય છે</translation> <translation id="8129620843620772246"><ph name="TEMPERATURE_C" />° C</translation> <translation id="8132480444149501833">ટ્રાફિક કાઉન્ટરની વિનંતી કરો</translation> <translation id="8206859287963243715">સેલ્યુલર</translation> @@ -479,6 +488,7 @@ <translation id="910415269708673980"><ph name="PRINCIPAL_NAME" /> માટે ટિકિટ રિફ્રેશ કરો</translation> <translation id="9106415115617144481"><ph name="PAGE_NUMBER" /> નંબરનું પેજ સ્કૅન કરી રહ્યાં છીએ</translation> <translation id="9111102763498581341">અનલોક કરો</translation> +<translation id="9126720536733509015">એક PDFમાં એકથી વધુ પેજ સાચવો</translation> <translation id="9137526406337347448">Google સેવાઓ</translation> <translation id="9149391708638971077">મેમરીનું પરીક્ષણ ચાલુ કરો</translation> <translation id="9173638680043580060">એક મિનિટ કરતાં ઓછો સમય બાકી છે</translation>
diff --git a/chromeos/strings/chromeos_strings_hy.xtb b/chromeos/strings/chromeos_strings_hy.xtb index ae19cc20..955f676b 100644 --- a/chromeos/strings/chromeos_strings_hy.xtb +++ b/chromeos/strings/chromeos_strings_hy.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">Չհաջողվեց տպել – Տպիչի աշխատանքը դադարեցվել է</translation> <translation id="3102119246920354026">Հիշապահեստ</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{Հեռացնե՞լ էջը}=1{Հեռացնե՞լ էջ {PAGE_NUMBER}-ը}one{Հեռացնե՞լ էջ {PAGE_NUMBER}-ը}other{Հեռացնե՞լ էջ {PAGE_NUMBER}-ը}}</translation> <translation id="315116470104423982">Բջջային կապի տվյալներ</translation> <translation id="3156846309055100599">Սկանավորվում է էջ <ph name="PAGE_NUMBER" />-ը...</translation> <translation id="315738237743207937">Հայտնաբերվել է մուտքի էջ</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">SIM քարտը կողպված է (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">Խմբի անունը</translation> +<translation id="5051044138948155788">Սա միակ էջն է։ Դուք կվերահղվեք սկանավորման մեկնարկի էջ։</translation> <translation id="5088172560898466307">Սերվերի խնամորդի անուն</translation> <translation id="5089810972385038852">Նահանգ</translation> <translation id="5142961317498132443">Նույնականացում</translation> @@ -269,6 +271,7 @@ <translation id="5499114900554609492">Չհաջողվեց ավարտել սկանավորումը</translation> <translation id="5502931783115429516">Android-ը չի աշխատում</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">Նորից սկանավորել</translation> <translation id="5669267381087807207">Ակտիվացում</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">Ընտանիք</translation> @@ -319,6 +322,7 @@ <translation id="641081527798843608">Թեմաների համընկնում</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">Լավ</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{Նորից սկանավորե՞լ էջը}=1{Նորից սկանավորե՞լ էջ {PAGE_NUMBER}-ը}one{Նորից սկանավորե՞լ էջ {PAGE_NUMBER}-ը}other{Նորից սկանավորե՞լ էջ {PAGE_NUMBER}-ը}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287">Ադմինիստրատոր՝ <ph name="MANAGER" /></translation> <translation id="649050271426829538">Դադարեցվել է – Թղթի խցանում</translation>
diff --git a/chromeos/strings/chromeos_strings_iw.xtb b/chromeos/strings/chromeos_strings_iw.xtb index ca78652b..56f0c5f 100644 --- a/chromeos/strings/chromeos_strings_iw.xtb +++ b/chromeos/strings/chromeos_strings_iw.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">נכשלה – משימת ההדפסה הופסקה</translation> <translation id="3102119246920354026">מטמון</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{להסיר את הדף?}=1{להסיר את דף {PAGE_NUMBER}?}two{להסיר את דף {PAGE_NUMBER}?}many{להסיר את דף {PAGE_NUMBER}?}other{להסיר את דף {PAGE_NUMBER}?}}</translation> <translation id="315116470104423982">נתוני נייד</translation> <translation id="3156846309055100599">מתבצעת סריקה של עמוד <ph name="PAGE_NUMBER" />...</translation> <translation id="315738237743207937">זוהה פורטל שבוי</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">כרטיס ה-SIM נעול (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">שם הקבוצה</translation> +<translation id="5051044138948155788">זהו הדף היחיד. פעולה זו תעביר אותך אל מסך ההתחלה של הסריקה.</translation> <translation id="5088172560898466307">שם מארח של שרת</translation> <translation id="5089810972385038852">מדינה</translation> <translation id="5142961317498132443">אימות</translation> @@ -269,6 +271,7 @@ <translation id="5499114900554609492">לא ניתן היה להשלים את הסריקה</translation> <translation id="5502931783115429516">מערכת Android לא פועלת</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">סריקה מחדש</translation> <translation id="5669267381087807207">ההפעלה מתבצעת</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">משפחה</translation> @@ -319,6 +322,7 @@ <translation id="641081527798843608">התאמת נושא</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">טוב</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{לסרוק את הדף מחדש?}=1{לסרוק מחדש את דף {PAGE_NUMBER}?}two{לסרוק מחדש את דף {PAGE_NUMBER}?}many{לסרוק מחדש את דף {PAGE_NUMBER}?}other{לסרוק מחדש את דף {PAGE_NUMBER}?}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287">מנוהל על ידי <ph name="MANAGER" /></translation> <translation id="649050271426829538">הפסיקה – חסימת נייר</translation>
diff --git a/chromeos/strings/chromeos_strings_ja.xtb b/chromeos/strings/chromeos_strings_ja.xtb index a1f4b9a..8628b280 100644 --- a/chromeos/strings/chromeos_strings_ja.xtb +++ b/chromeos/strings/chromeos_strings_ja.xtb
@@ -57,6 +57,7 @@ <translation id="1908234395526491708">UDP リクエストに失敗しました</translation> <translation id="1930797645656624981">Chrome OS の入力方法サービス</translation> <translation id="1947737735496445907">印刷完了</translation> +<translation id="197386857804679933">再接続するには [設定] に移動してください</translation> <translation id="1979103255016296513">パスワードの変更期限を過ぎました</translation> <translation id="1999615961760456652">キャプティブ ポータル</translation> <translation id="2006864819935886708">接続</translation> @@ -96,6 +97,7 @@ <translation id="2783010256799387990">合格</translation> <translation id="2789486458103222910">OK</translation> <translation id="2805756323405976993">アプリ</translation> +<translation id="2860473693272905224">スキャナに次のページを置いてください</translation> <translation id="2872961005593481000">終了</translation> <translation id="2878387241690264070"><ph name="NUM_SECONDS" /> 秒で <ph name="RATE" /> 放電しました。</translation> <translation id="3008341117444806826">更新</translation> @@ -107,9 +109,11 @@ <translation id="3091839911843451378">失敗 - 停止中です</translation> <translation id="3102119246920354026">キャッシュ</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{ページを削除しますか?}=1{ページ {PAGE_NUMBER} を削除しますか?}other{ページ {PAGE_NUMBER} を削除しますか?}}</translation> <translation id="315116470104423982">モバイル データ</translation> <translation id="3156846309055100599"><ph name="PAGE_NUMBER" /> ページ目をスキャンしています...</translation> <translation id="315738237743207937">キャプティブ ポータルが検出されました</translation> +<translation id="3170673040743561620">スキャナにドキュメントを置いてください</translation> <translation id="3188257591659621405">マイファイル</translation> <translation id="3199982728237701504">ドキュメント フィーダー(両面)</translation> <translation id="3226405216343213872">スキャナを検索しています</translation> @@ -210,6 +214,7 @@ <translation id="4813345808229079766">接続</translation> <translation id="4832079907277790330">ファイルアプリ内のフォルダを選択...</translation> <translation id="4835901797422965222">有効なネットワークがありません</translation> +<translation id="484790837831576105">(Android)DNS の解決</translation> <translation id="4848429997038228357">実行中</translation> <translation id="4861758251032006121">{ATTEMPTS_LEFT,plural, =1{<ph name="ERROR_MESSAGE" />あと {0} 回試行できます}other{<ph name="ERROR_MESSAGE" />あと {0} 回試行できます}}</translation> <translation id="4880328057631981605">アクセス ポイント名</translation> @@ -228,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">SIM はロックされています(<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">グループ名</translation> +<translation id="5051044138948155788">これは存在する唯一のページです。削除すると、スキャンのスタート画面に戻ります。</translation> <translation id="5088172560898466307">サーバーのホスト名</translation> <translation id="5089810972385038852">都道府県 / 州</translation> <translation id="5142961317498132443">認証</translation> @@ -265,6 +271,7 @@ <translation id="5499114900554609492">スキャンを完了できませんでした</translation> <translation id="5502931783115429516">Android は実行されていません</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">再スキャン</translation> <translation id="5669267381087807207">有効化中</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">ファミリー</translation> @@ -290,6 +297,7 @@ <translation id="6050189528197190982">グレースケール</translation> <translation id="6058625436358447366">終了するには、古いパスワードと新しいパスワードを入力してください</translation> <translation id="6061772781719867950">HTTP リクエストが失敗しました</translation> +<translation id="6075872808778243331">(Android)HTTP レイテンシ</translation> <translation id="6104112872696127344">スキャンをキャンセルしました</translation> <translation id="6106186594183574873">終了するには、古いパスワードを入力してください</translation> <translation id="6108689792487843350">ゲートウェイにアクセスできません</translation> @@ -314,6 +322,7 @@ <translation id="641081527798843608">件名の一致</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">中程度</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{ページを再スキャンしますか?}=1{ページ {PAGE_NUMBER} を再スキャンしますか?}other{ページ {PAGE_NUMBER} を再スキャンしますか?}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287"><ph name="MANAGER" /> によって管理されています</translation> <translation id="649050271426829538">停止 - 紙詰まり</translation> @@ -332,6 +341,7 @@ <translation id="6643016212128521049">削除</translation> <translation id="6657585470893396449">パスワード</translation> <translation id="6704062477274546131">DNS の解決</translation> +<translation id="6714650824879092633"><ph name="NETWORK_NAME" /> が無効になっています</translation> <translation id="6747215703636344499">停止 - 排紙トレイがいっぱいです</translation> <translation id="6756731097889387912">スキャンをキャンセルできませんでした</translation> <translation id="6766275201586212568">DNS 解決に失敗しました</translation> @@ -341,11 +351,13 @@ <translation id="6910312834584889076">スキャナのカバーが開いています。カバーを閉じてから、もう一度お試しください。</translation> <translation id="6911383237894364323">メディア サーバーに接続できません</translation> <translation id="6957231940976260713">サービス名</translation> +<translation id="6961170852793647506">まずスキャナにドキュメントを置きます</translation> <translation id="6977381486153291903">ファームウェア リビジョン</translation> <translation id="6982876849933694860">新しい接続の設定は<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />で行うことができます。</translation> <translation id="7028979494427204405"><ph name="MANAGER" /> はこのデバイスを管理しており、閲覧したウェブページ、パスワード、メールなど、すべてのユーザー アクティビティにアクセスできます。</translation> <translation id="7039041976777695848"><ph name="CONNECTION_TYPE" /> キーボード</translation> <translation id="7040230719604914234">携帯通信会社</translation> +<translation id="7058278511608979688">終了して保存</translation> <translation id="7059230779847288458">充電中、フル充電まで <ph name="TIME_VALUE" /></translation> <translation id="708426984172631313">停止中</translation> <translation id="7086440545492620869"><ph name="VALUE" /> <ph name="DISPLAY_NAME" /></translation> @@ -409,6 +421,7 @@ <translation id="8041089156583427627">フィードバックを送信</translation> <translation id="8075838845814659848">バッテリー残量</translation> <translation id="808894953321890993">パスワードの変更</translation> +<translation id="811820734797650957">(Android)ゲートウェイへの ping</translation> <translation id="8129620843620772246"><ph name="TEMPERATURE_C" /> ℃</translation> <translation id="8132480444149501833">トラフィック カウンタをリクエスト</translation> <translation id="8206859287963243715">携帯電話</translation> @@ -480,6 +493,7 @@ <translation id="910415269708673980"><ph name="PRINCIPAL_NAME" /> のチケットを更新してください</translation> <translation id="9106415115617144481"><ph name="PAGE_NUMBER" /> ページ目をスキャンしています</translation> <translation id="9111102763498581341">ロック解除</translation> +<translation id="9126720536733509015">複数のページを保存して 1 つの PDF にまとめる</translation> <translation id="9137526406337347448">Google サービス</translation> <translation id="9149391708638971077">メモリテストを実行</translation> <translation id="9173638680043580060">残り 1 分未満</translation>
diff --git a/chromeos/strings/chromeos_strings_kk.xtb b/chromeos/strings/chromeos_strings_kk.xtb index 9a3ea8a3..0ee9c29c 100644 --- a/chromeos/strings/chromeos_strings_kk.xtb +++ b/chromeos/strings/chromeos_strings_kk.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">Сәтсіз: тоқтатылды</translation> <translation id="3102119246920354026">Кэш</translation> <translation id="3122464029669770682">Орталық процессор</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{Бетті өшіру керек пе?}=1{{PAGE_NUMBER}-бетті өшіру керек пе?}other{{PAGE_NUMBER}-бетті өшіру керек пе?}}</translation> <translation id="315116470104423982">Мобильді деректер</translation> <translation id="3156846309055100599"><ph name="PAGE_NUMBER" />-бет сканерленуде…</translation> <translation id="315738237743207937">Адаптивті портал анықталды.</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">SIM құлыпталған (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">Топ атауы</translation> +<translation id="5051044138948155788">Бұл — жалғыз бет. Осы арқылы сканерлеуді бастау экранына өтесіз.</translation> <translation id="5088172560898466307">Сервер хостының атауы</translation> <translation id="5089810972385038852">Штат</translation> <translation id="5142961317498132443">Аутентификация</translation> @@ -268,6 +270,7 @@ <translation id="5499114900554609492">Сканерлеу аяқталмады</translation> <translation id="5502931783115429516">Android іске қосылмаған.</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">Қайта сканерлеу</translation> <translation id="5669267381087807207">Белсендірілуде</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">Отбасы</translation> @@ -318,6 +321,7 @@ <translation id="641081527798843608">Тақырып сәйкестігі</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">Жақсы</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{Бетті қайта сканерлеу керек пе?}=1{{PAGE_NUMBER}-бетті қайта сканерлеу керек пе?}other{{PAGE_NUMBER}-бетті қайта сканерлеу керек пе?}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287"><ph name="MANAGER" /> басқарады</translation> <translation id="649050271426829538">Тоқтатылды: қағаз кептелісі</translation>
diff --git a/chromeos/strings/chromeos_strings_ko.xtb b/chromeos/strings/chromeos_strings_ko.xtb index bc123c8..280b027 100644 --- a/chromeos/strings/chromeos_strings_ko.xtb +++ b/chromeos/strings/chromeos_strings_ko.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">실패 - 중지됨</translation> <translation id="3102119246920354026">캐시</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{페이지를 삭제하시겠습니까?}=1{{PAGE_NUMBER}페이지를 삭제하시겠습니까?}other{{PAGE_NUMBER}페이지를 삭제하시겠습니까?}}</translation> <translation id="315116470104423982">모바일 데이터</translation> <translation id="3156846309055100599"><ph name="PAGE_NUMBER" />페이지 스캔 중…</translation> <translation id="315738237743207937">종속 포털 감지됨</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">SIM 잠김(<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">그룹 이름</translation> +<translation id="5051044138948155788">단일 페이지입니다. 스캔 시작 화면으로 이동합니다.</translation> <translation id="5088172560898466307">서버 호스트 이름</translation> <translation id="5089810972385038852">시/도</translation> <translation id="5142961317498132443">인증</translation> @@ -269,6 +271,7 @@ <translation id="5499114900554609492">스캔을 완료할 수 없음</translation> <translation id="5502931783115429516">Android 실행되고 있지 않음</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">다시 스캔</translation> <translation id="5669267381087807207">활성화 중</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">가족</translation> @@ -319,6 +322,7 @@ <translation id="641081527798843608">주제 일치</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">좋음</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{페이지를 다시 스캔하시겠습니까?}=1{{PAGE_NUMBER}페이지를 다시 스캔하시겠습니까?}other{{PAGE_NUMBER}페이지를 다시 스캔하시겠습니까?}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287"><ph name="MANAGER" />에서 관리함</translation> <translation id="649050271426829538">중지됨 - 용지 걸림</translation>
diff --git a/chromeos/strings/chromeos_strings_sq.xtb b/chromeos/strings/chromeos_strings_sq.xtb index 54f03c4..c10f73d 100644 --- a/chromeos/strings/chromeos_strings_sq.xtb +++ b/chromeos/strings/chromeos_strings_sq.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">Dështoi - Ndaloi</translation> <translation id="3102119246920354026">Memoria specifike</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{Të hiqet faqja?}=1{Të hiqet faqja {PAGE_NUMBER}?}other{Të hiqet faqja {PAGE_NUMBER}?}}</translation> <translation id="315116470104423982">Të dhëna celulare</translation> <translation id="3156846309055100599">Po skanon faqen <ph name="PAGE_NUMBER" />...</translation> <translation id="315738237743207937">U zbulua portal izolues</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">Karta SIM e kyçur (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">Emri i grupit</translation> +<translation id="5051044138948155788">Kjo është faqja e vetme. Kjo do të të çojë tek ekrani i fillimit të skanimit.</translation> <translation id="5088172560898466307">Emri i strehuesit të serverit</translation> <translation id="5089810972385038852">Shteti</translation> <translation id="5142961317498132443">Vërtetimi</translation> @@ -268,6 +270,7 @@ <translation id="5499114900554609492">Skanimi nuk mund të përfundohej</translation> <translation id="5502931783115429516">Android nuk po punon</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">Skano përsëri</translation> <translation id="5669267381087807207">Po aktivizohet</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">Familja</translation> @@ -318,6 +321,7 @@ <translation id="641081527798843608">Përputhja e subjektit</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">I mirë</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{Të skanohet përsëri faqja?}=1{Të skanohet përsëri faqja {PAGE_NUMBER}?}other{Të skanohet përsëri faqja {PAGE_NUMBER}?}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287">Menaxhuar nga <ph name="MANAGER" /></translation> <translation id="649050271426829538">Ndaloi - Bllokim letre</translation>
diff --git a/chromeos/strings/chromeos_strings_sw.xtb b/chromeos/strings/chromeos_strings_sw.xtb index 5160ef5..7cde1e5 100644 --- a/chromeos/strings/chromeos_strings_sw.xtb +++ b/chromeos/strings/chromeos_strings_sw.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">Haijakamilika - Imesimamisha</translation> <translation id="3102119246920354026">Akiba</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{Ungependa kuondoa ukurasa huu?}=1{Ungependa kuondoa ukurasa wa {PAGE_NUMBER}?}other{Ungependa kuondoa ukurasa wa {PAGE_NUMBER}?}}</translation> <translation id="315116470104423982">Data ya mtandao wa simu</translation> <translation id="3156846309055100599">Inachanganua ukurasa wa <ph name="PAGE_NUMBER" />...</translation> <translation id="315738237743207937">Ukurasa wa mwanzo umetambuliwa</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">SIM Imefungwa (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">Jina la kikundi</translation> +<translation id="5051044138948155788">Huu ndio ukurasa pekee uliosalia. Hatua hii itakuelekeza kwenye skrini ya kuanza kuchanganua.</translation> <translation id="5088172560898466307">Jina la seva pangishi</translation> <translation id="5089810972385038852">Jimbo</translation> <translation id="5142961317498132443">Uthibitishaji</translation> @@ -268,6 +270,7 @@ <translation id="5499114900554609492">Imeshindwa kukamilisha uchanganuzi</translation> <translation id="5502931783115429516">Android haifanyi kazi</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">Changanua upya</translation> <translation id="5669267381087807207">Inawashwa</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">Familia</translation> @@ -318,6 +321,7 @@ <translation id="641081527798843608">Mada inalingana</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">Bora</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{Ungependa kuchanganua ukurasa huu upya?}=1{Ungependa kuchanganua ukurasa wa {PAGE_NUMBER} upya?}other{Ungependa kuchanganua ukurasa wa {PAGE_NUMBER} upya?}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287">Inadhibitiwa na <ph name="MANAGER" /></translation> <translation id="649050271426829538">Imesimama - Karatasi imekwama</translation>
diff --git a/chromeos/strings/chromeos_strings_ta.xtb b/chromeos/strings/chromeos_strings_ta.xtb index d041113..b64c6c9 100644 --- a/chromeos/strings/chromeos_strings_ta.xtb +++ b/chromeos/strings/chromeos_strings_ta.xtb
@@ -57,6 +57,7 @@ <translation id="1908234395526491708">UDP கோரிக்கையை அனுப்ப முடியவில்லை</translation> <translation id="1930797645656624981">Chrome OS உள்ளீட்டு முறை சேவை</translation> <translation id="1947737735496445907">அச்சிடப்பட்டது</translation> +<translation id="197386857804679933">மீண்டும் இணைக்க, அமைப்புகளுக்குச் செல்லவும்</translation> <translation id="1979103255016296513">கடவுச்சொல்லை மாற்ற வேண்டும்</translation> <translation id="1999615961760456652">கேப்டிவ் போர்டல்</translation> <translation id="2006864819935886708">இணைப்பு</translation> @@ -96,6 +97,7 @@ <translation id="2783010256799387990">சரிபார்க்கப்பட்டது</translation> <translation id="2789486458103222910">சரி</translation> <translation id="2805756323405976993">ஆப்ஸ்</translation> +<translation id="2860473693272905224">ஸ்கேனரில் மற்றொரு பக்கத்தை வைக்கவும்</translation> <translation id="2872961005593481000">நிறுத்து</translation> <translation id="2878387241690264070"><ph name="NUM_SECONDS" /> வினாடிகளில் <ph name="RATE" /> சார்ஜ் இறங்கியது.</translation> <translation id="3008341117444806826">புதுப்பி</translation> @@ -110,6 +112,7 @@ <translation id="315116470104423982">மொபைல் டேட்டா</translation> <translation id="3156846309055100599"><ph name="PAGE_NUMBER" />வது பக்கம் ஸ்கேன் செய்யப்படுகிறது...</translation> <translation id="315738237743207937">கேப்டிவ் போர்டல் கண்டறியப்பட்டது</translation> +<translation id="3170673040743561620">ஆவணத்தை ஸ்கேனர் மீது வைக்கவும்</translation> <translation id="3188257591659621405">எனது ஃபைல்கள் </translation> <translation id="3199982728237701504">டாக்குமெண்ட் ஃபீடர் (இரண்டு பக்கமும்)</translation> <translation id="3226405216343213872">ஸ்கேனர்களைத் தேடுகிறது</translation> @@ -210,6 +213,7 @@ <translation id="4813345808229079766">இணைப்பு</translation> <translation id="4832079907277790330">Files ஆப்ஸில் ஃபோல்டரைத் தேர்ந்தெடு...</translation> <translation id="4835901797422965222">நெட்நொர்க்குகள் எதுவும் செயலில் இல்லை</translation> +<translation id="484790837831576105">(Android) DNS ரெசல்யூஷன்</translation> <translation id="4848429997038228357">நடைபெறுவது</translation> <translation id="4861758251032006121">{ATTEMPTS_LEFT,plural, =1{<ph name="ERROR_MESSAGE" /> {0} முயற்சி மீதமுள்ளது}other{<ph name="ERROR_MESSAGE" /> {0} முயற்சிகள் மீதமுள்ளன}}</translation> <translation id="4880328057631981605">ஆக்சஸ் பாயிண்ட் நேம்</translation> @@ -290,6 +294,7 @@ <translation id="6050189528197190982">கிரேஸ்கேல்</translation> <translation id="6058625436358447366">நிறைவுசெய்ய தற்போதைய கடவுச்சொல்லையும் புதிய கடவுச்சொல்லையும் உள்ளிடவும்</translation> <translation id="6061772781719867950">HTTPS கோரிக்கைகளுக்குப் பதில் கிடைக்கவில்லை</translation> +<translation id="6075872808778243331">(Android) HTTP தாமதம்</translation> <translation id="6104112872696127344">ஸ்கேன் செய்வது ரத்துசெய்யப்பட்டது</translation> <translation id="6106186594183574873">நிறைவுசெய்ய தற்போதைய கடவுச்சொல்லை உள்ளிடவும்</translation> <translation id="6108689792487843350">கேட்வேயை அணுக முடியவில்லை</translation> @@ -332,6 +337,7 @@ <translation id="6643016212128521049">அழி</translation> <translation id="6657585470893396449">கடவுச்சொல்</translation> <translation id="6704062477274546131">DNS ரெசல்யூஷன்</translation> +<translation id="6714650824879092633"><ph name="NETWORK_NAME" /> முடக்கப்பட்டுள்ளது</translation> <translation id="6747215703636344499">பிரிண்ட் வெளியே வரும் டிரே நிரம்பிவிட்டதால் அச்சிட முடியவில்லை</translation> <translation id="6756731097889387912">ஸ்கேன் செய்வதை ரத்துசெய்ய முடியவில்லை</translation> <translation id="6766275201586212568">DNS ரெசல்யூஷன்கள் தோல்வி அடைந்தது</translation> @@ -341,11 +347,13 @@ <translation id="6910312834584889076">ஸ்கேனரின் கவர் திறந்துள்ளது. கவரை மூடிவிட்டு மீண்டும் முயலவும்.</translation> <translation id="6911383237894364323">மீடியா சேவையகங்களுடன் இணைக்க முடியவில்லை</translation> <translation id="6957231940976260713">சேவைப் பெயர்</translation> +<translation id="6961170852793647506">ஸ்கேன் செய்ய, ஆவணத்தை ஸ்கேனர் மீது வைக்கவும்</translation> <translation id="6977381486153291903">நிலைபொருள் பதிப்பு</translation> <translation id="6982876849933694860">புதிய இணைப்பை அமைக்க, <ph name="BEGIN_LINK" />அமைப்புகளுக்குச்<ph name="END_LINK" /> செல்லவும்.</translation> <translation id="7028979494427204405">இந்தச் சாதனத்தை <ph name="MANAGER" /> நிர்வகிக்கிறது. பார்வையிட்ட இணையப்பக்கங்கள், கடவுச்சொற்கள், மின்னஞ்சல் உட்பட பயனரின் செயல்பாடு அனைத்திற்குமான அணுகலும் இதற்கு உள்ளது.</translation> <translation id="7039041976777695848"><ph name="CONNECTION_TYPE" /> கீபோர்டு</translation> <translation id="7040230719604914234">ஆபரேட்டர்</translation> +<translation id="7058278511608979688">நிறுத்திவிட்டுச் சேமி</translation> <translation id="7059230779847288458">சார்ஜ் ஆகிறது, முழுமையாகச் சார்ஜ் ஏற <ph name="TIME_VALUE" /> ஆகும்</translation> <translation id="708426984172631313">நிறுத்தப்பட்டது</translation> <translation id="7086440545492620869"><ph name="VALUE" /> <ph name="DISPLAY_NAME" /></translation> @@ -409,6 +417,7 @@ <translation id="8041089156583427627">கருத்துத் தெரிவிக்கவும்</translation> <translation id="8075838845814659848">மீதமுள்ள சார்ஜ்</translation> <translation id="808894953321890993">கடவுச்சொல்லை மாற்று</translation> +<translation id="811820734797650957">(Android) கேட்வேயைத் தொடர்புகொள்வது</translation> <translation id="8129620843620772246"><ph name="TEMPERATURE_C" />° C</translation> <translation id="8132480444149501833">டிராஃபிக் கவுண்ட்டர்களைக் கோரு</translation> <translation id="8206859287963243715">செல்லுலர்</translation> @@ -480,6 +489,7 @@ <translation id="910415269708673980"><ph name="PRINCIPAL_NAME" /> வலைதளத்திற்கான டிக்கெட்டை ரெஃப்ரெஷ் செய்யவும்</translation> <translation id="9106415115617144481">ஸ்கேன் செய்யப்படும் பக்கம்: <ph name="PAGE_NUMBER" /></translation> <translation id="9111102763498581341">அன்லாக் செய்</translation> +<translation id="9126720536733509015">பல பக்கங்களை ஒரே PDF ஃபைலாகச் சேமி</translation> <translation id="9137526406337347448">Google சேவைகள்</translation> <translation id="9149391708638971077">நினைவகச் சோதனையை இயக்கு</translation> <translation id="9173638680043580060">ஒரு நிமிடத்திற்கும் குறைவான நேரமே மீதமுள்ளது</translation>
diff --git a/chromeos/strings/chromeos_strings_te.xtb b/chromeos/strings/chromeos_strings_te.xtb index 59dc8710..75d2371d 100644 --- a/chromeos/strings/chromeos_strings_te.xtb +++ b/chromeos/strings/chromeos_strings_te.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">విఫలమైంది - ఆగిపోయింది</translation> <translation id="3102119246920354026">కాష్</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{పేజీని తీసివేయాలా?}=1{{PAGE_NUMBER}వ పేజీని తీసివేయాలా?}other{{PAGE_NUMBER}వ పేజీని తీసివేయాలా?}}</translation> <translation id="315116470104423982">మొబైల్ డేటా</translation> <translation id="3156846309055100599"><ph name="PAGE_NUMBER" />వ పేజీని స్కాన్ చేస్తోంది...</translation> <translation id="315738237743207937">క్యాప్టివ్ పోర్టల్ గుర్తించబడింది</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">SIM లాక్ చేయబడింది (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">సమూహం పేరు</translation> +<translation id="5051044138948155788">ఈ పేజీ మాత్రమే ఉంది. ఇది మిమ్మల్ని స్కానింగ్ ప్రారంభ స్క్రీన్కు తీసుకువెళ్తుంది.</translation> <translation id="5088172560898466307">సర్వర్ హోస్ట్ పేరు</translation> <translation id="5089810972385038852">రాష్ట్రం</translation> <translation id="5142961317498132443">ప్రమాణీకరణ</translation> @@ -268,6 +270,7 @@ <translation id="5499114900554609492">స్కాన్ను పూర్తి చేయడం సాధ్యపడలేదు</translation> <translation id="5502931783115429516">Android రన్ అవ్వడం లేదు</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">మళ్లీ స్కాన్ చేయండి</translation> <translation id="5669267381087807207">సక్రియమవుతోంది</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">కుటుంబం</translation> @@ -318,6 +321,7 @@ <translation id="641081527798843608">విషయ సరిపోలిక</translation> <translation id="6423239382391657905">OpenVPN</translation> <translation id="6456394469623773452">శ్రేష్టమైనది</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{పేజీని మళ్లీ స్కాన్ చేయాలా?}=1{{PAGE_NUMBER}వ పేజీని మళ్లీ స్కాన్ చేయాలా?}other{{PAGE_NUMBER}వ పేజీని మళ్లీ స్కాన్ చేయాలా?}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287"><ph name="MANAGER" /> ద్వారా మేనేజ్ చేయబడుతోంది</translation> <translation id="649050271426829538">ఆగిపోయింది - కాగితం జామ్ అయింది</translation>
diff --git a/chromeos/strings/chromeos_strings_th.xtb b/chromeos/strings/chromeos_strings_th.xtb index 828391a4..ca9c56d 100644 --- a/chromeos/strings/chromeos_strings_th.xtb +++ b/chromeos/strings/chromeos_strings_th.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">ไม่สำเร็จ - หยุดทำงาน</translation> <translation id="3102119246920354026">แคช</translation> <translation id="3122464029669770682">CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{นำหน้าออกไหม}=1{นำหน้าที่ {PAGE_NUMBER} ออกไหม}other{นำหน้าที่ {PAGE_NUMBER} ออกไหม}}</translation> <translation id="315116470104423982">เน็ตมือถือ</translation> <translation id="3156846309055100599">กำลังสแกนหน้า <ph name="PAGE_NUMBER" />...</translation> <translation id="315738237743207937">ตรวจพบแคพทีฟพอร์ทัล</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">LEAP</translation> <translation id="5049856988445523908">ล็อกซิมแล้ว (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">ชื่อกลุ่ม</translation> +<translation id="5051044138948155788">เหลือเพียงหน้าเดียว ระบบจะนำคุณไปยังหน้าจอเริ่มต้นการสแกน</translation> <translation id="5088172560898466307">ชื่อโฮสต์ของเซิร์ฟเวอร์</translation> <translation id="5089810972385038852">รัฐ</translation> <translation id="5142961317498132443">การตรวจสอบสิทธิ์</translation> @@ -269,6 +271,7 @@ <translation id="5499114900554609492">สแกนไม่สำเร็จ</translation> <translation id="5502931783115429516">Android ไม่ทำงาน</translation> <translation id="554517032089923082">GTC</translation> +<translation id="5578519639599103840">สแกนอีกครั้ง</translation> <translation id="5669267381087807207">กำลังเปิดใช้</translation> <translation id="5670702108860320605">BSSID</translation> <translation id="5691511426247308406">ครอบครัว</translation> @@ -319,6 +322,7 @@ <translation id="641081527798843608">หัวเรื่องที่ตรงกัน</translation> <translation id="6423239382391657905">เปิด VPN</translation> <translation id="6456394469623773452">ดี</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{สแกนหน้าอีกครั้งไหม}=1{สแกนหน้าที่ {PAGE_NUMBER} อีกครั้งไหม}other{สแกนหน้าที่ {PAGE_NUMBER} อีกครั้งไหม}}</translation> <translation id="6472207088655375767">OTP</translation> <translation id="6480327114083866287">จัดการโดย <ph name="MANAGER" /></translation> <translation id="649050271426829538">หยุดพิมพ์ - กระดาษติด</translation>
diff --git a/chromeos/strings/chromeos_strings_zu.xtb b/chromeos/strings/chromeos_strings_zu.xtb index a53a7ff..ca97a04d 100644 --- a/chromeos/strings/chromeos_strings_zu.xtb +++ b/chromeos/strings/chromeos_strings_zu.xtb
@@ -109,6 +109,7 @@ <translation id="3091839911843451378">Yehlulekile - Imile</translation> <translation id="3102119246920354026">Inqolobane</translation> <translation id="3122464029669770682">I-CPU</translation> +<translation id="3127341325625468058">{PAGE_NUMBER,plural, =0{Susa ikhasi?}=1{Susa ikhasi {PAGE_NUMBER}?}one{Susa ikhasi {PAGE_NUMBER}?}other{Susa ikhasi {PAGE_NUMBER}?}}</translation> <translation id="315116470104423982">Idatha yeselula</translation> <translation id="3156846309055100599">Iskena ikhasi <ph name="PAGE_NUMBER" />...</translation> <translation id="315738237743207937">Iphothali yabathunjiweyo itholiwe</translation> @@ -232,6 +233,7 @@ <translation id="5017508259293544172">I-LEAP</translation> <translation id="5049856988445523908">I-SIM Ikhiyiwe (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">Igama leqembu</translation> +<translation id="5051044138948155788">Yileli kuphela ikhasi. Lokhu kuzokusa kusikrini sokuqala sokuskena.</translation> <translation id="5088172560898466307">Igama lomethuli leseva</translation> <translation id="5089810972385038852">Izwe</translation> <translation id="5142961317498132443">Ukufakazela ubuqiniso</translation> @@ -269,6 +271,7 @@ <translation id="5499114900554609492">Ayikwazanga ukuqedela ukuskena</translation> <translation id="5502931783115429516">I-Android ayiqalisi</translation> <translation id="554517032089923082">I-GTC</translation> +<translation id="5578519639599103840">Phinda uskene</translation> <translation id="5669267381087807207">Yenza isebenze</translation> <translation id="5670702108860320605">I-BSSID</translation> <translation id="5691511426247308406">Umndeni</translation> @@ -319,6 +322,7 @@ <translation id="641081527798843608">Ukufana kwesihloko</translation> <translation id="6423239382391657905">I-OpenVPN</translation> <translation id="6456394469623773452">Kulungile</translation> +<translation id="6463239094587744704">{PAGE_NUMBER,plural, =0{Skena kabusha ikhasi?}=1{Skena kabusha ikhasi {PAGE_NUMBER}?}one{Skena kabusha ikhasi {PAGE_NUMBER}?}other{Skena kabusha ikhasi {PAGE_NUMBER}?}}</translation> <translation id="6472207088655375767">I-OTP</translation> <translation id="6480327114083866287">Iphethwe yi-<ph name="MANAGER" /></translation> <translation id="649050271426829538">Imile - Ukujema kwephepha</translation>
diff --git a/chromeos/system/name_value_pairs_parser.cc b/chromeos/system/name_value_pairs_parser.cc index 1836227..76356322 100644 --- a/chromeos/system/name_value_pairs_parser.cc +++ b/chromeos/system/name_value_pairs_parser.cc
@@ -11,11 +11,9 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/process/launch.h" -#include "base/strings/string_number_conversions.h" #include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" #include "base/system/sys_info.h" -#include "chromeos/system/statistics_provider.h" namespace chromeos { // NOLINT namespace system { @@ -53,13 +51,10 @@ const std::string& delim) { std::string contents; if (base::ReadFileToString(file_path, &contents)) { - return ParseNameValuePairs(contents, eq, delim, - /*debug_source=*/file_path.value()); + return ParseNameValuePairs(contents, eq, delim); } else { - if (base::SysInfo::IsRunningOnChromeOS()) { - // TODO(crbug.com/1123153): Downgrade to VLOG(1) after fixing the bug. - LOG(WARNING) << "Statistics file not present: " << file_path.value(); - } + if (base::SysInfo::IsRunningOnChromeOS()) + VLOG(1) << "Statistics file not present: " << file_path.value(); return false; } } @@ -70,14 +65,12 @@ const std::string& eq, const std::string& delim, const std::string& comment_delim) { - DCHECK_GE(argc, 1); - std::string output_string; if (!GetToolOutput(argc, argv, &output_string)) return false; - return ParseNameValuePairsWithComments( - output_string, eq, delim, comment_delim, /*debug_source=*/argv[0]); + return ParseNameValuePairsWithComments(output_string, eq, delim, + comment_delim); } void NameValuePairsParser::DeletePairsWithValue(const std::string& value) { @@ -103,21 +96,17 @@ } } -bool NameValuePairsParser::ParseNameValuePairs( - const std::string& in_string, - const std::string& eq, - const std::string& delim, - const std::string& debug_source) { - return ParseNameValuePairsWithComments(in_string, eq, delim, "", - debug_source); +bool NameValuePairsParser::ParseNameValuePairs(const std::string& in_string, + const std::string& eq, + const std::string& delim) { + return ParseNameValuePairsWithComments(in_string, eq, delim, ""); } bool NameValuePairsParser::ParseNameValuePairsWithComments( const std::string& in_string, const std::string& eq, const std::string& delim, - const std::string& comment_delim, - const std::string& debug_source) { + const std::string& comment_delim) { bool all_valid = true; // Set up the pair tokenizer. base::StringTokenizer pair_toks(in_string, delim); @@ -125,13 +114,6 @@ // Process token pairs. while (pair_toks.GetNext()) { std::string pair(pair_toks.token()); - - // TODO(crbug.com/1123153): Delete logging after the bug is fixed. - LOG_IF(WARNING, - pair.find(kFirmwareWriteProtectCurrentKey) != std::string::npos) - << "Statistics " << kFirmwareWriteProtectCurrentKey << " mentioned in " - << debug_source << ": " << base::HexEncode(pair.c_str(), pair.size()); - // Anything before the first |eq| is the key, anything after is the value. // |eq| must exist. size_t eq_pos = pair.find(eq);
diff --git a/chromeos/system/name_value_pairs_parser.h b/chromeos/system/name_value_pairs_parser.h index b9c2f62..15317fb 100644 --- a/chromeos/system/name_value_pairs_parser.h +++ b/chromeos/system/name_value_pairs_parser.h
@@ -60,8 +60,7 @@ // be added to the map. bool ParseNameValuePairs(const std::string& in_string, const std::string& eq, - const std::string& delim, - const std::string& debug_source); + const std::string& delim); // This version allows for values which end with a comment beginning with // |comment_delim|. @@ -71,8 +70,7 @@ bool ParseNameValuePairsWithComments(const std::string& in_string, const std::string& eq, const std::string& delim, - const std::string& comment_delim, - const std::string& debug_source); + const std::string& comment_delim); NameValueMap* map_;
diff --git a/chromeos/system/name_value_pairs_parser_unittest.cc b/chromeos/system/name_value_pairs_parser_unittest.cc index a43cd1b8..bc04906 100644 --- a/chromeos/system/name_value_pairs_parser_unittest.cc +++ b/chromeos/system/name_value_pairs_parser_unittest.cc
@@ -14,7 +14,7 @@ NameValuePairsParser::NameValueMap map; NameValuePairsParser parser(&map); const std::string contents1 = "foo=Foo bar=Bar\nfoobar=FooBar\n"; - EXPECT_TRUE(parser.ParseNameValuePairs(contents1, "=", " \n", "")); + EXPECT_TRUE(parser.ParseNameValuePairs(contents1, "=", " \n")); EXPECT_EQ(3U, map.size()); EXPECT_EQ("Foo", map["foo"]); EXPECT_EQ("Bar", map["bar"]); @@ -22,21 +22,21 @@ map.clear(); const std::string contents2 = "foo=Foo,bar=Bar"; - EXPECT_TRUE(parser.ParseNameValuePairs(contents2, "=", ",\n", "")); + EXPECT_TRUE(parser.ParseNameValuePairs(contents2, "=", ",\n")); EXPECT_EQ(2U, map.size()); EXPECT_EQ("Foo", map["foo"]); EXPECT_EQ("Bar", map["bar"]); map.clear(); const std::string contents3 = "foo=Foo=foo,bar=Bar"; - EXPECT_TRUE(parser.ParseNameValuePairs(contents3, "=", ",\n", "")); + EXPECT_TRUE(parser.ParseNameValuePairs(contents3, "=", ",\n")); EXPECT_EQ(2U, map.size()); EXPECT_EQ("Foo=foo", map["foo"]); EXPECT_EQ("Bar", map["bar"]); map.clear(); const std::string contents4 = "foo=Foo,=Bar"; - EXPECT_FALSE(parser.ParseNameValuePairs(contents4, "=", ",\n", "")); + EXPECT_FALSE(parser.ParseNameValuePairs(contents4, "=", ",\n")); EXPECT_EQ(1U, map.size()); EXPECT_EQ("Foo", map["foo"]); @@ -45,7 +45,7 @@ "\"initial_locale\"=\"ja\"\n" "\"initial_timezone\"=\"Asia/Tokyo\"\n" "\"keyboard_layout\"=\"mozc-jp\"\n"; - EXPECT_TRUE(parser.ParseNameValuePairs(contents5, "=", "\n", "")); + EXPECT_TRUE(parser.ParseNameValuePairs(contents5, "=", "\n")); EXPECT_EQ(3U, map.size()); EXPECT_EQ("ja", map["initial_locale"]); EXPECT_EQ("Asia/Tokyo", map["initial_timezone"]); @@ -58,7 +58,7 @@ const std::string contents1 = "foo=Foo,bar=#Bar,baz= 0 #Baz"; EXPECT_TRUE( - parser.ParseNameValuePairsWithComments(contents1, "=", ",\n", "#", "")); + parser.ParseNameValuePairsWithComments(contents1, "=", ",\n", "#")); EXPECT_EQ(3U, map.size()); EXPECT_EQ("Foo", map["foo"]); EXPECT_EQ("", map["bar"]); @@ -67,14 +67,14 @@ map.clear(); const std::string contents2 = "foo="; EXPECT_TRUE( - parser.ParseNameValuePairsWithComments(contents2, "=", ",\n", "#", "")); + parser.ParseNameValuePairsWithComments(contents2, "=", ",\n", "#")); EXPECT_EQ(1U, map.size()); EXPECT_EQ("", map["foo"]); map.clear(); const std::string contents3 = " \t ,,#all empty,"; EXPECT_FALSE( - parser.ParseNameValuePairsWithComments(contents3, "=", ",\n", "#", "")); + parser.ParseNameValuePairsWithComments(contents3, "=", ",\n", "#")); EXPECT_EQ(0U, map.size()); }
diff --git a/chromeos/system/statistics_provider.cc b/chromeos/system/statistics_provider.cc index 3cc53ae..d829879 100644 --- a/chromeos/system/statistics_provider.cc +++ b/chromeos/system/statistics_provider.cc
@@ -323,8 +323,7 @@ // and unblock pending WaitForStatisticsLoaded() calls. statistics_loaded_.Signal(); - // TODO(crbug.com/1123153): Downgrade to VLOG(1) after the bug is fixed. - LOG(WARNING) << "Finished loading statistics."; + VLOG(1) << "Finished loading statistics."; } // Schedule callbacks that were in |statistics_loaded_callbacks_|. @@ -622,8 +621,7 @@ region_ = command_line->GetSwitchValueASCII(chromeos::switches::kCrosRegion); machine_info_[kRegionKey] = region_; - // TODO(crbug.com/1123153): Downgrade to VLOG(1) after the bug is fixed. - LOG(WARNING) << "CrOS region set to '" << region_ << "'"; + VLOG(1) << "CrOS region set to '" << region_ << "'"; } LoadRegionsFile(base::FilePath(kCrosRegions)); @@ -676,8 +674,7 @@ machine_flags_[kOemKeyboardDrivenOobeKey] = oem_manifest.keyboard_driven_oobe; oem_manifest_loaded_ = true; - // TODO(crbug.com/1123153): Downgrade to VLOG(1) after the bug is fixed. - LOG(WARNING) << "Loaded OEM Manifest statistics from " << file.value(); + VLOG(1) << "Loaded OEM Manifest statistics from " << file.value(); } StatisticsProviderImpl* StatisticsProviderImpl::GetInstance() {
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 bbb428b..02b5d96 100644 --- a/components/autofill_assistant/browser/actions/collect_user_data_action.cc +++ b/components/autofill_assistant/browser/actions/collect_user_data_action.cc
@@ -624,8 +624,9 @@ // Gather info for UMA histograms. if (!shown_to_user_) { shown_to_user_ = true; - initially_prefilled_ = - CheckInitialAutofillDataComplete(delegate_->GetPersonalDataManager()); + initially_prefilled_ = CheckInitialAutofillDataComplete( + user_data->available_profiles_, + user_data->available_payment_instruments_); } if (collect_user_data.has_prompt()) { @@ -970,58 +971,52 @@ } bool CollectUserDataAction::CheckInitialAutofillDataComplete( - autofill::PersonalDataManager* personal_data_manager) { + const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles, + const std::vector<std::unique_ptr<PaymentInstrument>>& + payment_instruments) { DCHECK(collect_user_data_options_ != nullptr); bool request_contact = RequiresContact(*collect_user_data_options_); if (request_contact || collect_user_data_options_->request_shipping) { - auto profiles = personal_data_manager->GetProfiles(); if (request_contact) { - auto completeContactIter = std::find_if( + auto complete_contact_iter = std::find_if( profiles.begin(), profiles.end(), [this](const auto& profile) { return user_data::GetContactValidationErrors( - profile, *this->collect_user_data_options_.get()) + profile.get(), *collect_user_data_options_) .empty(); }); - if (completeContactIter == profiles.end()) { + if (complete_contact_iter == profiles.end()) { return false; } } if (collect_user_data_options_->request_shipping) { - auto completeAddressIter = std::find_if( - profiles.begin(), profiles.end(), [this](const auto* profile) { + auto complete_address_iter = std::find_if( + profiles.begin(), profiles.end(), [this](const auto& profile) { return user_data::GetShippingAddressValidationErrors( - profile, *this->collect_user_data_options_.get()) + profile.get(), *collect_user_data_options_) .empty(); }); - if (completeAddressIter == profiles.end()) { + if (complete_address_iter == profiles.end()) { return false; } } } if (collect_user_data_options_->request_payment_method) { - auto credit_cards = personal_data_manager->GetCreditCards(); - auto complete_card_iter = std::find_if( - credit_cards.begin(), credit_cards.end(), - [this, personal_data_manager](const auto* credit_card) { - // TODO(b/142630213): Figure out how to retrieve billing - // profile if user has turned off addresses in Chrome - // settings. - return user_data::GetPaymentInstrumentValidationErrors( - credit_card, - credit_card != nullptr && - !credit_card->billing_address_id().empty() - ? personal_data_manager->GetProfileByGUID( - credit_card->billing_address_id()) - : nullptr, - *this->collect_user_data_options_.get()) - .empty(); - }); - if (complete_card_iter == credit_cards.end()) { + auto complete_payment_instrument_iter = + std::find_if(payment_instruments.begin(), payment_instruments.end(), + [this](const auto& payment_instrument) { + return user_data::GetPaymentInstrumentValidationErrors( + payment_instrument->card.get(), + payment_instrument->billing_address.get(), + *collect_user_data_options_) + .empty(); + }); + if (complete_payment_instrument_iter == payment_instruments.end()) { return false; } } + return true; }
diff --git a/components/autofill_assistant/browser/actions/collect_user_data_action.h b/components/autofill_assistant/browser/actions/collect_user_data_action.h index a6eafa3..7e41b3a 100644 --- a/components/autofill_assistant/browser/actions/collect_user_data_action.h +++ b/components/autofill_assistant/browser/actions/collect_user_data_action.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "components/autofill/core/browser/data_model/autofill_profile.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/personal_data_manager_observer.h" #include "components/autofill_assistant/browser/actions/action.h" @@ -94,9 +95,10 @@ // Creates a new instance of |CollectUserDataOptions| from |proto_|. bool CreateOptionsFromProto(); - // Will update |initial_card_has_billing_postal_code_|. bool CheckInitialAutofillDataComplete( - autofill::PersonalDataManager* personal_data_manager); + const std::vector<std::unique_ptr<autofill::AutofillProfile>>& profiles, + const std::vector<std::unique_ptr<PaymentInstrument>>& + payment_instruments); void WriteProcessedAction(UserData* user_data, const UserModel* user_model); void UpdateProfileAndCardUse(UserData* user_data);
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 a4655e22..ae9930f 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
@@ -11,12 +11,14 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/test/gmock_callback_support.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" #include "base/time/time.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill_assistant/browser/actions/mock_action_delegate.h" #include "components/autofill_assistant/browser/cud_condition.pb.h" +#include "components/autofill_assistant/browser/metrics.h" #include "components/autofill_assistant/browser/mock_personal_data_manager.h" #include "components/autofill_assistant/browser/mock_website_login_manager.h" #include "components/autofill_assistant/browser/test_util.h" @@ -2497,5 +2499,60 @@ action.ProcessAction(callback_.Get()); } +TEST_F(CollectUserDataActionTest, TestInitiallyCompleteUMALogging) { + base::HistogramTester histogram_tester; + + ActionProto action_proto; + auto* collect_user_data_proto = action_proto.mutable_collect_user_data(); + auto* contact_details_proto = + collect_user_data_proto->mutable_contact_details(); + contact_details_proto->set_contact_details_name("contact"); + contact_details_proto->set_request_payer_name(true); + contact_details_proto->set_request_payer_email(true); + contact_details_proto->set_request_payer_phone(true); + collect_user_data_proto->set_request_terms_and_conditions(false); + collect_user_data_proto->set_request_payment_method(true); + collect_user_data_proto->set_billing_address_name("billing_address"); + collect_user_data_proto->set_shipping_address_name("shipping_address"); + + std::string address_guid = base::GenerateGUID(); + autofill::AutofillProfile address(address_guid, kFakeUrl); + autofill::test::SetProfileInfo( + &address, "Marion", "Mitchell", "Morrison", "marion@me.xyz", "Fox", + "123 Zoo St.", "unit 5", "Hollywood", "CA", "91601", "US", "16505678910"); + + std::string card_guid = base::GenerateGUID(); + autofill::CreditCard credit_card(card_guid, kFakeUrl); + autofill::test::SetCreditCardInfo(&credit_card, "Marion Mitchell", + "4111 1111 1111 1111", "01", "2050", + address.guid()); + + ON_CALL(mock_personal_data_manager_, IsAutofillProfileEnabled) + .WillByDefault(Return(true)); + ON_CALL(mock_personal_data_manager_, IsAutofillCreditCardEnabled) + .WillByDefault(Return(true)); + ON_CALL(mock_personal_data_manager_, ShouldSuggestServerCards) + .WillByDefault(Return(true)); + ON_CALL(mock_personal_data_manager_, GetProfiles) + .WillByDefault( + Return(std::vector<autofill::AutofillProfile*>({&address}))); + ON_CALL(mock_personal_data_manager_, GetCreditCards) + .WillByDefault( + Return(std::vector<autofill::CreditCard*>({&credit_card}))); + ON_CALL(mock_personal_data_manager_, GetProfileByGUID(address_guid)) + .WillByDefault(Return(&address)); + + std::unique_ptr<CollectUserDataAction> action = + std::make_unique<CollectUserDataAction>(&mock_action_delegate_, + action_proto); + action->ProcessAction(callback_.Get()); + // We can't wait for the callback_ to be called and destroy the action there, + // it will trigger a "heap use after free" error. + action.reset(); // Destroy to write histogram entries. + histogram_tester.ExpectUniqueSample( + "Android.AutofillAssistant.PaymentRequest.Prefilled", + Metrics::PaymentRequestPrefilled::PREFILLED_SUCCESS, 1u); +} + } // namespace } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/web/web_controller_browsertest.cc b/components/autofill_assistant/browser/web/web_controller_browsertest.cc index 3d28f12..6285614 100644 --- a/components/autofill_assistant/browser/web/web_controller_browsertest.cc +++ b/components/autofill_assistant/browser/web/web_controller_browsertest.cc
@@ -818,7 +818,7 @@ // Show the overlay in the first iframe, which covers the content // of that frame. void ShowOverlayInFrame() { - EXPECT_TRUE(ExecJs(shell()->web_contents()->GetAllFrames()[1], + EXPECT_TRUE(ExecJs(ChildFrameAt(shell()->web_contents(), 0), R"( document.getElementById("overlay_in_frame").style.visibility='visible'; )")); @@ -834,7 +834,7 @@ // Hide the overlay in the first iframe. void HideOverlayInFrame() { - EXPECT_TRUE(ExecJs(shell()->web_contents()->GetAllFrames()[1], + EXPECT_TRUE(ExecJs(ChildFrameAt(shell()->web_contents(), 0), R"( document.getElementById("overlay_in_frame").style.visibility='hidden'; )")); @@ -2503,7 +2503,7 @@ // Make sure the button is visible. EXPECT_TRUE( - ExecJs(shell()->web_contents()->GetAllFrames()[1], + ExecJs(ChildFrameAt(shell()->web_contents(), 0), "document.getElementById('button').scrollIntoViewIfNeeded();")); // The button is covered by an overlay in the main frame
diff --git a/components/page_load_metrics/browser/page_load_tracker.cc b/components/page_load_metrics/browser/page_load_tracker.cc index c48d52c..0c8fd21 100644 --- a/components/page_load_metrics/browser/page_load_tracker.cc +++ b/components/page_load_metrics/browser/page_load_tracker.cc
@@ -1049,8 +1049,10 @@ } // Reset the page end reason to END_NONE. The page has been restored, its - // previous end reason is no longer relevant. + // previous end reason is no longer relevant. Similarly, its page end time is + // no longer accurate, so reset that as well. page_end_reason_ = END_NONE; + page_end_time_ = base::TimeTicks(); } void PageLoadTracker::OnV8MemoryChanged(
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 38cfb48..62b8817 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -144,6 +144,13 @@ # 'default_for_managed_devices_doc_only', which documents an explicitly # implemented default policy value for managed devices. # +# 'items' is used to outline the behavior of each state the policy can take. +# This field is only used for policies of type 'main', 'int-enum', or +# 'string-enum'. For 'main' policies, it describes how the policy behaves when +# set to True or False, and whether the unset state is different from the +# enabled/disabled states. For 'enum' policies, it lists all possible values +# the policy can be set to along with a brief description. +# # Additional information is specified under the 'features' key: # 'dynamic_refresh' controls if the generated documentation should state that # the policy supports dynamic refresh or not. Supporting dynamic refresh means
diff --git a/components/policy/resources/policy_templates_de.xtb b/components/policy/resources/policy_templates_de.xtb index 92e44c0..c07421c 100644 --- a/components/policy/resources/policy_templates_de.xtb +++ b/components/policy/resources/policy_templates_de.xtb
@@ -1091,6 +1091,13 @@ <translation id="2299220924812062390">Liste der aktivierten Plug-ins angeben</translation> <translation id="2301048990069984110">Unterstützung für Chrome-Apps unter Windows, Mac und Linux verlängern.</translation> <translation id="2303795211377219696">„Automatisches Ausfüllen“ für Kreditkarten aktivieren</translation> +<translation id="2304009805995145854">Seit <ph name="PRODUCT_NAME" />-Version 67 ist die Website-Isolierung auf allen Desktop-Plattformen standardmäßig aktiviert. Dadurch wird jede Website in einem eigenen Prozess ausgeführt. Eine Website ist ein Protokoll plus eTLD+1 (z. B. https://beispiel.de). Wenn diese Richtlinie aktiviert ist, verändert sich dieses Verhalten nicht. Es wird lediglich verhindert, dass Nutzer die Einstellung ändern können und z. B. „Disable site isolation“ in chrome://flags verwenden. Seit <ph name="PRODUCT_NAME" />-Version 76 wird die Website-Isolierung nicht deaktiviert, wenn die Richtlinie deaktiviert oder nicht konfiguriert wird. Nutzer können sie stattdessen selbst deaktivieren. + + <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> bietet sich auch für die Isolierung spezifischer Ursprünge bei höherer Granularität als der Websiteebene an (z. B. https://a.beispiel.de). + + Setzen Sie unter <ph name="PRODUCT_OS_NAME" />-Version 76 oder niedriger die Geräterichtlinie <ph name="DEVICE_LOGIN_SCREEN_SITE_PER_PROCESS_POLICY_NAME" /> auf denselben Wert. Wenn die Werte nicht übereinstimmen, kann es beim Beginn von Nutzersitzungen zu einer Verzögerung kommen. + + Hinweis: Nutzen Sie unter Android stattdessen die Richtlinie <ph name="SITE_PER_PROCESS_ANDROID_POLICY_NAME" />.</translation> <translation id="2307496301287881990">Status von Display und Grafikkarte melden</translation> <translation id="2309390639296060546">Standardeinstellung für "Standortbestimmung"</translation> <translation id="2331354174913096226">Die URI-Vorlage des gewünschten DoH-Resolvers (DNS over HTTPS). Wenn Sie mehrere DoH-Resolver angeben möchten, trennen Sie die dazugehörigen URI-Vorlagen durch Leerzeichen. @@ -1151,6 +1158,17 @@ Wenn Sie "<ph name="VARIATIONS_DISABLED_OPTION_NAME" />" festlegen (Wert: 2), werden keine Variationen auf den Browser angewendet. Dieser Modus kann die <ph name="PRODUCT_NAME" />-Entwickler möglicherweise daran hindern, wichtige Sicherheitskorrekturen zeitnah durchzuführen. Er wird daher nicht empfohlen.</translation> <translation id="2402547085566757554">„Neuer Tab“-Seite nicht als Startseite verwenden</translation> +<translation id="240713331529749993">Wenn die Richtlinie konfiguriert ist, wird unter Android für jeden der benannten Ursprünge in einer durch Kommas getrennten Liste ein eigener Prozess ausgeführt. Jeder Prozess darf nur Dokumente aus diesem Ursprung und den zugehörigen Subdomains enthalten. Wird zum Beispiel https://a1.beispiel.de/ angegeben, ist https://a2.a1.beispiel.de/ im selben Prozess zulässig, https://beispiel.de oder https://b.beispiel.de aber nicht. Ab <ph name="PRODUCT_NAME" />-Version 77 werden unter Android bestimmte sensible Websites standardmäßig isoliert. Diese Richtlinie weitet diesen Modus auf die Isolierung zusätzlicher Ursprünge aus. + + Seit <ph name="PRODUCT_NAME" />-Version 77 kann auch ein Ursprungsbereich für die Isolierung angegeben werden. Dazu wird ein Platzhalter verwendet. Wenn Sie z. B. https://[*.]firma.beispiel.de angeben, wird für jeden Ursprung unter https://firma.beispiel.de ein eigener Prozess ausgeführt, einschließlich https://firma.beispiel.de selbst, https://a1.firma.beispiel.de und https://a2.a1.firma.beispiel.de. + + Beachten Sie auch, dass Ursprünge, die durch diese Richtlinie isoliert werden, keine anderen Ursprünge auf derselben Website skripten können. Das ist sonst möglich, wenn zwei SameSite-Dokumente ihre „document.domain“-Werte so verändern, dass sie übereinstimmen. Administratoren sollten sicherstellen, dass dieses ungewöhnliche Verhalten nicht für einen Ursprung verwendet wird, bevor er isoliert wird. + + Wenn diese Richtlinie deaktiviert ist, wird jegliche Form der Website-Isolierung deaktiviert, einschließlich der Isolierung sensibler Websites und Tests von IsolateOriginsAndroid, SitePerProcessAndroid und anderer Modi für die Website-Isolierung. Nutzer können aber weiter das Befehlszeilen-Flag verwenden, um IsolateOrigins manuell zu aktivieren. + + Ist die Richtlinie nicht konfiguriert, können Nutzer diese Einstellung ändern. + + Hinweis: Wenn unter Android zu viele Websites isoliert werden, kann dies Leistungsprobleme verursachen, vor allem auf leistungsschwächeren Geräten. Diese Richtlinie kann nur für Chrome unter Android auf Geräten mit mehr als 1 GB RAM verwendet werden. Für andere Plattformen als Android müssen Sie <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> verwenden.</translation> <translation id="2411629345938804022">Wenn die Richtlinie auf "3" gesetzt ist, können Websites den Zugriff auf Bluetooth-Geräte in der Nähe anfragen. Wenn die Richtlinie auf "2" gesetzt ist, wird der Zugriff auf Bluetooth-Geräte in der Nähe verweigert. Wird sie nicht konfiguriert, können Websites den Zugriff anfragen, Nutzer können diese Einstellung jedoch ändern.</translation> @@ -2686,6 +2704,17 @@ Wenn die Richtlinie deaktiviert oder nicht konfiguriert ist, können Nutzer Dateien auch über die Mobilfunkverbindung in Drive hochladen.</translation> <translation id="4248277954659222481">Autoplay von Medien für eine Zulassungsliste mit URL-Mustern erlauben</translation> <translation id="4250680216510889253">Nein</translation> +<translation id="4260027436474745627">Wenn die Richtlinie konfiguriert ist, wird für jeden der benannten Ursprünge in einer durch Kommas getrennten Liste ein eigener Prozess ausgeführt. Jeder Prozess darf nur Dokumente aus diesem Ursprung und den zugehörigen Subdomains enthalten. Wird zum Beispiel https://a1.beispiel.de/ angegeben, ist https://a2.a1.beispiel.de/ im selben Prozess zulässig, https://beispiel.de oder https://b.beispiel.de aber nicht. + + Seit <ph name="PRODUCT_NAME" />-Version 77 kann auch ein Ursprungsbereich für die Isolierung angegeben werden. Dazu wird ein Platzhalter verwendet. Wenn Sie z. B. https://[*.]firma.beispiel.de angeben, wird für jeden Ursprung unter https://firma.beispiel.de ein eigener Prozess ausgeführt, einschließlich https://firma.beispiel.de selbst, https://a1.firma.beispiel.de und https://a2.a1.firma.beispiel.de. + + Beachten Sie, dass alle Websites (also Protokoll plus eTLD+1, z. B. https://beispiel.de) auf Desktop-Plattformen bereits standardmäßig isoliert werden, wie in der Richtlinie <ph name="SITE_PER_PROCESS_POLICY_NAME" /> angegeben. Die Richtlinie <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> bietet sich auch für die Isolierung spezifischer Ursprünge bei höherer Granularität an (z. B. https://a.beispiel.de). + + Beachten Sie auch, dass Ursprünge, die durch diese Richtlinie isoliert werden, keine anderen Ursprünge auf derselben Website skripten können. Das ist sonst möglich, wenn zwei SameSite-Dokumente ihre „document.domain“-Werte so verändern, dass sie übereinstimmen. Administratoren sollten sicherstellen, dass dieses ungewöhnliche Verhalten nicht für einen Ursprung verwendet wird, bevor er isoliert wird. + + Wenn die Richtlinie deaktiviert oder nicht konfiguriert ist, können Nutzer diese Einstellung ändern. + + Hinweis: Nutzen Sie unter Android stattdessen die Richtlinie <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" />.</translation> <translation id="4261820385751181068">Sprache der Anmeldeseite</translation> <translation id="4266547484666068234">Mit dieser Richtlinie kann auf die aufgeführten URLs zugegriffen werden (als Ausnahmen von <ph name="URL_BLOCKLIST_POLICY_NAME" />). Informationen zum Format der Einträge in der Liste finden Sie in der Beschreibung der Richtlinie. Beispielsweise werden alle Anfragen blockiert, wenn Sie <ph name="URL_BLOCKLIST_POLICY_NAME" /> auf * setzen. Sie können diese Richtlinie verwenden, um den Zugriff auf eine eingeschränkte Liste mit URLs zu erlauben. Mit ihr lassen sich bei Verwendung des unter https://www.chromium.org/administrators/url-blocklist-filter-format angegebenen Formats Ausnahmen für bestimmte Schemata, Subdomains anderer Domains, Ports oder bestimmte Pfade festlegen. Mit dem spezifischsten Filter wird festgelegt, ob eine URL blockiert oder zulässig ist. Die Richtlinie <ph name="URL_ALLOWLIST_POLICY_NAME" /> hat Vorrang vor <ph name="URL_BLOCKLIST_POLICY_NAME" />. Diese Richtlinie ist auf 1.000 Einträge beschränkt. @@ -3555,6 +3584,15 @@ </translation> <translation id="5435888298115339571">Desktop-Freigabe in der Omnibox und im Dreipunkt-Menü aktivieren</translation> <translation id="5442026853063570579">Mit dieser Richtlinie wird außerdem der Zugriff auf Android-Entwickleroptionen festgelegt. Wenn Sie diese Richtlinie auf "DeveloperToolsDisallowed" (Wert 2) setzen, können Nutzer nicht auf die Entwickleroptionen zugreifen. Wenn Sie diese Richtlinie auf einen anderen Wert setzen oder sie nicht festlegen, können Nutzer auf die Entwickleroptionen zugreifen, indem sie in der Android-App "Einstellungen" siebenmal auf die Build-Nummer tippen.</translation> +<translation id="5443582909255996887">Wenn die Richtlinie aktiviert ist, werden unter Android alle Websites isoliert. Jede Website wird dann in einem eigenen Prozess ausgeführt. Nutzer können diese Einstellung nicht ändern. Eine Website ist ein Protokoll plus eTLD+1 (z. B. https://beispiel.de). Ab <ph name="PRODUCT_NAME" />-Version 77 werden unter Android bestimmte sensible Websites standardmäßig isoliert. Diese Richtlinie weitet diesen Modus für die standardmäßige Website-Isolierung auf alle Websites aus. + + Wenn diese Richtlinie deaktiviert ist, wird jegliche Form der Website-Isolierung deaktiviert, einschließlich der Isolierung sensibler Websites und Tests von IsolateOriginsAndroid, SitePerProcessAndroid und anderer Modi für die Website-Isolierung. Nutzer können die Richtlinie aber weiterhin manuell aktivieren. + + Wenn die Richtlinie nicht konfiguriert ist, können Nutzer diese Einstellung ändern. + + <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> kann auch für die Isolierung spezifischer Ursprünge bei höherer Granularität als der Websiteebene nützlich sein (z. B. https://a.beispiel.de). + + Hinweis: Die Unterstützung der Isolierung jeder Website unter Android wird weiter verbessert. Derzeit kann sie aber Leistungsprobleme verursachen, vor allem auf leistungsschwächeren Geräten. Diese Richtlinie kann nur für Chrome unter Android auf Geräten mit mehr als 1 GB RAM verwendet werden. Wenn Sie bestimmte Websites isolieren und die Leistungseinbußen dabei so gering wie möglich halten möchten, verwenden Sie <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> mit einer Liste der Websites, die isoliert werden sollen. Für andere Plattformen als Android müssen Sie <ph name="SITE_PER_PROCESS_POLICY_NAME" /> verwenden.</translation> <translation id="5445596354079213552">Diese Richtlinie wird nur angewendet, wenn das Gerät das Ablaufdatum für die automatische Aktualisierung erreicht hat und die durch die Richtlinie <ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" /> festgelegte Mindestanforderung im Hinblick auf die <ph name="PRODUCT_OS_NAME" />-Version nicht mehr erfüllt. Wenn für diese Richtlinie ein String definiert wird, der nicht leer ist, gilt Folgendes: @@ -6135,6 +6173,7 @@ Ab Version 92 von <ph name="PRODUCT_NAME" /> wird diese Richtlinie auch im monitorlosen Modus unterstützt. Hinweis: Wenn interne „chrome://*“-URLs blockiert werden, können unerwartete Fehler auftreten.</translation> +<translation id="8626826495474944836">Website-Isolierung für jede Website erzwingen</translation> <translation id="8631434304112909927">Bis Version <ph name="UNTIL_VERSION" /></translation> <translation id="8631437968147930597">Die Liste der Notizen-Apps, die auf dem Sperrbildschirm von <ph name="PRODUCT_OS_NAME" /> zulässig sind</translation> <translation id="8637566476051166626">Ausdrücklich erlaubte Netzwerkports</translation>
diff --git a/components/policy/resources/policy_templates_it.xtb b/components/policy/resources/policy_templates_it.xtb index c14a60c5..4e31ff8 100644 --- a/components/policy/resources/policy_templates_it.xtb +++ b/components/policy/resources/policy_templates_it.xtb
@@ -1099,6 +1099,13 @@ <translation id="2299220924812062390">Consente di specificare un elenco dei plug-in attivati</translation> <translation id="2301048990069984110">Estendi il supporto delle app di Chrome su Windows, Mac e Linux</translation> <translation id="2303795211377219696">Attiva la Compilazione automatica per le carte di credito</translation> +<translation id="2304009805995145854">A partire da <ph name="PRODUCT_NAME" /> 67, l'isolamento dei siti è stato attivato per impostazione predefinita su tutte le piattaforme desktop, così che ogni sito venga eseguito nel proprio processo. Ogni sito è uno schema più eTLD+1 (ad es. https://example.com). Se il criterio viene impostato su Attivato, il comportamento non cambia; impedisce solo la disattivazione da parte degli utenti (ad esempio, utilizzando la voce "Disattiva l'isolamento dei siti" in chrome://flags). A partire da <ph name="PRODUCT_NAME" /> 76, se il criterio viene impostato su Disattivato o se non viene configurato, l'isolamento dei siti non viene disattivato, ma è consentita la disattivazione da parte degli utenti. + + <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> potrebbe anche essere utile per l'isolamento di origini specifiche a una granularità maggiore rispetto al sito (ad es. https://a.example.com). + + In <ph name="PRODUCT_OS_NAME" /> 76 o versioni precedenti, imposta il criterio relativo ai dispositivi <ph name="DEVICE_LOGIN_SCREEN_SITE_PER_PROCESS_POLICY_NAME" /> sullo stesso valore, perché, se i valori non corrispondono, potrebbe verificarsi un ritardo quando si accede a una sessione utente. + + Nota: per Android, utilizza invece il criterio <ph name="SITE_PER_PROCESS_ANDROID_POLICY_NAME" />.</translation> <translation id="2307496301287881990">Segnala stati del display e della grafica</translation> <translation id="2309390639296060546">Impostazione di geolocalizzazione predefinita</translation> <translation id="2331354174913096226">Il modello URI del resolver DNS over HTTPS desiderato. Per specificare diversi resolver DNS over HTTPS, separa i modelli URI corrispondenti con gli spazi. @@ -1159,6 +1166,17 @@ La configurazione di <ph name="VARIATIONS_DISABLED_OPTION_NAME" /> (valore 2) impedisce di applicare al browser tutte le varianti. Questa modalità potrebbe impedire agli sviluppatori di <ph name="PRODUCT_NAME" /> di fornire tempestivamente correzioni fondamentali per la sicurezza ed è pertanto sconsigliata.</translation> <translation id="2402547085566757554">Non usare la pagina Nuova scheda come home page</translation> +<translation id="240713331529749993">Se il criterio viene configurato, ciascuna delle origini denominate in un elenco separato da virgole viene eseguita in un processo dedicato su Android. Il processo di ogni origine denominata potrà contenere solo documenti provenienti da tale origine e i relativi sottodomini. Ad esempio, specificare https://a1.example.com/ consente https://a2.a1.example.com/ nello stesso processo, ma non https://example.com o https://b.example.com. Tieni presente che Android isola alcuni siti sensibili per impostazione predefinita a partire da <ph name="PRODUCT_NAME" /> 77 e il criterio estende questa modalità per isolare origini aggiuntive specifiche. + + A partire da <ph name="PRODUCT_NAME" /> 77, puoi specificare anche un intervallo di origini da isolare utilizzando un carattere jolly. FAd esempio, specificare https://[*.]corp.example.com consentirà a ogni origine al di sotto di https://corp.example.com il proprio processo dedicato, inclusi https://corp.example.com stesso, https://a1.corp.example.com e https://a2.a1.corp.example.com. + + Tieni presente che le origini isolate da questo criterio non potranno scrivere altre origini nello stesso sito, processo possibile se due documenti dello stesso sito modificano i propri valori document.docmani affinché corrispondano. Gli amministratori devono confermare che questo comportamento non comune non venga utilizzato su un'origine prima di isolarla. + + Se il criterio viene impostato su Disattivato, vengono disattivati tutti i tipi di isolamento dei siti, inclusi quelli di siti sensibili, prove sul campo di IsolateOriginsAndroid, SitePerProcessAndroid e altre modalità di isolamento dei siti. Gli utenti possono comunque attivare IsolateOrigins manualmente usando il flag della riga di comando. + + Se il criterio non viene configurato, gli utenti possono modificare questa impostazione. + + Nota: se vengono isolati troppi siti su Android, potrebbero verificarsi problemi di prestazioni, in particolare sui dispositivi con poca memoria. Questo criterio viene applicato solo a Chrome su dispositivi Android con più di 1 GB di RAM. Per applicare il criterio a piattaforme non Androd, utilizza <ph name="ISOLATE_ORIGINS_POLICY_NAME" />.</translation> <translation id="2411629345938804022">Se il criterio è impostato su 3, i siti web possono chiedere l'accesso ai dispositivi Bluetooth nelle vicinanze. Se il criterio è impostato su 2, l'accesso ai dispositivi Bluetooth nelle vicinanze viene negato. Se il criterio non viene configurato, i siti possono chiedere l'accesso, ma gli utenti possono modificare l'impostazione.</translation> @@ -2690,6 +2708,17 @@ Se il criterio viene impostato su Disattivato o se non viene configurato, gli utenti potranno trasferire i file su Drive tramite la connessione a una rete cellulare.</translation> <translation id="4248277954659222481">Consenti la riproduzione automatica dei contenuti multimediali per una lista consentita di pattern URL</translation> <translation id="4250680216510889253">No</translation> +<translation id="4260027436474745627">Se il criterio viene configurato, ciascuna delle origini denominate in un elenco separato da virgole viene eseguita in un processo dedicato. Il processo di ogni origine denominata potrà contenere solo documenti provenienti da tale origine e i relativi sottodomini. Ad esempio, specificare https://a1.example.com/ consente https://a2.a1.example.com/ nello stesso processo, ma non https://example.com o https://b.example.com. + + A partire da <ph name="PRODUCT_NAME" /> 77, puoi specificare anche un intervallo di origini da isolare utilizzando un carattere jolly. Ad esempio, specificare https://[*.]corp.example.com consentirà a ogni origine al di sotto di https://corp.example.com il proprio processo dedicato, inclusi https://corp.example.com stesso, https://a1.corp.example.com e https://a2.a1.corp.example.com. + + Tieni presente che tutti i siti (vale a dire schema più eTLD+1, come https://example.com) sono già isolati per impostazione predefinita sulle piattaforme desktop, come specificato nel criterio <ph name="SITE_PER_PROCESS_POLICY_NAME" />. Il criterio <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> è utile per isolare origini specifiche a una granularità maggiore (ad es. https://a.example.com). + + Tieni anche presente che le origini isolate da questo criterio non potranno scrivere altre origini nello stesso sito, processo possibile se due documenti dello stesso sito modificano i propri valori document.docmani affinché corrispondano. Gli amministratori devono confermare che questo comportamento non comune non venga utilizzato su un'origine prima di isolarla. + + Se il criterio viene disattivato o non viene configurato, gli utenti possono modificare questa impostazione. + + Nota: per Android, utilizza invece il criterio <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" />.</translation> <translation id="4261820385751181068">Lingua della schermata di accesso del dispositivo</translation> <translation id="4266547484666068234">La configurazione del criterio consente di fornire l'accesso agli URL elencati, sotto forma di eccezioni a <ph name="URL_BLOCKLIST_POLICY_NAME" />. Leggi la descrizione del criterio per conoscere il formato delle voci di questo elenco. Ad esempio, se imposti il criterio <ph name="URL_BLOCKLIST_POLICY_NAME" /> su *, tutte le richieste verranno bloccate e puoi utilizzare questo criterio per consentire l'accesso a un elenco limitato di URL. Utilizzalo per aprire le eccezioni di alcuni schemi, sottodomini di altri domini, porte o percorsi specifici utilizzando il formato specificato all'indirizzo https://www.chromium.org/administrators/url-blocklist-filter-format. Il filtro più specifico consente di determinare se un URL è bloccato o consentito. Il criterio <ph name="URL_ALLOWLIST_POLICY_NAME" /> ha la precedenza sul criterio <ph name="URL_BLOCKLIST_POLICY_NAME" />. Per questo criterio è possibile definire al massimo 1000 voci. @@ -3563,6 +3592,15 @@ </translation> <translation id="5435888298115339571">Attiva la condivisione desktop nel menu con tre puntini e in omnibox</translation> <translation id="5442026853063570579">Questa norma consente di controllare anche l'accesso alle Opzioni sviluppatore di Android. Se la norma viene impostata su "DeveloperToolsDisallowed" (valore 2), gli utenti non potranno accedere alle Opzioni sviluppatore. Se la norma viene impostata su un altro valore o non viene impostata, gli utenti potranno accedere alle Opzioni sviluppatore toccando sette volte il numero di build nell'app Impostazioni di Android.</translation> +<translation id="5443582909255996887">Se il criterio viene impostato su Attivato, tutti i siti vengono isolati su Android, così che ogni sito venga eseguito nel proprio processo e la disattivazione da parte degli utenti viene impedita. Ogni sito è uno schema più eTLD+1 (ad es. https://example.com). Tieni presente che Android isola alcuni siti sensibili per impostazione predefinita a partire da <ph name="PRODUCT_NAME" /> 77 e il criterio estende questa modalità di isolamento dei siti predefinita affinché venga applicata a tutti i siti. + + Se il criterio viene impostato su Disattivato, vengono disattivati tutti i tipi di isolamento dei siti, inclusi quelli di siti sensibili, prove sul campo di IsolateOriginsAndroid, SitePerProcessAndroid e altre modalità di isolamento dei siti. Gli utenti possono comunque attivare il criterio manualmente. + + Se il criterio non viene configurato, gli utenti possono modificare questa impostazione. + + <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> potrebbe anche essere utile per l'isolamento di origini specifiche a una granularità maggiore rispetto al sito (ad es. https://a.example.com). + + Nota: il supporto dell'isolamento verrà migliorato per tutti i siti su Android, ma al momento potrebbe causare problemi di prestazioni, specialmente sui dispositivi di fascia bassa. Questo criterio viene applicato solo a Chrome su dispositivi Android con più di 1 GB di RAM. Per isolare siti specifici limitando l'impatto sulle prestazioni per gli utenti, utilizza <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> con un elenco di siti che vuoi isolare. Per applicare il criterio a piattaforme non Androd, utilizza <ph name="SITE_PER_PROCESS_POLICY_NAME" />.</translation> <translation id="5445596354079213552">Questo criterio viene applicato soltanto se il dispositivo ha raggiunto la scadenza dell'aggiornamento automatico e non rispetta la versione minima consentita di <ph name="PRODUCT_OS_NAME" /> impostata tramite il criterio <ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" />. Se il criterio viene impostato su una stringa non vuota: @@ -6134,6 +6172,7 @@ A partire dalla versione 92 di <ph name="PRODUCT_NAME" />, questo criterio è supportato anche nella modalità headless. Nota: il blocco degli URL chrome://* interni può generare errori imprevisti.</translation> +<translation id="8626826495474944836">Richiedi isolamento dei siti per ogni sito</translation> <translation id="8631434304112909927">fino alla versione <ph name="UNTIL_VERSION" /></translation> <translation id="8631437968147930597">L'elenco delle app per scrivere note consentite nella schermata di blocco di <ph name="PRODUCT_OS_NAME" /></translation> <translation id="8637566476051166626">Porte di rete esplicitamente consentite</translation>
diff --git a/components/policy/resources/policy_templates_ja.xtb b/components/policy/resources/policy_templates_ja.xtb index d92adabf..7eb2b4a5 100644 --- a/components/policy/resources/policy_templates_ja.xtb +++ b/components/policy/resources/policy_templates_ja.xtb
@@ -1082,6 +1082,7 @@ <translation id="2299220924812062390">有効なプラグインのリストを指定する</translation> <translation id="2301048990069984110">Windows、Mac、Linux で Chrome アプリを使用できるようサポートを拡張する。</translation> <translation id="2303795211377219696">クレジット カードの自動入力を有効にする</translation> +<translation id="2304009805995145854"><ph name="PRODUCT_NAME" /> 67 以降、サイト分離はすべてのデスクトップ プラットフォームでデフォルトで有効になっており、すべてのサイトが独自のプロセスで実行されます。サイトは、スキームと eTLD+1 で構成されます(例: https://example.com)。このポリシーを有効にしても、ユーザーによる無効化(サイト分離を無効にする chrome://flags の使用など)ができなくなる点以外に、動作の変更はありません。<ph name="PRODUCT_NAME" /> 76 以降では、このポリシーを無効に設定するか未設定のままにしても、サイト分離は依然として有効のままですが、ユーザーが無効にできるようになります。<ph name="ISOLATE_ORIGINS_POLICY_NAME" /> を使用して、サイト単位でなく、より細かいレベルで発行元を指定して分離することもできます(例: https://a.example.com)。<ph name="PRODUCT_OS_NAME" /> バージョン 76 以前では、<ph name="DEVICE_LOGIN_SCREEN_SITE_PER_PROCESS_POLICY_NAME" /> デバイス ポリシーを同じ値に設定してください(値が異なる場合、ユーザー セッションの開始時に遅延が生じる可能性があります)。注: Android では代わりに <ph name="SITE_PER_PROCESS_ANDROID_POLICY_NAME" /> ポリシーを使用してください。</translation> <translation id="2307496301287881990">ディスプレイとグラフィックのステータスを報告する</translation> <translation id="2309390639296060546">デフォルトの位置情報設定</translation> <translation id="2331354174913096226">希望の DNS-over-HTTPS リゾルバの URI テンプレートを指定します。複数の DNS-over-HTTPS リゾルバを指定するには、対応する URI テンプレートをスペースで区切ります。 @@ -1140,6 +1141,9 @@ <ph name="VARIATIONS_DISABLED_OPTION_NAME" />(値 2)に設定した場合は、どのバリエーションもブラウザに適用できません。このモードは、<ph name="PRODUCT_NAME" /> のデベロッパーがセキュリティに関する重要な修正を適切なタイミングで適用できない場合があるため推奨されません。</translation> <translation id="2402547085566757554">新しいタブページをホームページとして使用しない</translation> +<translation id="240713331529749993">このポリシーを設定した場合、カンマ区切りのリストで指定した発行元は、Android 上でそれぞれ独自のプロセスで実行されます。指定した発行元のプロセスで使用できるのは、発行元およびそのサブドメインのドキュメントだけです。たとえば、https://a1.example.com/ を指定した場合、https://a2.a1.example.com/ は同一のプロセスで実行されますが、https://example.com や https://b.example.com はこの限りではありません。Android では <ph name="PRODUCT_NAME" /> バージョン 77 以降、特定のデリケートなコンテンツを含むウェブサイトがデフォルトで分離されており、このポリシーによってデフォルトのサイト分離モードが特定の発行元にも適用されます。<ph name="PRODUCT_NAME" /> 77 以降であれば、ワイルドカードを使用し、分離する発行元の範囲を指定できます。たとえば、https://[*.]corp.example.com を指定した場合、https://corp.example.com 以下の発行元に対して同じ独自プロセスが適用されます。これには https://corp.example.com 自体が該当するほか、https://a1.corp.example.com や https://a2.a1.corp.example.com も含まれます。 + + このポリシーで分離した発行元では、同一サイト内の他の発行元をスクリプト化することはできません。ただし、同じサイトの 2 つのドキュメント内で、document.domain の値が同一のものに変更されれば、このスクリプト化は可能になります。これは一般には行いません。管理者は、発行元の分離前にこのような操作が行われないよう管理する必要があります。このポリシーを無効に設定した場合は、すべてのサイト分離が無効になります。これには、デリケートなコンテンツを含むサイトの分離、IsolateOriginsAndroid と SitePerProcessAndroid のフィールド テスト、その他のサイト分離モードが含まれます。ただしユーザーはコマンドライン フラグを使用して手動で IsolateOrigins を有効にできます。このポリシーを未設定のままにした場合、ユーザーはこの設定を変更できます。注: Android で大量のサイトを分離する場合、特にメモリ容量の少ないデバイスでパフォーマンスに影響が生じる可能性があります。このポリシーは、厳密に 1 GB より大きい RAM を搭載した Android デバイスの Chrome のみに適用されます。Android 以外のプラットフォームにこのポリシーを適用するには、<ph name="ISOLATE_ORIGINS_POLICY_NAME" /> を使用してください。</translation> <translation id="2411629345938804022">このポリシーを 3 に設定した場合、ウェブサイトに対して周辺の Bluetooth デバイスへのアクセスの要求が許可されます。このポリシーを 2 に設定した場合、周辺の Bluetooth デバイスへのアクセスは拒否されます。 このポリシーを未設定のままにした場合、サイトに対してアクセスの要求は許可されますが、ユーザーはこの設定を変更できます。</translation> @@ -1431,6 +1435,7 @@ <translation id="2725855586003209701">このポリシーを有効にするか、未設定のままにすると、登録済みのデバイスは最近ログインしたデバイス ユーザーのリストを報告します。 このポリシーを無効に設定すると、登録済みのデバイスはユーザーのリストを報告しません。</translation> +<translation id="2730419309754848345">「PDF を画像として印刷する」のデフォルト</translation> <translation id="2731627323327011390">ARC アプリで <ph name="PRODUCT_OS_NAME" /> の証明書を使用できないようにする</translation> <translation id="2742843273354638707">[新しいタブ] ページと <ph name="PRODUCT_OS_NAME" /> のアプリ ランチャーで、Chrome ウェブストア アプリとフッターのリンクを非表示にします。 @@ -2645,6 +2650,11 @@ このポリシーを無効に設定するか未設定のままにした場合、ユーザーはモバイル接続時にドライブにファイルを転送できます。</translation> <translation id="4248277954659222481">メディアの自動再生を許可する URL パターンのリストを指定する</translation> <translation id="4250680216510889253">いいえ</translation> +<translation id="4260027436474745627">このポリシーを設定した場合、カンマ区切りのリストで指定した発行元はそれぞれ独自のプロセスで実行されます。指定した発行元のプロセスで使用できるのは、発行元およびそのサブドメインのドキュメントだけです。たとえば、https://a1.example.com/ を指定した場合、https://a2.a1.example.com/ は同一のプロセスで実行されますが、https://example.com や https://b.example.com はこの限りではありません。 + + <ph name="PRODUCT_NAME" /> 77 以降であれば、ワイルドカードを使用し、分離する発行元の範囲を指定できます。たとえば、https://[*.]corp.example.com を指定した場合、https://corp.example.com 以下の発行元に対して同じ独自プロセスが適用されます。これには https://corp.example.com 自体が該当するほか、https://a1.corp.example.com や https://a2.a1.corp.example.com も含まれます。 + + <ph name="SITE_PER_PROCESS_POLICY_NAME" /> ポリシーで言及されているとおり、すべてのサイト(https://example.com のような、スキームと eTLD+1 の組み合わせ)は、デスクトップ プラットフォームではデフォルトで分離されます。この <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> ポリシーは、発行元をより細かいレベル(例: https://a.example.com)で指定して分離するのに有効です。このポリシーで分離した発行元では、同一サイト内の他の発行元をスクリプト化することはできません。ただし、同じサイトの 2 つのドキュメント内で、document.domain の値が同一のものに変更されれば、このスクリプト化は可能になります。これは一般には行いません。管理者は、発行元の分離前にこのような操作が行われないよう管理する必要があります。このポリシーを無効に設定するか未設定のままにした場合、ユーザーはこの設定を変更できます。注: Android では代わりに <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> ポリシーを使用してください。</translation> <translation id="4261820385751181068">デバイスのログイン画面の言語 / 地域</translation> <translation id="4266547484666068234">このポリシーでは、<ph name="URL_BLOCKLIST_POLICY_NAME" /> の例外としてアクセスを許可する URL のリストを指定できます。リストの指定形式については、このポリシーの説明をご覧ください。このポリシーは、たとえば <ph name="URL_BLOCKLIST_POLICY_NAME" /> で「*」と設定してすべてのリクエストをブロックし、限定された一部の URL のみアクセスを許可する場合に使用します。つまり、特定のスキームや、他のドメインのサブドメイン、ポート、具体的なパスについて例外を設定します。設定の際は、https://www.chromium.org/administrators/url-blocklist-filter-format で指定された形式を使用します。URL をブロックするか許可するかは、最も具体的なフィルタによって決定されます。<ph name="URL_ALLOWLIST_POLICY_NAME" /> ポリシーは、<ph name="URL_BLOCKLIST_POLICY_NAME" /> より優先されます。このポリシーで指定できる URL は最大 1,000 件です。 @@ -3156,6 +3166,7 @@ <translation id="4988291787868618635">アイドル時間に到達したときに行われる操作</translation> <translation id="4996068111491152684"><ph name="PRODUCT_OS_NAME" /> のログイン認証情報をネットワーク認証に使用しない。</translation> <translation id="4996086761250834365"><ph name="PLUGIN_VM_NAME" /> のサービス分析を許可する</translation> +<translation id="4997074784107449343">「画像として印刷する」オプションが使用可能な場合、「画像として印刷する」オプションは PDF ドキュメントの印刷プレビューでデフォルトで設定されません。</translation> <translation id="500149597848135831">すべてのバリエーションを有効にします</translation> <translation id="5017369989680827157">このポリシーを True に設定するか未設定のままにした場合、ユーザーは UI で住所の自動入力を制御できます。このポリシーを False に設定した場合、住所情報が候補として表示されたり、自動入力されたりすることはありません。また、ユーザーがウェブの利用中に送信した住所情報が追加で保存されることもありません。</translation> <translation id="5021550478471824215">このポリシーでは、事前設定のネットワーク ファイル共有のリストを指定できます。個々の項目は、<ph name="SHARE_URL_FIELD_NAME" /> と <ph name="MODE_FIELD_NAME" /> の 2 つのプロパティで構成されるオブジェクトとなります。 @@ -3488,6 +3499,7 @@ </translation> <translation id="5435888298115339571">アドレスバーとその他メニューでデスクトップ共有を有効にする</translation> <translation id="5442026853063570579">このポリシーでは、Android 開発者向けオプションへのアクセスも管理できます。このポリシーを「DeveloperToolsDisallowed」(値 2)に設定した場合、ユーザーは開発者向けオプションにアクセスできません。このポリシーを別の値に設定するか未設定のままにした場合、ユーザーは Android 設定アプリのビルド番号を 7 回タップすれば開発者向けオプションにアクセスできます。</translation> +<translation id="5443582909255996887">このポリシーを有効に設定した場合、Android ではすべてのサイトが分離され、各サイトが独自のプロセスで実行されます。ユーザーが無効にすることはできません。サイトは、スキームと eTLD+1 で構成されます(例: https://example.com)。Android では <ph name="PRODUCT_NAME" /> バージョン 77 以降、特定のデリケートなコンテンツを含むウェブサイトがデフォルトで分離されており、このポリシーによってデフォルトのサイト分離モードがすべてのサイトに適用されます。このポリシーを無効に設定した場合は、すべてのサイト分離が無効になります。これには、デリケートなコンテンツを含むサイトの分離、IsolateOriginsAndroid と SitePerProcessAndroid のフィールド テスト、その他のサイト分離モードが含まれます。ただし、ユーザーはポリシーを手動で有効にできます。このポリシーを未設定のままにした場合、ユーザーはこの設定を変更できます。<ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> を使用して、サイト単位でなく、より細かいレベルで発行元を指定して分離することもできます(例: https://a.example.com)。注: 今後は改善される予定ですが、Android ですべてのサイトを分離する場合、現在は特にローエンドのデバイスでパフォーマンスに影響が生じる可能性があります。このポリシーは、厳密に 1 GB より大きい RAM を搭載した Android デバイスの Chrome のみに適用されます。ユーザーへのパフォーマンス上の影響を抑えつつ、特定のサイトを分離する場合は、<ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> で分離するサイトのリストを指定してください。Android 以外のプラットフォームにこのポリシーを適用するには、<ph name="SITE_PER_PROCESS_POLICY_NAME" /> を使用してください。</translation> <translation id="5445596354079213552">このポリシーは、デバイスが自動更新の有効期限に達していて、<ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" /> ポリシーで設定された <ph name="PRODUCT_OS_NAME" /> の最小バージョン要件を満たしていない場合にのみ有効です。 このポリシーを空でない文字列に設定した場合: @@ -3885,6 +3897,13 @@ このポリシーを無効に設定した場合、QUIC プロトコルの使用は許可されません。</translation> <translation id="5921713479449475707">HTTP 経由での自動更新ダウンロードを許可する</translation> +<translation id="5928633129285224981"><ph name="PRODUCT_NAME" /> で PDF の印刷時に「画像として印刷する」オプションがデフォルトで設定されるかどうかを管理します。 + + このポリシーを有効に設定した場合、<ph name="PRODUCT_NAME" /> では PDF の印刷時に、印刷プレビューで「画像として印刷する」オプションがデフォルトで設定されます。 + + このポリシーを無効にするか未設定のままにした場合、<ph name="PRODUCT_NAME" /> では「画像として保存する」オプションのユーザー選択は最初は設定されません。このオプションが使用可能な場合、ユーザーは各 PDF 印刷ジョブで選択できます。 + + <ph name="MS_WIN_NAME" /> または <ph name="MAC_OS_NAME" /> では、このポリシーが効果を持つのは、<ph name="PRINT_PDF_AS_IMAGE_AVAILABILITY_POLICY_NAME" /> も有効になっている場合に限られます。</translation> <translation id="5929855945144989709">Chrome OS での仮想マシンの実行をデバイスに許可する</translation> <translation id="5932767795525445337">このポリシーを使って Android アプリを固定することもできます。</translation> <translation id="5934763632608026594">このポリシーでは、<ph name="PRODUCT_NAME" /> のウェブアプリ管理設定を管理できます。 @@ -5608,6 +5627,7 @@ このポリシーを無効にするか、未設定のままにすると、パケットは送信されません。</translation> <translation id="816783746144552109">デバイスでの使用を許可する Chrome の最小バージョンを設定する。</translation> <translation id="8171924760436219650">ログイン画面でマウスのメインボタンを右に切り替える</translation> +<translation id="8173864651667424191">「画像として印刷する」オプションが使用可能な場合、「画像として印刷する」オプションは PDF ドキュメントの印刷プレビューでデフォルトで設定されます。</translation> <translation id="8176035528522326671">企業ユーザーがメインのマルチプロフィール ユーザーとしてのみ操作できるようにする(企業の管理対象ユーザーに対するデフォルトの動作)</translation> <translation id="8179161412673077784">不正なコンテンツを提供するサイトが新しいウィンドウやタブで開くことを許可しない</translation> <translation id="8183108371184777472">ブラウザ ウィンドウの起動を抑制する</translation> @@ -5977,6 +5997,7 @@ <ph name="PRODUCT_NAME" /> バージョン 92 以降、このポリシーはヘッドレス モードでもサポートされるようになりました。 注: 「chrome://*」の内部 URL をブロックすると、予期しないエラーが発生する可能性があります。</translation> +<translation id="8626826495474944836">すべてのサイトに対してサイト分離を必須にする</translation> <translation id="8631434304112909927">バージョン <ph name="UNTIL_VERSION" /> まで</translation> <translation id="8631437968147930597"><ph name="PRODUCT_OS_NAME" /> のロック画面で許可されるメモアプリのリスト</translation> <translation id="8637566476051166626">明示的に許可するネットワーク ポートを指定する</translation>
diff --git a/components/policy/resources/policy_templates_ko.xtb b/components/policy/resources/policy_templates_ko.xtb index 8afe1a5..b3a331a 100644 --- a/components/policy/resources/policy_templates_ko.xtb +++ b/components/policy/resources/policy_templates_ko.xtb
@@ -1104,6 +1104,13 @@ <translation id="2299220924812062390">사용 설정한 플러그인 목록 지정</translation> <translation id="2301048990069984110">Windows, Mac, Linux에서 Chrome 앱 지원을 확장합니다.</translation> <translation id="2303795211377219696">신용카드 정보 자동 완성 사용</translation> +<translation id="2304009805995145854"><ph name="PRODUCT_NAME" /> 67부터 모든 데스크톱 플랫폼에서 사이트 격리가 기본적으로 사용 설정되므로 모든 사이트가 자체 프로세스로 실행됩니다. 사이트는 스킴 플러스 eTLD+1(예: https://example.com)입니다. 이 정책을 사용 설정해도 동작은 변경되지 않으며, 사용자가 정책을 선택 해제할 수 없을 뿐입니다(예: chrome://flags에서 사이트 격리 사용 안함). <ph name="PRODUCT_NAME" /> 76부터 이 정책을 사용 안함으로 설정하거나 설정하지 않아도 사이트 격리는 사용 중지되지 않으며 대신 사용자가 선택 해제할 수 있습니다. + + 사이트보다 더 세부적인 수준으로 특정 출처를 격리하려면 <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> 정책을 사용하는 것이 유용할 수 있습니다(예: https://a.example.com). + + <ph name="PRODUCT_OS_NAME" /> 버전 76 이전의 경우 <ph name="DEVICE_LOGIN_SCREEN_SITE_PER_PROCESS_POLICY_NAME" /> 기기 정책을 같은 값으로 설정하세요. 값이 일치하지 않으면 사용자 세션을 시작할 때 지연이 발생할 수 있습니다. + + 참고: Android에서는 대신 <ph name="SITE_PER_PROCESS_ANDROID_POLICY_NAME" /> 정책을 사용하세요.</translation> <translation id="2307496301287881990">디스플레이 및 그래픽 상태 보고</translation> <translation id="2309390639296060546">기본 위치정보 설정</translation> <translation id="2331354174913096226">원하는 DNS-over-HTTPS 리졸버의 URI 템플릿입니다. 여러 개의 DNS-over-HTTPS 리졸버를 지정하려면 해당하는 URI 템플릿을 공백으로 구분하세요. @@ -1164,6 +1171,17 @@ <ph name="VARIATIONS_DISABLED_OPTION_NAME" /> 옵션을 설정하면(값 2) 어떤 변형도 브라우저에 적용할 수 없습니다. 이 모드를 사용하면 <ph name="PRODUCT_NAME" /> 개발자가 중요한 보안 수정사항을 신속히 제공하지 못할 수 있으므로 권장되지 않습니다.</translation> <translation id="2402547085566757554">새 탭 페이지를 홈페이지로 사용 안함</translation> +<translation id="240713331529749993">정책을 설정하면 쉼표로 구분된 목록의 이름이 지정된 각 출처가 Android에서 전용 프로세스로 실행됩니다. 이름이 지정된 각 출처의 프로세스에는 해당 출처와 하위 도메인의 문서만 포함될 수 있습니다. 예를 들어 https://a1.example.com/을 지정하면 동일한 프로세스에는 https://a2.a1.example.com/만 허용되며 https://example.com 또는 https://b.example.com은 허용되지 않습니다. Android에서는 <ph name="PRODUCT_NAME" /> 버전 77부터 기본적으로 민감한 특정 사이트가 격리됩니다. 이 정책을 설정하면 기본적인 격리 모드가 확장되어 특정 출처를 추가로 격리합니다. + + <ph name="PRODUCT_NAME" /> 77부터 와일드 카드를 사용해 격리할 출처의 범위를 지정할 수도 있습니다. 예를 들어 https://[*.]corp.example.com을 지정하면 https://corp.example.com 자체와 https://a1.corp.example.com, https://a2.a1.corp.example.com 등 https://corp.example.com에 속한 모든 출처에 전용 프로세스가 제공됩니다. + + 이 정책에 의해 격리된 출처는 동일한 사이트의 다른 출처를 스크립트할 수 없으며, 동일한 사이트 문서 두 개의 document.domain을 일치하는 값으로 수정하는 경우 스크립트할 수 있습니다. 관리자는 격리 전에 이 비정상적인 동작이 출처에서 발생하지 않는지 확인해야 합니다. + + 정책을 사용 안함으로 설정하면 모든 형태의 사이트 격리가 중지됩니다. 여기에는 민감한 사이트의 격리와 IsolateOriginsAndroid, SitePerProcessAndroid 및 기타 사이트 격리 모드의 공개 실험도 포함됩니다. 사용자는 계속해서 명령줄 플래그를 통해 IsolateOrigins를 직접 사용 설정할 수 있습니다. + + 정책을 설정하지 않으면 사용자가 이 설정을 변경할 수 있습니다. + + 참고: Android에서 너무 많은 사이트를 격리하면 특히 메모리 용량이 부족한 기기에서 성능 문제가 발생할 수 있습니다. 이 정책을 Android용 Chrome에 적용하려면 기기에 반드시 1GB 이상의 RAM이 있어야 합니다. Android가 아닌 플랫폼에 정책을 적용하려면 <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> 정책을 사용하세요.</translation> <translation id="2411629345938804022">정책을 3으로 설정하면 웹사이트에서 근처 블루투스 기기 액세스를 요청하도록 허용합니다. 정책을 2로 설정하면 근처 블루투스 기기 액세스를 거부합니다. 정책을 설정하지 않으면 사이트의 액세스 요청이 허용되지만 사용자가 이 설정을 변경할 수 있습니다.</translation> @@ -2709,6 +2727,17 @@ 정책을 '사용 안함'으로 설정하거나 설정하지 않으면 모바일 데이터에 연결되어 있을 때도 사용자가 드라이브로 파일을 전송하도록 허용합니다.</translation> <translation id="4248277954659222481">URL 패턴의 허용 목록에서 미디어 자동 재생 허용</translation> <translation id="4250680216510889253">아니요</translation> +<translation id="4260027436474745627">정책을 설정하면 쉼표로 구분된 목록의 이름이 지정된 각 출처가 전용 프로세스로 실행됩니다. 이름이 지정된 각 출처의 프로세스에는 해당 출처와 하위 도메인의 문서만 포함될 수 있습니다. 예를 들어 https://a1.example.com/을 지정하면 동일한 프로세스에는 https://a2.a1.example.com/만 허용되며 https://example.com 또는 https://b.example.com은 허용되지 않습니다. + + <ph name="PRODUCT_NAME" /> 77부터 와일드 카드를 사용해 격리할 출처의 범위를 지정할 수도 있습니다. 예를 들어 https://[*.]corp.example.com을 지정하면 https://corp.example.com 자체와 https://a1.corp.example.com, https://a2.a1.corp.example.com 등 https://corp.example.com에 속한 모든 출처에 전용 프로세스가 제공됩니다. + + <ph name="SITE_PER_PROCESS_POLICY_NAME" /> 정책에 명시된 바와 같이 모든 사이트(예: https://example.com 같은 스킴 플러스 eTLD+1)는 데스크톱 플랫폼에서 이미 기본적으로 격리되어 있습니다. 사이트보다 더 세부적인 수준으로 특정 출처를 격리하려면 <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> 정책을 사용하는 것이 유용합니다(예: https://a.example.com). + + 이 정책에 의해 격리된 출처는 동일한 사이트의 다른 출처를 스크립트할 수 없으며, 동일한 사이트 문서 두 개의 document.domain을 일치하는 값으로 수정하는 경우 스크립트할 수 있습니다. 관리자는 격리 전에 이 비정상적인 동작이 출처에서 발생하지 않는지 확인해야 합니다. + + 정책을 사용 중지하거나 설정하지 않으면 사용자가 이 설정을 변경할 수 있습니다. + + 참고: Android에서는 대신 <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> 정책을 사용하세요.</translation> <translation id="4261820385751181068">기기 로그인 화면 언어</translation> <translation id="4266547484666068234">정책을 설정하면 <ph name="URL_BLOCKLIST_POLICY_NAME" />의 예외로 목록에 추가된 URL에 액세스할 수 있습니다. 목록 항목의 형식은 정책 설명을 확인하세요. 예를 들어, <ph name="URL_BLOCKLIST_POLICY_NAME" />를 * 기호로 설정하여 모든 요청이 차단된 경우에 이 정책을 사용하여 제한된 URL 목록에 액세스하도록 허용할 수 있습니다. 또한 https://www.chromium.org/administrators/url-blocklist-filter-format에 지정된 형식을 사용하여 특정 스킴, 다른 도메인의 하위 도메인, 포트, 특정 경로에 대한 예외 목록을 열 수도 있습니다. 가장 구체적인 필터에 따라 URL 차단 또는 허용 여부가 결정됩니다. <ph name="URL_ALLOWLIST_POLICY_NAME" /> 정책은 <ph name="URL_BLOCKLIST_POLICY_NAME" />보다 우선 적용됩니다. 정책의 항목은 1,000개로 제한됩니다. @@ -3579,6 +3608,15 @@ </translation> <translation id="5435888298115339571">검색주소창과 점 3개 메뉴에서 데스크톱 공유 사용 설정</translation> <translation id="5442026853063570579">이 정책은 Android 개발자 옵션 액세스 권한도 제어합니다. 이 정책을 'DeveloperToolsDisallowed'(값 2)로 설정하는 경우 사용자는 개발자 옵션에 액세스할 수 없습니다. 이 정책을 다른 값으로 설정하거나 설정하지 않은 채로 두는 경우 사용자는 Android 설정 앱에서 빌드 번호를 7번 탭하여 개발자 옵션에 액세스할 수 있습니다.</translation> +<translation id="5443582909255996887">정책을 사용 설정하면 각 사이트가 자체 프로세스로 실행되도록 Android의 모든 사이트가 격리되며, 사용자가 선택 해제할 수 없습니다. 사이트는 스킴 플러스 eTLD+1(예: https://example.com)입니다. Android에서는 <ph name="PRODUCT_NAME" /> 버전 77부터 기본적으로 민감한 특정 사이트가 격리됩니다. 이 정책을 설정하면 기본적인 사이트 격리 모드가 확장되어 모든 사이트에 적용됩니다. + + 정책을 사용 안함으로 설정하면 모든 형태의 사이트 격리가 중지됩니다. 여기에는 민감한 사이트의 격리와 IsolateOriginsAndroid, SitePerProcessAndroid 및 기타 사이트 격리 모드의 공개 실험도 포함됩니다. 사용자는 계속해서 정책을 직접 사용 설정할 수 있습니다. + + 정책을 설정하지 않으면 사용자가 이 설정을 변경할 수 있습니다. + + 사이트보다 더 세부적인 수준으로 특정 출처를 격리하려면 <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> 정책을 사용하는 것이 유용할 수 있습니다(예: https://a.example.com). + + 참고: Android에서 모든 사이트를 격리하는 기능의 지원은 개선될 예정이지만 현재로서는 특히 보급형 기기에서 성능 문제를 일으킬 수 있습니다. 이 정책을 Android용 Chrome에 적용하려면 기기에 반드시 1GB 이상의 RAM이 있어야 합니다. 사용자에게 미치는 성능 영향을 제한하는 동시에 특정 사이트를 격리하려면 격리할 사이트의 목록에 <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> 정책을 사용하세요. Android가 아닌 플랫폼에 정책을 적용하려면 <ph name="SITE_PER_PROCESS_POLICY_NAME" /> 정책을 사용하세요.</translation> <translation id="5445596354079213552">이 정책은 기기가 자동 업데이트 만료에 도달했으며 <ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" /> 정책을 통해 설정된 <ph name="PRODUCT_OS_NAME" />의 최소 허용 버전을 충족하지 않을 때만 적용됩니다. 정책이 비어 있지 않은 문자열로 설정된 경우: @@ -6191,6 +6229,7 @@ <ph name="PRODUCT_NAME" /> 버전 92부터 이 정책이 헤드리스 모드에서도 지원됩니다. 참고: 내부 chrome://* URL을 차단하면 예기치 못한 오류가 발생할 수 있습니다.</translation> +<translation id="8626826495474944836">모든 사이트에 사이트 격리 필요</translation> <translation id="8631434304112909927">버전 <ph name="UNTIL_VERSION" /> 이하</translation> <translation id="8631437968147930597"><ph name="PRODUCT_OS_NAME" /> 잠금 화면에서 허용된 메모 앱 목록</translation> <translation id="8637566476051166626">명시적으로 허용된 네트워크 포트</translation>
diff --git a/components/policy/resources/policy_templates_nl.xtb b/components/policy/resources/policy_templates_nl.xtb index 829794a..b0b8ad03 100644 --- a/components/policy/resources/policy_templates_nl.xtb +++ b/components/policy/resources/policy_templates_nl.xtb
@@ -1091,6 +1091,13 @@ <translation id="2299220924812062390">Lijst met aangezette plug-ins specificeren</translation> <translation id="2301048990069984110">Breid de ondersteuning uit voor Chrome-apps op Windows, Mac en Linux.</translation> <translation id="2303795211377219696">Automatisch invullen aanzetten voor creditcards</translation> +<translation id="2304009805995145854">Sinds <ph name="PRODUCT_NAME" /> 67 staat site-isolatie standaard aan op alle desktopplatforms, waardoor elke site zijn eigen proces uitvoert. Een site is een schema plus eTLD+1 (bijvoorbeeld https://example.com). Dit gedrag verandert niet als je dit beleid toepast, maar het verhindert wel dat gebruikers deze functie kunnen uitzetten (bijvoorbeeld door site-isolatie uit te zetten in chrome://flags). Sinds <ph name="PRODUCT_NAME" /> 76 wordt site-isolatie niet uitgezet als je het beleid niet toepast of niet instelt, maar kunnen gebruikers deze functie zelf uitzetten. + + <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> kan ook handig zijn om specifieke herkomsten te isoleren op een kleiner niveau dan het siteniveau (bijvoorbeeld https://a.example.com). + + In <ph name="PRODUCT_OS_NAME" /> versie 76 en eerder stel je het apparaatbeleid van <ph name="DEVICE_LOGIN_SCREEN_SITE_PER_PROCESS_POLICY_NAME" /> in op dezelfde waarde. (Er kan een vertraging optreden als de waarden niet overeenkomen bij het starten van een gebruikerssessie.) + + Opmerking: Voor Android gebruik je het beleid <ph name="SITE_PER_PROCESS_ANDROID_POLICY_NAME" />.</translation> <translation id="2307496301287881990">Statussen van scherm en grafische kaart rapporteren</translation> <translation id="2309390639296060546">Standaardinstelling voor geolocatie</translation> <translation id="2331354174913096226">De URI-template van de gewenste DNS-over-HTTPS-resolver. Als je meerdere DNS-over-HTTPS-resolvers wilt opgeven, scheid je de overeenkomstige URI-templates met een spatie. @@ -1150,6 +1157,17 @@ Als je <ph name="VARIATIONS_DISABLED_OPTION_NAME" /> (waarde 2) instelt, mag geen van de varianten worden toegepast op de browser. Deze modus kan er potentieel voor zorgen dat <ph name="PRODUCT_NAME" />-ontwikkelaars essentiële beveiligingsoplossingen niet tijdig kunnen leveren en wordt dus niet aanbevolen.</translation> <translation id="2402547085566757554">Pagina Nieuw tabblad niet gebruiken als homepage</translation> +<translation id="240713331529749993">Als je dit beleid toepast, wordt elk van de benoemde herkomsten in een door komma's gescheiden lijst op Android uitgevoerd in een eigen proces. Elk proces van een benoemde herkomst mag alleen documenten bevatten van de betreffende herkomst en de subdomeinen daarvan. Als je bijvoorbeeld https://a1.example.com/ opgeeft, is https://a2.a1.example.com/ toegestaan in hetzelfde proces, maar https://example.com of https://b.example.com niet. Vanaf <ph name="PRODUCT_NAME" /> versie 77 worden bepaalde gevoelige sites standaard geïsoleerd op Android. Dit beleid vormt daarvan een uitbreiding waarbij nog meer specifieke herkomsten worden geïsoleerd. + + Sinds <ph name="PRODUCT_NAME" /> 77 kun je met een jokerteken een herkomstbereik opgeven om te isoleren. Als je bijvoorbeeld https://[*.]corp.example.com opgeeft, wordt elke herkomst onder https://corp.example.com uitgevoerd in een eigen proces, waaronder https://corp.example.com zelf, https://a1.corp.example.com en https://a2.a1.corp.example.com. + +Herkomsten die door dit beleid worden geïsoleerd, kunnen geen scripts uitvoeren van andere herkomsten binnen dezelfde site. Normaal is dit wel mogelijk als 2 documenten van dezelfde site hun waarden voor document.domain op elkaar afstemmen. Beheerders moeten bevestigen dat dit ongebruikelijke gedrag niet wordt toegepast op een herkomst voordat deze wordt geïsoleerd. + + Als je het beleid niet toepast, worden alle vormen van site-isolatie uitgezet, waaronder isolatie van gevoelige sites en praktijktests van IsolateOriginsAndroid, SitePerProcessAndroid en andere site-isolatiemodussen. Gebruikers kunnen IsolateOrigins nog altijd handmatig aanzetten via de opdrachtregelmarkering. + + Als je het beleid niet instelt, kunnen gebruikers deze instelling zelf wijzigen. + + Opmerking: Als je te veel sites isoleert in Android, kunnen er prestatieproblemen optreden, met name op apparaten met weinig geheugen. Dit beleid is alleen van toepassing op Chrome op Android-apparaten met meer dan 1 GB RAM-geheugen. Gebruik <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> om het beleid toe te passen op andere platforms dan Android.</translation> <translation id="2411629345938804022">Als je het beleid instelt op 3, kunnen websites vragen om toegang tot bluetooth-apparaten in de buurt. Als je het beleid instelt op 2, wordt de toegang tot bluetooth-apparaten in de buurt geblokkeerd. Als je het beleid niet instelt, kunnen sites om toegang vragen maar kunnen gebruikers deze instelling wijzigen.</translation> @@ -2672,6 +2690,17 @@ Als je het beleid niet toepast of niet instelt, kunnen gebruikers bestanden overzetten naar Drive via een mobiele verbinding.</translation> <translation id="4248277954659222481">Automatisch afspelen van media toestaan op een toelatingslijst met URL-patronen</translation> <translation id="4250680216510889253">Nee</translation> +<translation id="4260027436474745627">Als je dit beleid toepast, wordt elk van de benoemde herkomsten in een door komma's gescheiden lijst uitgevoerd in een eigen proces. Elk proces van een benoemde herkomst mag alleen documenten bevatten van de betreffende herkomst en de subdomeinen daarvan. Als je bijvoorbeeld https://a1.example.com/ opgeeft, valt https://a2.a1.example.com/ onder hetzelfde proces, maar https://example.com of https://b.example.com niet. + +Sinds <ph name="PRODUCT_NAME" /> 77 kun je met een jokerteken een herkomstbereik opgeven om te isoleren. Als je bijvoorbeeld https://[*.]corp.example.com opgeeft, wordt elke herkomst onder https://corp.example.com uitgevoerd in een eigen proces, waaronder https://corp.example.com zelf, https://a1.corp.example.com en https://a2.a1.corp.example.com. + +Zoals wordt vermeld in ons beleid <ph name="SITE_PER_PROCESS_POLICY_NAME" />, zijn op desktopplatforms alle sites (dus het schema plus eTLD+1, zoals https://example.com) standaard geïsoleerd. Het beleid <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> is handig om specifieke herkomsten op een lager detailniveau te isoleren (bijvoorbeeld https://a.example.com). + + Herkomsten die door dit beleid worden geïsoleerd, kunnen geen scripts uitvoeren van andere herkomsten binnen dezelfde site. Normaal is dit wel mogelijk als 2 documenten van dezelfde site hun waarden voor document.domain op elkaar afstemmen. Beheerders moeten bevestigen dat dit ongebruikelijke gedrag niet wordt toegepast op een herkomst voordat deze wordt geïsoleerd. + + Als je dit beleid niet toepast of niet instelt, kunnen gebruikers deze instelling wijzigen. + + Opmerking: Voor Android gebruik je het beleid <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" />.</translation> <translation id="4261820385751181068">Taal voor inlogscherm van apparaat</translation> <translation id="4266547484666068234">Als je dit beleid instelt, wordt toegang geboden tot de vermelde URL's, als uitzonderingen op <ph name="URL_BLOCKLIST_POLICY_NAME" />. Bekijk de beschrijving van dit beleid voor de indeling van items in deze lijst. Als je <ph name="URL_BLOCKLIST_POLICY_NAME" /> bijvoorbeeld instelt op *, worden alle verzoeken geblokkeerd en kun je dit beleid gebruiken om toegang tot een beperkte lijst met URL's toe te staan. Je kunt dit beleid gebruiken om uitzonderingen voor bepaalde schema's, subdomeinen van andere domeinen, poorten of specifieke paden op te geven met de indeling die wordt gespecificeerd op (https://www.chromium.org/administrators/url-blocklist-filter-format ). Het meest specifieke filter bepaalt of een URL geblokkeerd of toegestaan wordt. Het beleid <ph name="URL_ALLOWLIST_POLICY_NAME" /> krijgt voorrang op <ph name="URL_BLOCKLIST_POLICY_NAME" />. Dit beleid is beperkt tot 1000 items. @@ -3541,6 +3570,15 @@ Als je dit beleid niet toepast, wordt de functie verplicht uitgezet.</translation> <translation id="5435888298115339571">Delen van bureaublad aanzetten in de omnibox en het menu met 3 stippen</translation> <translation id="5442026853063570579">Met dit beleid wordt ook de toegang tot de ontwikkelaarsopties van Android beheerd. Als je dit beleid instelt op 'DeveloperToolsDisallowed' (waarde 2), hebben gebruikers geen toegang tot ontwikkelaarsopties. Als je dit beleid instelt op een andere waarde of niet instelt, hebben gebruikers toegang tot ontwikkelaarsopties door zeven keer op het buildnummer te tikken in de app Instellingen van Android.</translation> +<translation id="5443582909255996887">Als je dit beleid toepast, worden alle sites op Android geïsoleerd, zodat elke site zijn eigen proces uitvoert, en kunnen gebruikers kunnen deze functie niet uitzetten. Een site is een schema plus eTLD+1 (bijvoorbeeld https://example.com). Android isoleert bepaalde gevoelige sites standaard vanaf versie 77 van <ph name="PRODUCT_NAME" />. Dit beleid breidt die standaard site-isolatiemodus uit naar alle sites. + + Als je het beleid niet toepast, worden alle vormen van site-isolatie uitgezet, waaronder isolatie van gevoelige sites en praktijktests van IsolateOriginsAndroid, SitePerProcessAndroid en andere site-isolatiemodussen. Gebruikers kunnen het beleid nog steeds handmatig toepassen. + + Als je het beleid niet instelt, kunnen gebruikers deze instelling wijzigen. + + <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> kan ook handig zijn om specifieke herkomsten te isoleren op een kleiner niveau dan het siteniveau (bijvoorbeeld https://a.example.com). + + Opmerking: De ondersteuning voor isolatie van elke site in Android wordt verbeterd, maar er kunnen momenteel prestatieproblemen optreden, met name op basisapparaten. Dit beleid is alleen van toepassing op Chrome op Android-apparaten met meer dan 1 GB RAM-geheugen. Als je specifieke sites wilt isoleren terwijl dit zo min mogelijk impact heeft op de prestaties voor gebruikers, gebruik je <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> met een lijst van de sites die je wilt isoleren. Gebruik <ph name="SITE_PER_PROCESS_POLICY_NAME" /> om het beleid toe te passen op andere platforms dan Android.</translation> <translation id="5445596354079213552">Dit beleid is alleen van kracht als het apparaat de vervaldatum voor automatische updates heeft bereikt en niet voldoet aan de toegestane minimum versie van <ph name="PRODUCT_OS_NAME" /> die is ingesteld via het beleid <ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" />. Als dit beleid is ingesteld op een niet-lege tekenreeks: @@ -6098,6 +6136,7 @@ Vanaf <ph name="PRODUCT_NAME" /> versie 92 wordt dit beleid ook ondersteund in de stand zonder interface. Opmerking: Het blokkeren van interne chrome://* URL's kan tot onverwachte fouten leiden.</translation> +<translation id="8626826495474944836">Site-isolatie verplichten voor elke site</translation> <translation id="8631434304112909927">tot versie <ph name="UNTIL_VERSION" /></translation> <translation id="8631437968147930597">De lijst met notitie-apps die zijn toegestaan op het <ph name="PRODUCT_OS_NAME" />-vergrendelscherm</translation> <translation id="8637566476051166626">Expliciet toegestane netwerkpoorten</translation>
diff --git a/components/policy/resources/policy_templates_th.xtb b/components/policy/resources/policy_templates_th.xtb index 1a25e8f..fc33b10 100644 --- a/components/policy/resources/policy_templates_th.xtb +++ b/components/policy/resources/policy_templates_th.xtb
@@ -1093,6 +1093,13 @@ <translation id="2299220924812062390">ระบุรายการปลั๊กอินที่เปิดใช้งาน</translation> <translation id="2301048990069984110">ขยายการรองรับแอป Chrome ใน Windows, Mac และ Linux</translation> <translation id="2303795211377219696">เปิดใช้ "ป้อนข้อความอัตโนมัติ" สำหรับบัตรเครดิต</translation> +<translation id="2304009805995145854">ตั้งแต่ <ph name="PRODUCT_NAME" /> เวอร์ชัน 67 การแยกเว็บไซต์จะเปิดใช้ไว้โดยค่าเริ่มต้นในแพลตฟอร์มเดสก์ท็อปทั้งหมด ซึ่งทำให้ทุกเว็บไซต์ทำงานด้วยกระบวนการของตนเองได้ เว็บไซต์อยู่ในรูปแบบบวก eTLD+1 (เช่น https://example.com) การตั้งค่านโยบายนี้เป็น "เปิดใช้" ไม่ได้เปลี่ยนลักษณะการทำงานดังกล่าว เพียงแต่ป้องกันไม่ให้ผู้ใช้เลือกไม่ใช้ (เช่น การใช้ Disable site isolation (ปิดใช้การแยกเว็บไซต์) ใน chrome://flags) ตั้งแต่ <ph name="PRODUCT_NAME" /> เวอร์ชัน 76 การตั้งค่านโยบายเป็น "ปิดใช้" หรือไม่ได้ตั้งค่าจะไม่ปิดการแยกเว็บไซต์ แต่จะอนุญาตให้ผู้ใช้สามารถเลือกไม่ใช้ได้ + + <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> อาจเป็นประโยชน์ในการแยกต้นทางเฉพาะบางแห่งในระดับที่ละเอียดกว่าเว็บไซต์ด้วย (เช่น https://a.example.com) + + ใน <ph name="PRODUCT_OS_NAME" /> เวอร์ชัน 76 และเวอร์ชันก่อนหน้า ให้ตั้งค่านโยบายด้านอุปกรณ์ <ph name="DEVICE_LOGIN_SCREEN_SITE_PER_PROCESS_POLICY_NAME" /> ด้วยค่าเดียวกันนี้ (หากค่าไม่ตรงกัน อาจเกิดความล่าช้าเมื่อเข้าสู่เซสชันของผู้ใช้) + + หมายเหตุ: สำหรับ Android ให้ใช้นโยบาย <ph name="SITE_PER_PROCESS_ANDROID_POLICY_NAME" /> แทน</translation> <translation id="2307496301287881990">รายงานสถานะการแสดงผลและกราฟิก</translation> <translation id="2309390639296060546">การตั้งค่าตำแหน่งทางภูมิศาสตร์เริ่มต้น</translation> <translation id="2331354174913096226">เทมเพลต URI ของรีโซลเวอร์ DNS-over-HTTPS ที่ต้องการ วิธีระบุรีโซลเวอร์ DNS-over-HTTPS หลายรายการคือเว้นวรรคระหว่างเทมเพลต URI ที่เกี่ยวข้อง @@ -1153,6 +1160,17 @@ การตั้งค่า <ph name="VARIATIONS_DISABLED_OPTION_NAME" /> (ค่า 2) จะไม่อนุญาตให้ใช้รูปแบบใดก็ตามกับเบราว์เซอร์ โปรดทราบว่าโหมดนี้อาจขัดขวางไม่ให้นักพัฒนาแอปของ <ph name="PRODUCT_NAME" /> ทำการแก้ไขด้านความปลอดภัยที่สำคัญมากได้อย่างทันท่วงที และด้วยเหตุนี้จึงไม่แนะนำให้ใช้โหมดนี้</translation> <translation id="2402547085566757554">ไม่ใช้หน้าแท็บใหม่เป็นหน้าแรก</translation> +<translation id="240713331529749993">การตั้งค่านโยบายหมายความว่าต้นทางแต่ละแห่งที่มีชื่อในรายการที่คั่นด้วยคอมมาจะทำงานในกระบวนการเฉพาะบน Android กระบวนการของต้นทางแต่ละแห่งที่มีชื่อจะได้รับอนุญาตเฉพาะในเอกสารบางรายการจากต้นทางนั้นและโดเมนย่อย ตัวอย่างเช่น การระบุ https://a1.example.com/ จะอนุญาต https://a2.a1.example.com/ ในกระบวนการเดียวกัน แต่ไม่อนุญาต https://example.com หรือ https://b.example.com โปรดทราบว่า Android จะแยกเว็บไซต์ที่มีความละเอียดอ่อนบางเว็บไซต์โดยค่าเริ่มต้นใน <ph name="PRODUCT_NAME" /> เวอร์ชัน 77 เป็นต้นไป และนโยบายนี้จะขยายการทำงานของโหมดดังกล่าวให้แยกต้นทางบางรายการเพิ่มเติม + + ตั้งแต่ <ph name="PRODUCT_NAME" /> เวอร์ชัน 77 คุณจะระบุช่วงต้นทางเพื่อแยกโดยใช้ไวลด์การ์ดได้ด้วย ตัวอย่างเช่น การระบุ https://[*.]corp.example.com จะทำให้ทุกต้นทางภายใต้ https://corp.example.com มีกระบวนการเฉพาะของตนเอง ซึ่งรวมถึง https://corp.example.com, https://a1.corp.example.com และ https://a2.a1.corp.example.com + + โปรดทราบว่าต้นทางที่แยกโดยนโยบายนี้จะสคริปต์ต้นทางอื่นๆ ในเว็บไซต์เดียวกันไม่ได้ แต่จะเป็นไปได้หากเอกสาร 2 รายการของเว็บไซต์เดียวกันแก้ไขค่า document.domain ให้ตรงกัน ผู้ดูแลระบบควรตรวจสอบว่าไม่มีการใช้ลักษณะการทำงานไม่ปกตินี้ในต้นทางก่อนที่จะแยก + + การตั้งค่านโยบายเป็น "ปิดใช้" จะปิดการแยกเว็บไซต์ทุกรูปแบบ เช่น การแยกเว็บไซต์ที่มีความละเอียดอ่อน รวมถึงการทดลองใช้งานจริงของ IsolateOriginsAndroid และ SitePerProcessAndroid ตลอดจนโหมดการแยกเว็บไซต์อื่นๆ ผู้ใช้ยังคงเปิด IsolateOrigins ด้วยตนเองได้ผ่านแฟล็กบรรทัดคำสั่ง + + การไม่ตั้งค่านโยบายจะทำให้ผู้ใช้เปลี่ยนการตั้งค่านี้ได้ + + หมายเหตุ: การแยกเว็บไซต์จำนวนมากเกินไปใน Android อาจก่อให้เกิดปัญหาด้านประสิทธิภาพ โดยเฉพาะกับอุปกรณ์ที่มีหน่วยความจำน้อย นโยบายนี้มีผลเฉพาะกับ Chrome ใน Android ที่ทำงานในอุปกรณ์ที่มี RAM มากกว่า 1 GB เท่านั้น หากต้องการใช้นโยบายกับแพลตฟอร์มที่ไม่ใช่ Android ให้ใช้ <ph name="ISOLATE_ORIGINS_POLICY_NAME" /></translation> <translation id="2411629345938804022">การตั้งค่านโยบายเป็น 3 จะให้เว็บไซต์ขอสิทธิ์เข้าถึงอุปกรณ์บลูทูธใกล้เคียงได้ การตั้งค่านโยบายเป็น 2 จะปฏิเสธสิทธิ์เข้าถึงอุปกรณ์บลูทูธใกล้เคียง การไม่ตั้งค่านโยบายจะให้เว็บไซต์ขอสิทธิ์เข้าถึงได้ แต่ผู้ใช้เปลี่ยนการตั้งค่านี้ได้</translation> @@ -2671,6 +2689,15 @@ การตั้งค่านโยบายเป็น "ปิดใช้" หรือไม่ได้ตั้งค่าจะทำให้ผู้ใช้โอนไฟล์ไปยัง Google ไดรฟ์ขณะเชื่อมต่อเครือข่ายมือถือได้</translation> <translation id="4248277954659222481">อนุญาตการเล่นสื่ออัตโนมัติในรายการรูปแบบ URL ที่อนุญาต</translation> <translation id="4250680216510889253">ไม่มี</translation> +<translation id="4260027436474745627">การตั้งค่านโยบายหมายความว่าต้นทางแต่ละแห่งที่มีชื่อในรายการที่คั่นด้วยคอมมาจะทำงานในกระบวนการเฉพาะ กระบวนการของต้นทางแต่ละแห่งที่มีชื่อจะได้รับอนุญาตเฉพาะในเอกสารบางรายการจากต้นทางนั้นและโดเมนย่อย ตัวอย่างเช่น การระบุ https://a1.example.com/ จะอนุญาต https://a2.a1.example.com/ ในกระบวนการเดียวกัน แต่ไม่อนุญาต https://example.com หรือ https://b.example.com ตั้งแต่ <ph name="PRODUCT_NAME" /> เวอร์ชัน 77 คุณจะระบุช่วงต้นทางเพื่อแยกโดยใช้ไวลด์การ์ดได้ด้วย ตัวอย่างเช่น การระบุ https://[*.]corp.example.com จะทำให้ทุกต้นทางภายใต้ https://corp.example.com มีกระบวนการเฉพาะของตนเอง ซึ่งรวมถึง https://corp.example.com, https://a1.corp.example.com และ https://a2.a1.corp.example.com + + โปรดทราบว่าเว็บไซต์ทั้งหมด (เช่น รูปแบบบวก eTLD+1 อย่าง https://example.com) จะแยกไว้อยู่แล้วโดยค่าเริ่มต้นบนแพลตฟอร์มเดสก์ท็อปตามที่ได้ระบุในนโยบาย <ph name="SITE_PER_PROCESS_POLICY_NAME" /> นโยบาย <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> นี้เป็นประโยชน์ในการแยกต้นทางเฉพาะบางแห่งในระดับที่ละเอียดกว่า (เช่น https://a.example.com) + + นอกจากนี้ โปรดทราบว่าต้นทางที่แยกโดยนโยบายนี้จะสคริปต์ต้นทางอื่นๆ ในเว็บไซต์เดียวกันไม่ได้ แต่จะเป็นไปได้หากเอกสาร 2 รายการของเว็บไซต์เดียวกันแก้ไขค่า document.domain ให้ตรงกัน ผู้ดูแลระบบควรตรวจสอบว่าไม่มีการใช้ลักษณะการทำงานไม่ปกตินี้ในต้นทางก่อนที่จะแยก + + การตั้งค่านโยบายเป็น "ปิด" หรือไม่ตั้งค่าจะทำให้ผู้ใช้เปลี่ยนการตั้งค่านี้ได้ + + หมายเหตุ: สำหรับ Android ให้ใช้นโยบาย <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> แทน</translation> <translation id="4261820385751181068">ภาษาในหน้าจอการลงชื่อเข้าใช้อุปกรณ์</translation> <translation id="4266547484666068234">การตั้งค่านโยบายจะให้สิทธิ์เข้าถึง URL ที่ระบุไว้ โดยเป็นข้อยกเว้นของ <ph name="URL_BLOCKLIST_POLICY_NAME" /> ดูรูปแบบของรายการในลิสต์นี้ได้จากคำอธิบายของนโยบายดังกล่าว ตัวอย่างเช่น การตั้งค่า <ph name="URL_BLOCKLIST_POLICY_NAME" /> เป็น * จะบล็อกคำขอทั้งหมด และคุณจะใช้นโยบายนี้เพื่ออนุญาตการเข้าถึงรายการ URL ที่จำกัดไว้ได้ ตลอดจนใช้ในการเปิดข้อยกเว้นให้แก่บางรูปแบบ โดเมนย่อยของโดเมนอื่นๆ พอร์ต หรือเส้นทางที่เฉพาะเจาะจง โดยใช้รูปแบบที่ระบุไว้ที่ (https://www.chromium.org/administrators/url-blocklist-filter-format) ตัวกรองที่เฉพาะเจาะจงมากที่สุดจะเป็นตัวกำหนดว่า URL หนึ่งๆ ถูกบล็อกหรือได้รับอนุญาต นโยบาย <ph name="URL_ALLOWLIST_POLICY_NAME" /> จะมีความสำคัญเหนือ <ph name="URL_BLOCKLIST_POLICY_NAME" /> นโยบายนี้ระบุรายการได้ไม่เกิน 1,000 รายการ @@ -3539,6 +3566,15 @@ </translation> <translation id="5435888298115339571">เปิดใช้การแชร์เดสก์ท็อปในแถบอเนกประสงค์และเมนู 3 จุด</translation> <translation id="5442026853063570579">นโยบายนี้ยังควบคุมการเข้าถึงตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ของ Android เช่นกัน หากคุณตั้งค่านโยบายนี้เป็น "DeveloperToolsDisallowed" (ค่า 2) ผู้ใช้จะเข้าถึงตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ไม่ได้ หากตั้งค่านโยบายเป็นค่าอื่นหรือไม่ได้ตั้งค่า ผู้ใช้จะเข้าถึงตัวเลือกสำหรับนักพัฒนาซอฟต์แวร์ได้ด้วยการแตะหมายเลขบิลด์ 7 ครั้งในแอปการตั้งค่าของ Android</translation> +<translation id="5443582909255996887">การตั้งค่านโยบายเป็น "เปิดใช้" จะแยกเว็บไซต์ทั้งหมดใน Android ซึ่งจะทำให้แต่ละเว็บไซต์ทำงานด้วยกระบวนการของตนเอง และจะป้องกันไม่ให้ผู้ใช้เลือกไม่ใช้ เว็บไซต์อยู่ในรูปแบบบวก eTLD+1 (เช่น https://example.com) โปรดทราบว่า Android จะแยกเว็บไซต์ที่มีความละเอียดอ่อนบางเว็บไซต์โดยค่าเริ่มต้นใน <ph name="PRODUCT_NAME" /> เวอร์ชัน 77 เป็นต้นไป และนโยบายนี้จะขยายการทำงานของโหมดการแยกเว็บไซต์ตามค่าเริ่มต้นให้มีผลกับเว็บไซต์ทั้งหมด + + การตั้งค่านโยบายเป็น "ปิดใช้" จะปิดการแยกเว็บไซต์ทุกรูปแบบ เช่น การแยกเว็บไซต์ที่มีความละเอียดอ่อน รวมถึงการทดลองใช้งานจริงของ IsolateOriginsAndroid และ SitePerProcessAndroid ตลอดจนโหมดการแยกเว็บไซต์อื่นๆ ผู้ใช้ยังคงเปิดใช้นโยบายด้วยตนเองได้ + + การไม่ตั้งค่านโยบายจะทำให้ผู้ใช้เปลี่ยนการตั้งค่านี้ได้ + + <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> อาจเป็นประโยชน์ในการแยกต้นทางเฉพาะบางแห่งในระดับที่ละเอียดกว่าเว็บไซต์ด้วย (เช่น https://a.example.com) + + หมายเหตุ: เราจะปรับปรุงการรองรับการแยกทุกเว็บไซต์ใน Android แต่ปัจจุบันฟีเจอร์นี้อาจก่อให้เกิดปัญหาด้านประสิทธิภาพ โดยเฉพาะกับอุปกรณ์ระดับโลว์เอนด์ นโยบายนี้มีผลเฉพาะกับ Chrome ใน Android ที่ทำงานในอุปกรณ์ที่มี RAM มากกว่า 1 GB เท่านั้น หากต้องการแยกบางเว็บไซต์ในขณะที่ป้องกันไม่ให้ผู้ใช้ได้รับผลกระทบด้านประสิทธิภาพมากนัก ให้ใช้ <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> กับรายชื่อเว็บไซต์ที่ต้องการแยก หากต้องการใช้นโยบายกับแพลตฟอร์มที่ไม่ใช่ Android ให้ใช้ <ph name="SITE_PER_PROCESS_POLICY_NAME" /></translation> <translation id="5445596354079213552">นโยบายนี้มีผลเฉพาะเมื่อการอัปเดตอัตโนมัติของอุปกรณ์ถึงวันหมดอายุแล้วและอุปกรณ์มีเวอร์ชันไม่ตรงตามเวอร์ชันขั้นต่ำที่อนุญาตของ <ph name="PRODUCT_OS_NAME" /> ซึ่งตั้งค่าผ่านนโยบาย <ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" /> เมื่อตั้งค่านโยบายนี้เป็นสตริงที่ไม่ว่างเปล่า @@ -6100,6 +6136,7 @@ มีการรองรับนโยบายนี้ในโหมดไม่มีส่วนหัวด้วยใน <ph name="PRODUCT_NAME" /> เวอร์ชัน 92 เป็นต้นไป หมายเหตุ: การบล็อก chrome://* ซึ่งเป็น URL ภายในอาจทำให้เกิดข้อผิดพลาดที่ไม่คาดคิด</translation> +<translation id="8626826495474944836">ต้องมีการแยกเว็บไซต์สำหรับทุกเว็บไซต์</translation> <translation id="8631434304112909927">จนถึงรุ่น <ph name="UNTIL_VERSION" /></translation> <translation id="8631437968147930597">รายการแอปสำหรับจดโน้ตที่อนุญาตในหน้าจอล็อกของ <ph name="PRODUCT_OS_NAME" /></translation> <translation id="8637566476051166626">พอร์ตเครือข่ายที่ได้รับอนุญาตอย่างชัดแจ้ง</translation>
diff --git a/components/policy/resources/policy_templates_tr.xtb b/components/policy/resources/policy_templates_tr.xtb index bbe11eb..98db1133 100644 --- a/components/policy/resources/policy_templates_tr.xtb +++ b/components/policy/resources/policy_templates_tr.xtb
@@ -3962,7 +3962,7 @@ <translation id="5921713479449475707">HTTP aracılığıyla otomatik güncelleme indirmeye izin ver</translation> <translation id="5928633129285224981"><ph name="PRODUCT_NAME" /> üzerinde PDF yazdırılırken Resim olarak yazdır'ın varsayılan olarak seçilip seçilmeyeceğini kontrol eder. - Bu politika Etkin değerine ayarlandığında <ph name="PRODUCT_NAME" />, PDF yazdırılırken Yazdırma Önizleme'de Resim olarak yazdır'ı varsayılan olarak seçer. + Bu politika Etkin olarak belirlendiğinde, <ph name="PRODUCT_NAME" /> varsayılan olarak PDF yazdırırken Yazdırma Önizleme'de Resim olarak yazdır seçeneğini ayarlar. Bu politika Devre Dışı değerine ayarlanırsa veya ayarlanmadan bırakılırsa <ph name="PRODUCT_NAME" /> üzerinde Resim olarak yazdır seçeneği baştan seçilmemiş olur. Seçeneğin kullanılabildiği durumlarda kullanıcı, ayrı ayrı her bir PDF'nin yazdırma işi için bu seçimi yapabilir.
diff --git a/components/policy/resources/policy_templates_zh-TW.xtb b/components/policy/resources/policy_templates_zh-TW.xtb index 7ef5b03..788c4e56 100644 --- a/components/policy/resources/policy_templates_zh-TW.xtb +++ b/components/policy/resources/policy_templates_zh-TW.xtb
@@ -1091,6 +1091,13 @@ <translation id="2299220924812062390">指定停用的外掛程式清單</translation> <translation id="2301048990069984110">延長在 Windows、Mac 和 Linux 上支援 Chrome 應用程式的時間。</translation> <translation id="2303795211377219696">啟用信用卡的自動填入功能</translation> +<translation id="2304009805995145854">自 <ph name="PRODUCT_NAME" /> 第 67 版起,系統預設已在所有電腦平台上啟用網站隔離功能,因此每個網站都會以獨立程序執行。網站是指加上 eTLD+1 的配置 (例如 https://example.com)。將這項政策設為 Enabled 並不會改變這項行為,只會禁止使用者停用這項設定 (例如在 chrome://flags 中使用「停用網站隔離」功能)。自 <ph name="PRODUCT_NAME" /> 第 76 版起,如果將這項政策設為 Disabled 或不設定,系統並不會關閉網站隔離功能,只會開放使用者停用這項設定。 + + <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> 也能用來隔離低於網站層級的來源 (例如 https://a.example.com)。 + + 在 <ph name="PRODUCT_OS_NAME" /> 76 以下版本中,請將 <ph name="DEVICE_LOGIN_SCREEN_SITE_PER_PROCESS_POLICY_NAME" /> 裝置政策設為相同的值 (如果兩者的值不相符,就可能導致進入使用者工作階段的過程出現延遲)。 + + 注意:對於 Android 裝置,請改用 <ph name="SITE_PER_PROCESS_ANDROID_POLICY_NAME" /> 政策。</translation> <translation id="2307496301287881990">回報顯示狀態和圖形狀態</translation> <translation id="2309390639296060546">預設地理位置設定</translation> <translation id="2331354174913096226">所需 DNS-over-HTTPS 解析器的 URI 範本。如要指定多個 DNS-over-HTTPS 解析器,請以半形空格分隔相應的 URI 範本。 @@ -1152,6 +1159,17 @@ 如果設為 <ph name="VARIATIONS_DISABLED_OPTION_NAME" /> (值為 2),使用者無法將任何變化版本套用到瀏覽器。請注意,這個模式可能會讓 <ph name="PRODUCT_NAME" /> 開發人員無法及時提供重大安全性修正項目,因此不建議使用。</translation> <translation id="2402547085566757554">不要將新分頁設為首頁</translation> +<translation id="240713331529749993">如果設定這項政策,那麼在 Android 裝置上,逗號分隔清單中指定的每個來源就會在獨立程序中執行。每個指定來源的程序都只能容納來自相同來源及其子網域的文件。舉例來說,如果指定 https://a1.example.com/,https://a2.a1.example.com/ 就能使用同一個程序,但是 https://example.com 和 https://b.example.com 並不能使用同一個程序。請注意,自 <ph name="PRODUCT_NAME" /> 第 77 版起,Android 平台預設會隔離某些敏感網站,而這項政策會將這個模式擴大應用至隔離其他特定來源。 + + 自 <ph name="PRODUCT_NAME" /> 第 77 版起,你也可以使用萬用字元來指定要隔離的來源範圍。舉例來說,如果指定 https://[*.]corp.example.com,則 https://corp.example.com 底下的每個來源都會在獨立程序中執行,其中包括 https://corp.example.com 本身、https://a1.corp.example.com 和 https://a2.a1.corp.example.com。 + + 請注意,這項政策所隔離的來源將無法針對同一網站中的其他來源編寫指令碼;不過,如果同一個網站上的兩份文件將 document.domain 改成一致的值,就可能允許跨來源編寫指令碼。如果系統管理員需要隔離某個來源,應先確認該來源沒有這種不常見的行為。 + + 如果將這項政策設為 Disabled,則會關閉所有形式的網站隔離功能,包括隔離敏感網站、IsolateOriginsAndroid 和 SitePerProcessAndroid 的實測,以及其他網站隔離模式。使用者仍可透過指令列旗標來手動啟用 IsolateOrigins。 + + 如果未設定這項政策,代表使用者可以自行變更這項設定。 + + 注意:在 Android 裝置上隔離太多網站可能會導致效能問題 (尤其是在記憶體不足的裝置上)。這項政策僅適用於在 RAM 超過 1 GB 的裝置上執行的 Android 版 Chrome。如要在 Android 以外平台上應用這項政策,請使用 <ph name="ISOLATE_ORIGINS_POLICY_NAME" />。</translation> <translation id="2411629345938804022">如果將這項政策設為 3,網站即可要求存取附近的藍牙裝置。如果將這項政策設為 2,網站將無法存取附近的藍牙裝置。 如果未設定這項政策,網站可要求存取附近的藍牙裝置,但使用者可以變更這項設定。</translation> @@ -2666,6 +2684,17 @@ 如果將這項政策設為停用或不設定,使用者可在使用行動網路連線時,將檔案傳輸至雲端硬碟。</translation> <translation id="4248277954659222481">允許符合網址模式許可清單的網頁自動播放媒體</translation> <translation id="4250680216510889253">否</translation> +<translation id="4260027436474745627">如果設定這項政策,逗號分隔清單中指定的每個來源就會在獨立程序中執行。每個指定來源的程序都只能容納來自相同來源及其子網域的文件。舉例來說,如果指定 https://a1.example.com/,https://a2.a1.example.com/ 就能使用同一個程序,但是 https://example.com 和 https://b.example.com 並不能使用同一個程序。 + + 自 <ph name="PRODUCT_NAME" /> 第 77 版起,你也可以使用萬用字元來指定要隔離的來源範圍。舉例來說,如果指定 https://[*.]corp.example.com,則 https://corp.example.com 底下的每個來源都會在獨立程序中執行,其中包括 https://corp.example.com 本身、https://a1.corp.example.com 和 https://a2.a1.corp.example.com。 + + 請注意,如 <ph name="SITE_PER_PROCESS_POLICY_NAME" /> 政策所述,系統預設已在電腦平台上隔離所有網站 (即加上 eTLD+1 的配置,例如 https://example.com)。<ph name="ISOLATE_ORIGINS_POLICY_NAME" /> 政策也能用來隔離低於網站層級的來源 (例如 https://a.example.com)。 + + 另請注意,這項政策所隔離的來源將無法針對同一網站中的其他來源編寫指令碼;不過,如果同一個網站上的兩份文件將 document.domain 改成一致的值,就可能允許跨來源編寫指令碼。如果系統管理員需要隔離某個來源,應先確認該來源沒有這種不常見的行為。 + + 如果將這項政策設為停用或不設定,就代表使用者可以變更這項設定。 + + 注意:對於 Android 裝置,請改用 <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> 政策。</translation> <translation id="4261820385751181068">裝置登入畫面語言代碼</translation> <translation id="4266547484666068234">如果設定這項政策,使用者可以存取許可清單中的網址,這些網址是 <ph name="URL_BLOCKLIST_POLICY_NAME" /> 的例外項目。請參閱該項政策的說明,瞭解這份清單所含項目的格式。舉例來說,如果將 <ph name="URL_BLOCKLIST_POLICY_NAME" /> 設為「*」,系統會封鎖所有要求。你可以透過這項政策允許使用者存取一些特定的網址。請使用 https://www.chromium.org/administrators/url-blocklist-filter-format 網頁中所指定的格式,透過這項政策將特定的網路通訊協定、其他網域的子網域、通訊埠或特定路徑設為例外。系統需要判定是否封鎖某一個網址時,會以最精確的篩選條件為依據。<ph name="URL_ALLOWLIST_POLICY_NAME" /> 政策的優先順序高於 <ph name="URL_BLOCKLIST_POLICY_NAME" />。這項政策最多只能輸入 1,000 個項目。 @@ -3529,6 +3558,15 @@ </translation> <translation id="5435888298115339571">啟用網址列和三點選單中的桌面分享功能</translation> <translation id="5442026853063570579">這項政策也可以控制 Android 開發人員選項的存取權。如果將這項政策設為「DeveloperToolsDisallowed」(值 2),使用者將無法存取開發人員選項。如果將這項政策設為其他值或不予設定,使用者只要在 Android 設定應用程式中輕觸版本號碼七次,即可存取開發人員選項。</translation> +<translation id="5443582909255996887">如果將這項政策設為 Enabled,系統就會在 Android 裝置上隔離所有網站,讓每個網站以獨立程序執行,並禁止使用者停用這項設定。網站是指加上 eTLD+1 的配置 (例如 https://example.com)。請注意,自 <ph name="PRODUCT_NAME" /> 第 77 版起,Android 會預設隔離某些敏感網站,而這項政策會將這個預設的網站隔離模式應用於所有網站。 + + 如果將這項政策設為 Disabled,則會關閉所有形式的網站隔離功能,包括隔離敏感網站、IsolateOriginsAndroid 和 SitePerProcessAndroid 的實測,以及其他網站隔離模式。不過,使用者仍然可以手動啟用這項政策。 + + 如果未設定這項政策,代表使用者可以變更這項設定。 + + <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> 也能用來隔離低於網站層級的來源 (例如 https://a.example.com)。 + + 注意:目前 Android 裝置上的網站隔離支援功能可能會導致效能問題 (尤其是在低階裝置上),但日後將會改善。這項政策僅適用於在 RAM 超過 1 GB 的裝置上執行的 Android 版 Chrome。如果想隔離特定網站,同時減少對使用者效能的影響,請使用 <ph name="ISOLATE_ORIGINS_ANDROID_POLICY_NAME" /> 來指定要隔離的一系列網站。如要在 Android 以外平台上應用這項政策,請使用 <ph name="SITE_PER_PROCESS_POLICY_NAME" />。</translation> <translation id="5445596354079213552">只有在裝置的自動更新期限已結束,且裝置不符合透過 <ph name="DEVICE_MINIMUM_VERSION_POLICY_NAME" /> 政策設定的 <ph name="PRODUCT_OS_NAME" />最低版本限制時,這項政策才會生效。 將這項政策設為非空白的字串時: @@ -6062,6 +6100,7 @@ 自 <ph name="PRODUCT_NAME" /> 92 版起,系統在無頭模式下也會支援這項政策。 注意:封鎖內部的 chrome://* 網址可能會導致非預期的錯誤。</translation> +<translation id="8626826495474944836">要求針對所有網站啟用網站隔離功能</translation> <translation id="8631434304112909927">到第 <ph name="UNTIL_VERSION" /> 版為止</translation> <translation id="8631437968147930597"><ph name="PRODUCT_OS_NAME" />螢幕鎖定畫面上允許的筆記應用程式清單</translation> <translation id="8637566476051166626">明確允許的網路通訊埠</translation>
diff --git a/components/services/app_service/DEPS b/components/services/app_service/DEPS index 82362fe..d2af379 100644 --- a/components/services/app_service/DEPS +++ b/components/services/app_service/DEPS
@@ -11,9 +11,6 @@ "icon_cache\.h": [ "+ui/gfx/image/image_skia.h", ], - "intent_util\.cc" : [ - "+third_party/blink/public/common/mime_util/mime_util.h", - ], "instance\.h": [ "+ui/aura/window.h", "+ui/gfx/image/image_skia_rep.h",
diff --git a/components/services/app_service/public/cpp/BUILD.gn b/components/services/app_service/public/cpp/BUILD.gn index b3fdf22..9626a81 100644 --- a/components/services/app_service/public/cpp/BUILD.gn +++ b/components/services/app_service/public/cpp/BUILD.gn
@@ -145,7 +145,6 @@ deps = [ "//base", "//components/services/app_service/public/mojom", - "//third_party/blink/public/common", "//url", ] }
diff --git a/components/services/app_service/public/cpp/intent_util.cc b/components/services/app_service/public/cpp/intent_util.cc index 0adc3dd..7e9f64d4 100644 --- a/components/services/app_service/public/cpp/intent_util.cc +++ b/components/services/app_service/public/cpp/intent_util.cc
@@ -19,7 +19,6 @@ #include "components/services/app_service/public/mojom/types.mojom-shared.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" -#include "third_party/blink/public/common/mime_util/mime_util.h" namespace { @@ -130,14 +129,6 @@ return true; } -bool ExtensionMatched(const std::string& intent_extension, - const std::string& filter_extension) { - if (filter_extension == kWildCardAny) - return true; - return base::EndsWith(intent_extension, filter_extension, - base::CompareCase::INSENSITIVE_ASCII); -} - } // namespace namespace apps_util { @@ -161,15 +152,9 @@ return intent; } -apps::mojom::IntentPtr CreateViewIntentFromFiles( - std::vector<apps::mojom::IntentFilePtr> files) { - auto intent = apps::mojom::Intent::New(); - intent->action = kIntentActionView; - intent->files = std::move(files); - return intent; -} +namespace { -apps::mojom::IntentPtr CreateShareIntentFromFiles( +apps::mojom::IntentPtr CreateIntentFromFiles( const std::vector<GURL>& filesystem_urls, const std::vector<std::string>& mime_types) { DCHECK_EQ(filesystem_urls.size(), mime_types.size()); @@ -182,6 +167,23 @@ file->mime_type = mime_types.at(i); intent->files->push_back(std::move(file)); } + return intent; +} + +} // namespace + +apps::mojom::IntentPtr CreateViewIntentFromFiles( + const std::vector<GURL>& filesystem_urls, + const std::vector<std::string>& mime_types) { + auto intent = CreateIntentFromFiles(filesystem_urls, mime_types); + intent->action = kIntentActionView; + return intent; +} + +apps::mojom::IntentPtr CreateShareIntentFromFiles( + const std::vector<GURL>& filesystem_urls, + const std::vector<std::string>& mime_types) { + auto intent = CreateIntentFromFiles(filesystem_urls, mime_types); intent->action = filesystem_urls.size() == 1 ? kIntentActionSend : kIntentActionSendMultiple; return intent; @@ -259,8 +261,7 @@ case apps::mojom::PatternMatchType::kMimeType: // kMimeType as a match for kFile is handled in FileMatchesConditionValue. return MimeTypeMatched(value, condition_value->value); - case apps::mojom::PatternMatchType::kFileExtension: - case apps::mojom::PatternMatchType::kIsDirectory: { + case apps::mojom::PatternMatchType::kFileExtension: { // Handled in FileMatchesConditionValue. NOTREACHED(); return false; @@ -282,9 +283,8 @@ return file->mime_type.has_value() && MimeTypeMatched(file->mime_type.value(), condition_value->value); case apps::mojom::PatternMatchType::kFileExtension: - return ExtensionMatched(file->url.path(), condition_value->value); - case apps::mojom::PatternMatchType::kIsDirectory: - return file->is_directory == apps::mojom::OptionalBool::kTrue; + return base::EndsWith(file->url.path(), condition_value->value, + base::CompareCase::INSENSITIVE_ASCII); } } @@ -353,10 +353,6 @@ bool FilterIsForFileExtensions(const apps::mojom::IntentFilterPtr& filter) { for (const auto& condition : filter->conditions) { - // We expect action conditions to be paired with file conditions. - if (condition->condition_type == apps::mojom::ConditionType::kAction) { - continue; - } if (condition->condition_type != apps::mojom::ConditionType::kFile) { return false; } @@ -370,61 +366,6 @@ return true; } -namespace { - -void GetMimeTypesAndExtensions(const apps::mojom::IntentFilterPtr& filter, - std::set<std::string>& mime_types, - std::set<std::string>& file_extensions) { - for (const auto& condition : filter->conditions) { - if (condition->condition_type != apps::mojom::ConditionType::kFile) { - continue; - } - for (const auto& condition_value : condition->condition_values) { - if (condition_value->match_type == - apps::mojom::PatternMatchType::kFileExtension) { - file_extensions.insert(condition_value->value); - } - if (condition_value->match_type == - apps::mojom::PatternMatchType::kMimeType) { - mime_types.insert(condition_value->value); - } - } - } -} - -} // namespace - -bool IsGenericFileHandler(const apps::mojom::IntentPtr& intent, - const apps::mojom::IntentFilterPtr& filter) { - if (!intent->files.has_value()) - return false; - - std::set<std::string> mime_types; - std::set<std::string> file_extensions; - GetMimeTypesAndExtensions(filter, mime_types, file_extensions); - if (file_extensions.count("*") > 0 || mime_types.count("*") > 0 || - mime_types.count("*/*") > 0) - return true; - - // If a text/* file handler matches with an unsupported text mime type, we - // regard it as a generic match. - if (mime_types.count("text/*")) { - for (const auto& file : intent->files.value()) { - if (file->mime_type.has_value() && - blink::IsUnsupportedTextMimeType(file->mime_type.value())) { - return true; - } - } - } - - // We consider it a generic match if a directory is selected. - for (const auto& file : intent->files.value()) { - if (file->is_directory == apps::mojom::OptionalBool::kTrue) - return true; - } - return false; -} - // TODO(crbug.com/853604): For glob match, it is currently only for Android // intent filters, so we will use the ARC intent filter implementation that is // transcribed from Android codebase, to prevent divergence from Android code.
diff --git a/components/services/app_service/public/cpp/intent_util.h b/components/services/app_service/public/cpp/intent_util.h index e7e7022..2584251 100644 --- a/components/services/app_service/public/cpp/intent_util.h +++ b/components/services/app_service/public/cpp/intent_util.h
@@ -33,9 +33,11 @@ // Create an intent struct for a Create Note action. apps::mojom::IntentPtr CreateCreateNoteIntent(); -// Create an intent struct with the list of files with action kIntentActionView. +// Create an intent struct from the filesystem urls and mime types +// of a list of files with action kIntentActionView. apps::mojom::IntentPtr CreateViewIntentFromFiles( - std::vector<apps::mojom::IntentFilePtr> files); + const std::vector<GURL>& filesystem_urls, + const std::vector<std::string>& mime_types); // Create an intent struct from the filesystem urls and mime types // of a list of files with action kIntentActionSend{Multiple}. @@ -87,9 +89,6 @@ // Return true if |filter| only contains file extension pattern matches. bool FilterIsForFileExtensions(const apps::mojom::IntentFilterPtr& filter); -bool IsGenericFileHandler(const apps::mojom::IntentPtr& intent, - const apps::mojom::IntentFilterPtr& filter); - // Return true if |value| matches |pattern| with simple glob syntax. // In this syntax, you can use the '*' character to match against zero or // more occurrences of the character immediately before. If the character
diff --git a/components/services/app_service/public/cpp/intent_util_unittest.cc b/components/services/app_service/public/cpp/intent_util_unittest.cc index 4413babe..d69ef4b 100644 --- a/components/services/app_service/public/cpp/intent_util_unittest.cc +++ b/components/services/app_service/public/cpp/intent_util_unittest.cc
@@ -485,13 +485,6 @@ return url; } -std::vector<apps::mojom::IntentFilePtr> vectorise( - const apps::mojom::IntentFilePtr& file) { - std::vector<apps::mojom::IntentFilePtr> vector; - vector.push_back(file.Clone()); - return vector; -} - TEST_F(IntentUtilTest, FileExtensionMatch) { std::string mime_type_mp3 = "audio/mp3"; std::string file_ext_mp3 = "mp3"; @@ -500,30 +493,36 @@ auto file_filter = apps_util::CreateFileFilterForView(mime_type_mp3, file_ext_mp3, "label"); - auto file = apps::mojom::IntentFile::New(); - file->url = test_url("abc.mp3"); - file->is_directory = apps::mojom::OptionalBool::kFalse; + std::vector<GURL> urls; + std::vector<std::string> mime_types; + + urls.push_back(test_url("abc.mp3")); // Test match with the same mime type and the same file extension. - file->mime_type = mime_type_mp3; - auto intent = apps_util::CreateViewIntentFromFiles(vectorise(file)); + mime_types.push_back(mime_type_mp3); + auto intent = apps_util::CreateViewIntentFromFiles(urls, mime_types); EXPECT_TRUE(apps_util::IntentMatchesFilter(intent, file_filter)); // Test match with different mime types and the same file extension. - file->mime_type = mime_type_mpeg; - intent = apps_util::CreateViewIntentFromFiles(vectorise(file)); + mime_types.clear(); + mime_types.push_back(mime_type_mpeg); + intent = apps_util::CreateViewIntentFromFiles(urls, mime_types); EXPECT_TRUE(apps_util::IntentMatchesFilter(intent, file_filter)); // Test match with the same mime type and a different file extension. - file->url = test_url("abc.png"); - file->mime_type = mime_type_mp3; - intent = apps_util::CreateViewIntentFromFiles(vectorise(file)); + urls.clear(); + urls.push_back(test_url("abc.png")); + mime_types.clear(); + mime_types.push_back(mime_type_mp3); + intent = apps_util::CreateViewIntentFromFiles(urls, mime_types); EXPECT_TRUE(apps_util::IntentMatchesFilter(intent, file_filter)); // Test match with different mime types and a different file extension. - file->url = test_url("abc.png"); - file->mime_type = mime_type_mpeg; - intent = apps_util::CreateViewIntentFromFiles(vectorise(file)); + urls.clear(); + urls.push_back(test_url("abc.png")); + mime_types.clear(); + mime_types.push_back(mime_type_mpeg); + intent = apps_util::CreateViewIntentFromFiles(urls, mime_types); EXPECT_FALSE(apps_util::IntentMatchesFilter(intent, file_filter)); }
diff --git a/components/services/app_service/public/mojom/types.mojom b/components/services/app_service/public/mojom/types.mojom index 3312b7c..1b2f70b3 100644 --- a/components/services/app_service/public/mojom/types.mojom +++ b/components/services/app_service/public/mojom/types.mojom
@@ -318,7 +318,6 @@ kGlob, kMimeType, kFileExtension, - kIsDirectory, }; // For pattern type of condition, the value match will be based on the pattern @@ -366,7 +365,6 @@ string? file_name; // Human readable file name, including extension. Should // not contain path separators. uint64 file_size; // File size in bytes. - OptionalBool is_directory; // Whether this is a directory or not. }; // Action and resource handling request. This should
diff --git a/components/services/font/font_loader_unittest.cc b/components/services/font/font_loader_unittest.cc index f508bd8..4390da1 100644 --- a/components/services/font/font_loader_unittest.cc +++ b/components/services/font/font_loader_unittest.cc
@@ -48,7 +48,7 @@ FT_Face font_face; FT_Open_Args open_args = {FT_OPEN_MEMORY, reinterpret_cast<FT_Byte*>(file_contents.data()), - file_size}; + static_cast<FT_Long>(file_size)}; CHECK_EQ(FT_Err_Ok, FT_Open_Face(library, &open_args, 0, &font_face)); font_family_name = FT_Get_Postscript_Name(font_face); FT_Done_Face(font_face);
diff --git a/components/strings/components_strings_am.xtb b/components/strings/components_strings_am.xtb index 9a0be43..2dc5ca5 100644 --- a/components/strings/components_strings_am.xtb +++ b/components/strings/components_strings_am.xtb
@@ -1307,6 +1307,7 @@ <translation id="5252000469029418751">C7 (የደብዳቤ ፖስታ)</translation> <translation id="5254043433801397071">የህትመት ይዘትን አትባ</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">ለማንኛውም አንሳ</translation> <translation id="5265446478903775694">Google ላይ የእኔን ግላዊነት ያቀናብሩ</translation> <translation id="5266128565379329178">ከላይ ጠርዝ</translation> <translation id="5269225904387178860">አራቴ ከታች ብሳ</translation> @@ -1831,6 +1832,7 @@ <translation id="7153618581592392745">ፈዘዝ ያለ ወይን ጠጅ</translation> <translation id="7156870133441232244">አገልጋዩ ወደ TLS 1.2 ወይም ከዚያ በኋላ ማላቅ አለበት።</translation> <translation id="717330890047184534">የGaia መታወቂያ፦</translation> +<translation id="7173920250514487165">ሚስጥራዊ ይዘትን በማያ ገጽዎ ላይ ያንሱ</translation> <translation id="7174545416324379297">ተዋህደዋል</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ተጨማሪ}one{<ph name="SHIPPING_OPTION_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ተጨማሪ}other{<ph name="SHIPPING_OPTION_PREVIEW" /> እና <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ተጨማሪ}}</translation> <translation id="7179323680825933600">የመክፈያ ዘዴዎችን አስቀምጥ እና ሙላ</translation> @@ -2090,6 +2092,7 @@ <translation id="7977538094055660992">የውጽዓት መሣሪያ</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">ምናባዊ የእውነታ መሣሪያዎችን እና ውሂብን ለመጠቀም መጠየቅ ይችላል</translation> +<translation id="7984699858161118573">አስተዳዳሪው በማያ ገጹ ላይ ባለው ሚስጥራዊ ይዘት ምክንያት ቅጽበታዊ ገጽ እይታዎችን ወይም ቀረጻዎችን እንዲወስዱ አይመክርም</translation> <translation id="7984945080620862648">ድር ጣቢያው Chrome ሊሰራባቸው የማይችላቸው የተዘበራረቁ ምስክርነቶችን ስለላከ <ph name="SITE" />ን አሁን መጎብኘት ይችላሉ። የአውታረ መረብ ስህተቶች እና ጥቃቶች አብዛኛው ጊዜ ጊዜያዊ ናቸው፣ ስለዚህ ይህ ገጽ በኋላ ላይ ሊሰራ ይችላል።</translation> <translation id="79859296434321399">የትክክለኛ እውነታ ይዘትን ለማየት ARCore ይጫኑ</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_as.xtb b/components/strings/components_strings_as.xtb index 83a3532f..e92f444a 100644 --- a/components/strings/components_strings_as.xtb +++ b/components/strings/components_strings_as.xtb
@@ -1311,6 +1311,7 @@ <translation id="5252000469029418751">C7 (লেফাফা)</translation> <translation id="5254043433801397071">প্ৰিণ্টৰ সমল অপ্টিমাইজ কৰক</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">তথাপি কেপচাৰ কৰক</translation> <translation id="5265446478903775694">Googleত মোৰ গোপনীয়তা পৰিচালনা কৰক</translation> <translation id="5266128565379329178">ওপৰৰ অংশত সংযুক্ত কৰক</translation> <translation id="5269225904387178860">তলৰ অংশ চতুর্ভূজ আকাৰত পাঞ্চ কৰক</translation> @@ -1834,6 +1835,7 @@ <translation id="7153618581592392745">লেভেণ্ডাৰ</translation> <translation id="7156870133441232244">ছার্ভাৰটো TLS 1.2 অথবা তাতকৈ পাছৰ সংস্কৰণলৈ আপগ্ৰে’ড হ’ব লাগে।</translation> <translation id="717330890047184534">Gaia আইডি:</translation> +<translation id="7173920250514487165">আপোনাৰ স্ক্ৰীনত থকা গোপনীয় সমল কেপচাৰ কৰক</translation> <translation id="7174545416324379297">একত্ৰিত কৰা হৈছে</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> আৰু <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />টা}one{<ph name="SHIPPING_OPTION_PREVIEW" /> আৰু <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />টা}other{<ph name="SHIPPING_OPTION_PREVIEW" /> আৰু <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />টা}}</translation> <translation id="7179323680825933600">পৰিশোধ পদ্ধতি ছেভ কৰক আৰু পূৰ কৰক</translation> @@ -2093,6 +2095,7 @@ <translation id="7977538094055660992">আউটপুট ডিভাইচ</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">ভাৰ্চুৱেল ৰিয়েলিটি ডিভাইচসমূহ আৰু ডেটা ব্যৱহাৰ কৰিবলৈ বিচাৰিব পাৰে</translation> +<translation id="7984699858161118573">স্ক্ৰীনত গোপনীয় সমল থকাৰ বাবে প্ৰশাসকে স্ক্ৰীনশ্বট লোৱা অথবা ৰেকৰ্ড কৰাটো চুপাৰিছ নকৰে</translation> <translation id="7984945080620862648">আপুনি এই মুহূৰ্তত <ph name="SITE" /> ছাইটটো খুলিব নোৱাৰে কাৰণ ৱেবছাইটটোৱে বিশৃংখল ক্ৰেডেনশ্বিয়েল পঠিয়াইছে যিটো Chromeএ চলাব নোৱাৰে। নেটৱৰ্কৰ আসোঁৱাহ আৰু আক্ৰমণবোৰ সাধাৰণতে অস্থায়ী হয় গতিকে এই পৃষ্ঠাটোৱে পাছত কাম কৰিব পাৰে।</translation> <translation id="79859296434321399">পৰিৱৰ্ধিত বাস্তৱিকতাৰ সমল চাবলৈ ARCore ইনষ্টল কৰক</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_az.xtb b/components/strings/components_strings_az.xtb index c93a715..07f2bbf 100644 --- a/components/strings/components_strings_az.xtb +++ b/components/strings/components_strings_az.xtb
@@ -290,7 +290,7 @@ <translation id="1838374766361614909">Axtarışı təmizləyin</translation> <translation id="1839551713262164453">Siyasət dəyərlərinin doğrulanması xəta səbəbilə alınmadı</translation> <translation id="1842969606798536927">Ödəniş</translation> -<translation id="1856713167556118146">Anonim rejim nə etmir</translation> +<translation id="1856713167556118146">Anonim rejim nələri bacarmır</translation> <translation id="1863257867908022953">Qab 12</translation> <translation id="1871208020102129563">Proksi .pac skript URL deyil sabit proksi serverlər istifadə etmək üçün ayarlanıb.</translation> <translation id="1871284979644508959">Tələb olunan sahə</translation> @@ -1310,6 +1310,7 @@ <translation id="5252000469029418751">C7 (Zərf)</translation> <translation id="5254043433801397071">Çap məzmununu optimallaşdırın</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">Yenə də çəkiliş edilsin</translation> <translation id="5265446478903775694">Google'da məxfiliyimi idarə edin</translation> <translation id="5266128565379329178">Yuxarıdan uclarını qovuşdurun</translation> <translation id="5269225904387178860">Aşağıdan dördlü deşik açın</translation> @@ -1834,6 +1835,7 @@ <translation id="7153618581592392745">Yasəmən</translation> <translation id="7156870133441232244">Server TLS 1.2 və ya daha sonrakı versiyaya güncəlləməlidir.</translation> <translation id="717330890047184534">Gaia ID:</translation> +<translation id="7173920250514487165">Ekranınızda məxfi məzmunu çəkin</translation> <translation id="7174545416324379297">Birləşdirildi</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> və daha <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> və daha <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation> <translation id="7179323680825933600">Ödəniş Üsullarını Yadda Saxlayın və Doldurun</translation> @@ -2093,6 +2095,7 @@ <translation id="7977538094055660992">Çıxış cihazı</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">Saytlar virtual reallıq cihazları və datadan istifadə üçün icazə istəyə bilər</translation> +<translation id="7984699858161118573">Administrator ekranda məxfi məzmun olduğuna görə skrinşot çəkmək və ya çəkiliş etməyi məsləhət görmür</translation> <translation id="7984945080620862648">Sayt güvənsiz kredensiallar göndərdiyi üçün <ph name="SITE" /> ünvanına girə bilməzsiniz.</translation> <translation id="79859296434321399">Artırılmış virtual reallıq kontentinə baxmaq üçün ARCore quraşdırın</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_cs.xtb b/components/strings/components_strings_cs.xtb index e3d30db..3e8e644 100644 --- a/components/strings/components_strings_cs.xtb +++ b/components/strings/components_strings_cs.xtb
@@ -1302,6 +1302,7 @@ <translation id="5252000469029418751">C7 (obálka)</translation> <translation id="5254043433801397071">Optimalizovat obsah tisku</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">Přesto pořídit</translation> <translation id="5265446478903775694">Spravovat ochranu soukromí na Googlu</translation> <translation id="5266128565379329178">Vazba nahoře</translation> <translation id="5269225904387178860">Čtyři otvory dole</translation> @@ -1825,6 +1826,7 @@ <translation id="7153618581592392745">Levandulová</translation> <translation id="7156870133441232244">Server je třeba upgradovat na protokol TLS 1.2 nebo novější.</translation> <translation id="717330890047184534">ID Gaia:</translation> +<translation id="7173920250514487165">Na obrazovce se nachází důvěrný obsah</translation> <translation id="7174545416324379297">Sloučeno</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> další}few{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> další}many{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> další}other{<ph name="SHIPPING_OPTION_PREVIEW" /> a <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> dalších}}</translation> <translation id="7179323680825933600">Ukládat a vyplňovat platební metody</translation> @@ -2083,6 +2085,7 @@ <translation id="7977538094055660992">Výstupní zařízení</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">Může žádat o použití zařízení a dat pro virtuální realitu</translation> +<translation id="7984699858161118573">Administrátor pořizování snímků nebo záznamu vzhledem k důvěrnému obsahu na obrazovce nedoporučuje</translation> <translation id="7984945080620862648">Web <ph name="SITE" /> teď nemůžete navštívit, protože webové stránky odeslaly zakódované identifikační údaje, které Chrome nedokáže zpracovat. Síťové chyby a útoky jsou obvykle dočasné, tato stránka pravděpodobně později bude fungovat.</translation> <translation id="79859296434321399">Chcete-li zobrazit obsah pro rozšířenou realitu, nainstalujte ARCore</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_de.xtb b/components/strings/components_strings_de.xtb index 6ffbe0e..fe7f2a3 100644 --- a/components/strings/components_strings_de.xtb +++ b/components/strings/components_strings_de.xtb
@@ -1304,6 +1304,7 @@ <translation id="5252000469029418751">C7 (Umschlag)</translation> <translation id="5254043433801397071">Druckinhalte optimieren</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">Trotzdem aufnehmen</translation> <translation id="5265446478903775694">Datenschutz bei Google verwalten</translation> <translation id="5266128565379329178">Bindung oben</translation> <translation id="5269225904387178860">Vierfache Lochung unten</translation> @@ -1828,6 +1829,7 @@ <translation id="7153618581592392745">Lavendel</translation> <translation id="7156870133441232244">Der Server sollte auf TLS 1.2 oder höher aktualisiert werden.</translation> <translation id="717330890047184534">GAIA-ID: </translation> +<translation id="7173920250514487165">Vertrauliche Inhalte auf dem Bildschirm aufnehmen</translation> <translation id="7174545416324379297">Zusammengeführt</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> und <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> weitere}other{<ph name="SHIPPING_OPTION_PREVIEW" /> und <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> weitere}}</translation> <translation id="7179323680825933600">Zahlungsmethoden speichern und ausfüllen</translation> @@ -2087,6 +2089,7 @@ <translation id="7977538094055660992">Ausgabegerät</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">Darf nachfragen, wenn sie Virtual-Reality-Geräte und -Daten verwenden möchte</translation> +<translation id="7984699858161118573">Der Administrator rät davon ab, Screenshots oder Aufzeichnungen zu erstellen, da vertrauliche Informationen auf dem Bildschirm zu sehen sind</translation> <translation id="7984945080620862648">Sie können <ph name="SITE" /> zurzeit nicht aufrufen, weil die Website verschlüsselte Anmeldedaten gesendet hat, die von Chrome nicht verarbeitet werden können. Netzwerkfehler und Angriffe sind in der Regel nur vorübergehend, sodass die Seite wahrscheinlich später wieder funktioniert.</translation> <translation id="79859296434321399">ARCore installieren, um Augmented-Reality-Inhalte zu sehen</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_fa.xtb b/components/strings/components_strings_fa.xtb index fa6d6a10..9e78e66 100644 --- a/components/strings/components_strings_fa.xtb +++ b/components/strings/components_strings_fa.xtb
@@ -1315,6 +1315,7 @@ <translation id="5252000469029418751">C7 (Envelope)</translation> <translation id="5254043433801397071">بهینهسازی محتوای چاپ</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">درهرصورت ضبط شود</translation> <translation id="5265446478903775694">مدیریت حریمخصوصی در Google</translation> <translation id="5266128565379329178">بههم چسباندن از بالا</translation> <translation id="5269225904387178860">چهار سوراخ در پایین</translation> @@ -1839,6 +1840,7 @@ <translation id="7153618581592392745">نیلی کمرنگ</translation> <translation id="7156870133441232244">سرور باید به «امنیت لایه انتقال» (TLS) نسخه ۱.۲ یا بالاتر ارتقا داده شود.</translation> <translation id="717330890047184534">شناسه Gaia:</translation> +<translation id="7173920250514487165">ضبط محتوای محرمانه روی صفحه</translation> <translation id="7174545416324379297">ادغام شد</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> گزینه دیگر}one{<ph name="SHIPPING_OPTION_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> گزینه دیگر}other{<ph name="SHIPPING_OPTION_PREVIEW" /> و <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> گزینه دیگر}}</translation> <translation id="7179323680825933600">ذخیره و تکمیل روشهای پرداخت</translation> @@ -2098,6 +2100,7 @@ <translation id="7977538094055660992">دستگاه خروجی</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">میتواند برای استفاده از دادهها و دستگاههای واقعیت مجازی درخواست دهد</translation> +<translation id="7984699858161118573">بهدلیل محتوای محرمانهای که روی صفحه وجود دارد، سرپرست توصیه میکند از صفحهنمایش نماگرفت نگیرید یا محتوای روی آن را ضبط نکنید.</translation> <translation id="7984945080620862648">در حال حاضر نمیتوانید از <ph name="SITE" /> بازدید کنید زیرا این وبسایت اعتبارنامههای درهمی ارسال کرده است که Chrome نمیتواند پردازش کند. معمولاً خطاهای شبکه و حملهها موقتی هستند، بنابراین احتمالاً این صفحه بعداً کار خواهد کرد.</translation> <translation id="79859296434321399">برای مشاهده محتوای واقعیت افزوده، ARCore را نصب کنید</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_fr-CA.xtb b/components/strings/components_strings_fr-CA.xtb index da404c6d..9ca230b 100644 --- a/components/strings/components_strings_fr-CA.xtb +++ b/components/strings/components_strings_fr-CA.xtb
@@ -1306,6 +1306,7 @@ <translation id="5252000469029418751">Enveloppe C7</translation> <translation id="5254043433801397071">Optimiser le contenu d'impression</translation> <translation id="5254958791078852567">E</translation> +<translation id="5255690596502591079">Prendre une capture d'écran quand même</translation> <translation id="5265446478903775694">Gérez ma confidentialité sur Google</translation> <translation id="5266128565379329178">Reliure en haut</translation> <translation id="5269225904387178860">Quadruple perforation en bas</translation> @@ -1830,6 +1831,7 @@ <translation id="7153618581592392745">Lavande</translation> <translation id="7156870133441232244">Le serveur devrait effectuer la mise à niveau vers TLS 1.2 ou une version ultérieure.</translation> <translation id="717330890047184534">Identifiant Gaia :</translation> +<translation id="7173920250514487165">Capturer du contenu confidentiel sur votre écran</translation> <translation id="7174545416324379297">Fusionnées</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> autre option de livraison}one{<ph name="SHIPPING_OPTION_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> autre option de livraison}other{<ph name="SHIPPING_OPTION_PREVIEW" /> et <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> autres options de livraison}}</translation> <translation id="7179323680825933600">Enregistrer et remplir les modes de paiement</translation> @@ -2089,6 +2091,7 @@ <translation id="7977538094055660992">Appareil de sortie</translation> <translation id="7977894662897852582">EDP</translation> <translation id="798134797138789862">Les sites peuvent demander à utiliser des données et des appareils de réalité virtuelle</translation> +<translation id="7984699858161118573">L'administrateur déconseille de prendre des captures d'écran ou d'effectuer des enregistrements d'écran en raison du contenu confidentiel à l'écran</translation> <translation id="7984945080620862648">Vous ne pouvez pas consulter le site <ph name="SITE" /> pour le moment, car il a envoyé des identifiants brouillés qui ne peuvent être traités par Chrome. Les erreurs réseau et les attaques sont généralement temporaires. Vous devriez donc pouvoir accéder à cette page plus tard.</translation> <translation id="79859296434321399">Pour regarder du contenu de réalité augmentée, installez ARCore</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_gu.xtb b/components/strings/components_strings_gu.xtb index 09cac36..679df41 100644 --- a/components/strings/components_strings_gu.xtb +++ b/components/strings/components_strings_gu.xtb
@@ -32,6 +32,7 @@ <translation id="1074497978438210769">સુરક્ષિત નથી</translation> <translation id="1076113272840682464">Chromeમાં ડાઉનલોડ મેનેજ કરો</translation> <translation id="1080116354587839789">પહોળાઈ પ્રમાણે ફિટ કરો</translation> +<translation id="1081061862829655580">ટ્રે 19</translation> <translation id="1086953900555227778">અનુક્રમણિકા-5x8</translation> <translation id="1088860948719068836">કાર્ડ પર નામ ઉમેરો</translation> <translation id="1089439967362294234">પાસવર્ડ બદલો</translation> @@ -70,6 +71,7 @@ <translation id="1209221128712833642">'ફોર્મ બનાવો' બટન, Google Formsમાં ઝડપથી કોઈ નવું ફોર્મ બનાવવા માટે, Enter કી દબાવો</translation> <translation id="121201262018556460">તમે <ph name="DOMAIN" /> સુધી પહોંચવાનો પ્રયાસ કર્યો, પણ પ્રમાણપત્ર રજૂ કરતા સર્વર પાસે નબળી કી છે. હુમલાખોરે ખાનગી કી તોડી હોઈ શકે છે, અને બને કે સર્વર તમારું અપેક્ષિત સર્વર ન હોય (તમે કોઈ હુમલાખોર સાથે વાર્તાલાપ કરી રહ્યાં હોઈ શકો છો).</translation> <translation id="1219129156119358924">સિસ્ટમ સુરક્ષા</translation> +<translation id="1222060260947439312">જમણી બાજુની ટ્રે</translation> <translation id="1227224963052638717">અજ્ઞાત પૉલિસી.</translation> <translation id="1228893227497259893">ખોટો અસ્તિત્વ ઓળખકર્તા</translation> <translation id="1232569758102978740">શીર્ષક વિનાનું</translation> @@ -91,11 +93,13 @@ <translation id="1257553931232494454">નાનું-મોટું કરવાના લેવલ</translation> <translation id="1262388120645841613"><ph name="MANAGE_CHROME_SETTINGS_FOCUSED_FRIENDLY_MATCH_TEXT" />, તમારા Chrome સેટિંગ મેનેજ કરવા માટે, પહેલાં Tab અને પછી Enter કી દબાવો</translation> <translation id="1263231323834454256">વાચન સૂચિ</translation> +<translation id="1264309058268477500">વૈકલ્પિક</translation> <translation id="1269096320618100013">ઍક્સેસિબિલિટી સેટિંગ મેનેજ કરવા માટેનું બટન, Chrome OS સેટિંગમાં તમારા ઍક્સેસિબિલિટીના સાધનો મનગમતા બનાવવા માટે Enter કી દબાવો</translation> <translation id="1269516672602708785">Google Sitesમાં ઝડપથી કોઈ નવી સાઇટ બનાવો</translation> <translation id="1270502636509132238">પિકઅપ પદ્ધતિ</translation> <translation id="1281476433249504884">સ્ટૅકર 1</translation> <translation id="1285320974508926690">આ સાઇટનું ક્યારેય ભાષાંતર કરશો નહીં</translation> +<translation id="1292571435393770077">ટ્રે 16</translation> <translation id="1292701964462482250">"તમારા કમ્પ્યુટરમાંનું સૉફ્ટવેર Chromeને સુરક્ષિત રીતે વેબ સાથે કનેક્ટ થવાથી અટકાવે છે" (માત્ર Windows કમ્પ્યુટર)</translation> <translation id="1294154142200295408">આદેશ વાક્યમાં વિવિધતા</translation> <translation id="129553762522093515">તાજેતરમાં બંધ કરેલા</translation> @@ -203,6 +207,7 @@ <translation id="1592005682883173041">સ્થાનિક ડેટા ઍક્સેસ</translation> <translation id="1594030484168838125">પસંદ કરો</translation> <translation id="161042844686301425">સ્યાન</translation> +<translation id="1611101756749861742">બીજો રોલ</translation> <translation id="1620510694547887537">કૅમેરો</translation> <translation id="1623104350909869708">આ પૃષ્ઠને વધારાના સંવાદો બનાવતા અટકાવો</translation> <translation id="16338877384480380">સ્થાપત્ય-B</translation> @@ -279,14 +284,17 @@ <translation id="182139138257690338">ઑટોમૅટિક રીતે ડાઉનલોડ</translation> <translation id="1821930232296380041">અમાન્ય વિનંતી અથવા વિનંતી પરિમાણો</translation> <translation id="1822540298136254167">તમે મુલાકાત લો તે વેબસાઇટ અને તેના પર વિતાવેલો સમય</translation> +<translation id="1824402189105105503">આઠમો રોલ</translation> <translation id="1826516787628120939">તપાસી રહ્યાં છે</translation> <translation id="1834321415901700177">આ સાઇટમાં હાનિકારક પ્રોગ્રામ્સ છે</translation> <translation id="1838374766361614909">શોધ સાફ કરો</translation> <translation id="1839551713262164453">ભૂલના લીધે પૉલિસી મૂલ્યોની માન્યતા નિષ્ફળ થઈ</translation> <translation id="1842969606798536927">ચુકવણી કરો</translation> <translation id="1856713167556118146">છૂપો મોડ શું કરતો નથી</translation> +<translation id="1863257867908022953">ટ્રે 12</translation> <translation id="1871208020102129563">પ્રૉક્સી નક્કી કરેલા પ્રૉક્સી સર્વરનો ઉપયોગ કરવા માટે સેટ કરેલી છે, .pac સ્ક્રિપ્ટ URL નથી.</translation> <translation id="1871284979644508959">જરૂરી ફીલ્ડ</translation> +<translation id="1875025161375567525">ફોટો ટ્રે</translation> <translation id="1875512691959384712">Google Forms</translation> <translation id="187918866476621466">સ્ટાર્ટઅપ પૃષ્ઠો ખોલો</translation> <translation id="1883255238294161206">સૂચિ સંકુચિત કરો</translation> @@ -312,6 +320,7 @@ <translation id="1962204205936693436"><ph name="DOMAIN" /> બુકમાર્ક</translation> <translation id="1973335181906896915">અનુક્રમાંકન ભૂલ</translation> <translation id="1974060860693918893">વિગતવાર</translation> +<translation id="1975457531113383421">ઇનપુટ ટ્રે</translation> <translation id="1975584088563498795">મેઇલબૉક્સ 10</translation> <translation id="1978555033938440688">ફર્મવેયર વર્ઝન</translation> <translation id="1988881251331415125">જો જોડણી સાચી હોય, તો <ph name="BEGIN_LINK" />કનેક્ટિવિટી નિદાન ચલાવવાનો પ્રયાસ કરી જુઓ<ph name="END_LINK" />.</translation> @@ -325,6 +334,7 @@ <translation id="2025186561304664664">પ્રૉક્સીને ઑટો ગોઠવણી મોડ પર સેટ કરાઈ છે.</translation> <translation id="2025891858974379949">અસુરક્ષિત કન્ટેન્ટ</translation> <translation id="2032962459168915086"><ph name="BEGIN_LINK" />પ્રૉક્સી અને ફાયરવૉલ ચેક કરવાનો પ્રયાસ કરો<ph name="END_LINK" /></translation> +<translation id="2036983605131262583">વૈકલ્પિક રોલ</translation> <translation id="2042213636306070719">ટ્રે 7</translation> <translation id="204357726431741734">તમારા Google એકાઉન્ટમાં સ્ટોર કરેલા પાસવર્ડનો ઉપયોગ કરવા માટે સાઇન ઇન કરો</translation> <translation id="2053111141626950936"><ph name="LANGUAGE" />માં લખાયેલાં પેજનો અનુવાદ થશે નહીં.</translation> @@ -480,6 +490,7 @@ <translation id="2546283357679194313">કૂકીઝ અને સાઇટ ડેટા</translation> <translation id="254947805923345898">પૉલિસી મૂલ્ય માન્ય નથી.</translation> <translation id="255002559098805027"><ph name="HOST_NAME" /> એ અમાન્ય પ્રતિસાદ મોકલ્યો.</translation> +<translation id="2552246211866555379">Hagaki</translation> <translation id="2552295903035773204">હવેથી કાર્ડને કન્ફર્મ કરવા માટે સ્ક્રીન લૉકનો ઉપયોગ કરો</translation> <translation id="2553853292994445426">તમારા સુરક્ષિત DNS સેટિંગ ચેક કરો. તમે એવું DNS સર્વર ગોઠવ્યું હોઈ શકે છે જેના કનેક્શન નિષ્ફળ થઈ રહ્યાં છે.</translation> <translation id="2556876185419854533">&ફેરફાર કરવાનું રદ કરો</translation> @@ -530,6 +541,7 @@ <translation id="2713444072780614174">શ્વેત</translation> <translation id="2715612312510870559"><ph name="UPDATE_CREDIT_CARD_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chrome સેટિંગમાં તમારી ચુકવણીઓ અને ક્રેડિટ કાર્ડની માહિતી મેનેજ કરવા માટે Tab પછી Enter દબાવો</translation> <translation id="2721148159707890343">વિનંતી સફળ થઇ</translation> +<translation id="2726001110728089263">બાજુની ટ્રે</translation> <translation id="2728127805433021124">સર્વરનું પ્રમાણપત્ર એક નબળા સહી ઍલ્ગોરિધમનો ઉપયોગ કરીને સહીિત કરેલું છે.</translation> <translation id="2730326759066348565"><ph name="BEGIN_LINK" />કનેક્ટિવિટી ડાયગ્નોસ્ટિક્સ ચલાવી રહ્યાં છે<ph name="END_LINK" /></translation> <translation id="2738330467931008676">પિકઅપ માટેનું સરનામું પસંદ કરો</translation> @@ -561,6 +573,7 @@ <translation id="2880660355386638022">વિંડોનું સ્થાન નિયોજન</translation> <translation id="2881276955470682203">કાર્ડ સાચવીએ?</translation> <translation id="2882949212241984732">ડબલ-ગેટ ફોલ્ડ</translation> +<translation id="2893773853358652045">ચોથો રોલ</translation> <translation id="2900528713135656174">ઇવેન્ટ બનાવો</translation> <translation id="2903493209154104877">સરનામાંઓ</translation> <translation id="290376772003165898">પેજ <ph name="LANGUAGE" />માં નથી?</translation> @@ -619,6 +632,7 @@ <translation id="3096100844101284527">પિકઅપ માટેનું સરનામું ઉમેરો</translation> <translation id="3105172416063519923">સંપત્તિ ID:</translation> <translation id="3107591622054137333"><ph name="BEGIN_LINK" />સુરક્ષિત DNS ગોઠવણી ચેક કરી રહ્યાં છીએ<ph name="END_LINK" /></translation> +<translation id="3108943290502734357">વચ્ચેની ટ્રે</translation> <translation id="3109728660330352905">તમને આ પેજને જોવાનો અધિકાર નથી.</translation> <translation id="3113284927548439113">ત્રીજી પાળી</translation> <translation id="3115874930288085374"><ph name="ENROLLMENT_DOMAIN" /> માટે જરૂરી છે કે તમે તમારા ડેટાનું બૅકઅપ લઈને આ <ph name="DEVICE_TYPE" /> પરત કરો.</translation> @@ -632,6 +646,7 @@ <translation id="3154506275960390542">આ પૃષ્ઠમાં એક ફૉર્મ છે, જે કદાચ સુરક્ષિત રીતે સબમિટ નહીં થાય. જે ડેટા તમે મોકલો તેને પરિવહન દરમિયાન અન્ય લોકો જોઈ શકશે અથવા સર્વર જે મેળવે, તે બદલવા માટે હુમલાખોર ફેરફાર કરી શકશે.</translation> <translation id="315504272643575312"><ph name="MANAGER" /> દ્વારા તમારું એકાઉન્ટ મેનેજ કરવામાં આવે છે.</translation> <translation id="3157931365184549694">રિસ્ટોર કરો</translation> +<translation id="3158539265159265653">ડિસ્ક</translation> <translation id="3162559335345991374">તમે ઉપયોગ કરી રહ્યા છો તે વાઇ-ફાઇને તેના લોગિન પેજની મુલાકાત લેવાની જરૂર હોઈ શકે છે.</translation> <translation id="3169472444629675720">Discover</translation> <translation id="3174168572213147020">આઇલેન્ડ</translation> @@ -794,6 +809,7 @@ <translation id="3658742229777143148">પુનરાવર્તન</translation> <translation id="3664782872746246217">કીવર્ડ:</translation> <translation id="3671540257457995106">કદ બદલવાની મંજૂરી આપીએ?</translation> +<translation id="3675563144891642599">ત્રીજો રોલ</translation> <translation id="3676592649209844519">ડિવાઇસ ID:</translation> <translation id="3677008721441257057">શું તમારો અર્થ <a href="#" id="dont-proceed-link"><ph name="DOMAIN" /></a> હતો?</translation> <translation id="3678029195006412963">વિનંતી પર સહી કરી શક્યાં નથી</translation> @@ -909,6 +925,7 @@ <translation id="4084120443451129199">શોધ મોડ, <ph name="KEYWORD_SUFFIX" /> શોધવા માટે Enter દબાવો</translation> <translation id="4087296516249690906">'ઇવેન્ટ બનાવો' બટન, Google Calendarમાં ઝડપથી કોઈ નવી ઇવેન્ટ બનાવવા માટે, Enter કી દબાવો</translation> <translation id="4088981014127559358">બાજુ 1 છબીને Y અક્ષ પર ખસેડો</translation> +<translation id="4089152113577680600">ટ્રે 14</translation> <translation id="4098354747657067197">આગળ છેતરામણી સાઇટ છે</translation> <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chromeમાં ફૉન્ટના કદ અને ટાઇપફેસ કસ્ટમાઇઝ કરવા માટે, પહેલાં Tab અને પછી Enter કી દબાવો</translation> <translation id="4101413244023615925">ટેક્સ્ટ અને ગ્રાફિક</translation> @@ -943,6 +960,7 @@ <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation> <translation id="4194250254487269611">હમણાં જ તમારું કાર્ડ સાચવી શકાતું નથી</translation> <translation id="4196861286325780578">&ખસેડવું ફરી કરો</translation> +<translation id="4202554117186904723">પાંચમો રોલ</translation> <translation id="4203896806696719780"><ph name="BEGIN_LINK" />ફાયરવોલ અને એન્ટીવાઇરસ ગોઠવણી તપાસીને<ph name="END_LINK" /></translation> <translation id="4209092469652827314">મોટું</translation> <translation id="4209166701302774460">તમે જેના પર જવાનો પ્રયાસ કરી રહ્યાં છો, તે <ph name="ORIGIN" />, સર્વર દ્વારા વિનંતી કરવામાં આવી છે @@ -1004,6 +1022,7 @@ <translation id="4314815835985389558">સિંક મેનેજ કરો</translation> <translation id="4318312030194671742">પેઇન્ટ પ્રીવ્યૂ કમ્પોઝિટર સેવા</translation> <translation id="4318566738941496689">તમારા ડિવાઇસનું નામ અને નેટવર્ક ઍડ્રેસ</translation> +<translation id="4325600325087822253">ટ્રે 17</translation> <translation id="4325863107915753736">લેખ શોધવામાં નિષ્ફળ થયાં</translation> <translation id="4326324639298822553">તમારી સમાપ્તિ તારીખ તપાસો અને ફરી પ્રયાસ કરો</translation> <translation id="4329871760342656885">પૉલિસી વિશ્લેષણ ભૂલ: <ph name="ERROR" /></translation> @@ -1015,6 +1034,7 @@ <translation id="4346833872170306413">રૉક-16K</translation> <translation id="4348834659292907206"><ph name="SITE" />નું કનેક્શન સુરક્ષિત નથી</translation> <translation id="4349531505348777662">હમણાં જ કોઈ છેતરામણી સાઇટ પર તમે તમારો પાસવર્ડ દાખલ કર્યો. Chrome <ph name="WEBSITE_1" />, <ph name="WEBSITE_2" /> તેમજ તમે આ પાસવર્ડનો જ્યાં ઉપયોગ કરતા હોય તે અન્ય સાઇટ પર જઈને તેને હમણાં જ બદલવાનો સુઝાવ આપે છે.</translation> +<translation id="4350629523305688469">મલ્ટિ ફંક્શન ટ્રે</translation> <translation id="4351060348582610152"><ph name="ORIGIN" /> નજીકના બ્લૂટૂથ ડિવાઇસ માટે સ્કૅન કરવા માગે છે. નીચે મુજબના ડિવાઇસ મળ્યા છે:</translation> <translation id="4356973930735388585">આ સાઇટ પરના હુમલાખોરો તમારા કમ્પ્યુટર પર તમારી માહિતી (ઉદાહરણ તરીકે, ફોટો, પાસવર્ડ, સંદેશા અને ક્રેડિટ કાર્ડ)ને ચોરી શકે કે કાઢી નાખે એવા જોખમી પ્રોગ્રામને ઇન્સ્ટૉલ કરવાનો પ્રયાસ કરી શકે છે.</translation> <translation id="4358059973562876591">DnsOverHttpsMode નીતિમાં ભૂલના કારણે તમે ઉલ્લેખ કરેલા નમૂનાઓને કદાચ લાગુ કરવામાં આવશે નહીં.</translation> @@ -1069,6 +1089,7 @@ <translation id="4515275063822566619">કાર્ડ અને સરનામા Chrome અને Google એકાઉન્ટ (<ph name="ACCOUNT_EMAIL" />)માંથી છે. તમે તેને <ph name="BEGIN_LINK" />સેટિંગ<ph name="END_LINK" />માં જઈને મેનેજ કરી શકો છો.</translation> <translation id="4517607026994743406">Comm-10 (એન્વલપ)</translation> <translation id="4521157617044179198"><ph name="WIDTH" /> × <ph name="HEIGHT" /> મિ.મી. (<ph name="ORIENTATION" />)</translation> +<translation id="4521916730539354575">ડાબી બાજુની ટ્રે</translation> <translation id="4522570452068850558">વિગતો</translation> <translation id="4524138615196389145">હવેથી WebAuthnનો ઉપયોગ કરીને તમારા કાર્ડ વધુ ઝડપથી કન્ફર્મ કરો</translation> <translation id="4524805452350978254">કાર્ડ મેનેજ કરો</translation> @@ -1183,6 +1204,7 @@ <translation id="4889420713887366944">છુપી વિન્ડો ખોલો બટન, ખાનગી રીતે બ્રાઉઝ કરવા, નવી છુપી વિન્ડો ખોલવા માટે Enter દબાવો</translation> <translation id="4892518386797173871">પાછળ</translation> <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> +<translation id="4900217275619098670">નવમો રોલ</translation> <translation id="4901778704868714008">સાચવો...</translation> <translation id="4913987521957242411">ઉપર ડાબી બાજુએ કાણું પાડો</translation> <translation id="4918221908152712722"><ph name="APP_NAME" />ને ઇન્સ્ટૉલ કરો (કોઈ ડાઉનલોડ આવશ્યક નથી)</translation> @@ -1231,6 +1253,7 @@ <translation id="5068524481479508725">A10</translation> <translation id="5068778127327928576">{NUM_COOKIES,plural, =1{(1 ઉપયોગમાં છે)}one{(# ઉપયોગમાં છે)}other{(# ઉપયોગમાં છે)}}</translation> <translation id="5070335125961472645"><ph name="BEGIN_LINK" />પ્રૉક્સી ઍડ્રેસ ચેક કરવાનો પ્રયાસ કરો<ph name="END_LINK" /></translation> +<translation id="5070838744279127212">દસમો રોલ</translation> <translation id="507130231501693183">મેઇલબૉક્સ 4</translation> <translation id="5087286274860437796">સર્વરનું પ્રમાણપત્ર આ સમયે માન્ય નથી.</translation> <translation id="5087580092889165836">કાર્ડ ઉમેરો</translation> @@ -1243,6 +1266,7 @@ <translation id="5097501891273180634">A2</translation> <translation id="5108881358339761672">સાઇટ સુરક્ષિત નથી</translation> <translation id="5112422516732747637">A5</translation> +<translation id="5114288597538800140">ટ્રે 18</translation> <translation id="5114987907971894280">વર્ચ્યુઅલ રિયાલિટી</translation> <translation id="5115216390227830982">યુરોપિયન-Edp</translation> <translation id="5115232566827194440">પ્રતિબંધિત 'મેનેજ કરેલા અતિથિ સત્ર' માટે ઓવરરાઇડ</translation> @@ -1276,8 +1300,10 @@ <translation id="5201306358585911203">આ પેજ પરનું શામેલ કરેલ પેજ કહે છે કે</translation> <translation id="5205222826937269299">નામ આવશ્યક છે</translation> <translation id="5209518306177824490">SHA-1 ફિંગરપ્રિંટ</translation> +<translation id="5209670883520018268">ટ્રે 20</translation> <translation id="5215116848420601511">Google Payનો ઉપયોગ કરતી ચુકવણી પદ્ધતિઓ અને ઍડ્રેસ</translation> <translation id="5215363486134917902">ફોલિયો-Sp</translation> +<translation id="521659676233207110">ટ્રે 13</translation> <translation id="5222812217790122047">ઇમેઇલ આવશ્યક છે</translation> <translation id="5230733896359313003">વિતરણ માટેનું સરનામું</translation> <translation id="5230815978613972521">B8</translation> @@ -1481,6 +1507,7 @@ <translation id="5967592137238574583">સંપર્ક માહિતીમાં ફેરફાર કરો</translation> <translation id="5967867314010545767">ઇતિહાસમાંથી દૂર કરો</translation> <translation id="5968793460449681917">દરેક મુલાકાત વખતે</translation> +<translation id="5974052231147553524">છઠ્ઠો રોલ</translation> <translation id="5975083100439434680">ઝૂમ ઘટાડો</translation> <translation id="5979084224081478209">પાસવર્ડ ચેક કરો</translation> <translation id="5980920751713728343">અનુક્રમણિકા-3x5</translation> @@ -1635,11 +1662,13 @@ <translation id="6499038740797743453">પાસવર્ડ રીસેટ કરીએ?</translation> <translation id="6502991525169604759">તમારા ફેરફારો વિના</translation> <translation id="6505563257409036437">બધી છુપી વિન્ડો બંધ કરો</translation> +<translation id="6506959208958864820">પરબિડીયું</translation> <translation id="6508722015517270189">Chrome ને પુનઃપ્રારંભ કરો</translation> <translation id="6513005815064132016">તમારા કૅમેરાની સ્થિતિને ટ્રૅક કરવાનું પૂછી શકે છે</translation> <translation id="6517596291481585650">ચેતવણી: આ પૉલિસીને પૉલિસી દ્વારા ઉલ્લેખ થયા મુજબ સૂચિ તરીકે મર્જ કરવામાં આવી ન હતી, કારણ કે તે સૂચિ નથી.</translation> <translation id="6518133107902771759">પ્રમાણિત કરો</translation> <translation id="6521745193039995384">સક્રિય નથી</translation> +<translation id="6529173248185917884">સાતમો રોલ</translation> <translation id="6529602333819889595">&ફરી કરો ડિલીટ કરો</translation> <translation id="6545864417968258051">બ્લૂટૂથ સ્કૅનિંગ</translation> <translation id="6547208576736763147">ડાબી બાજુએ બે ચતુષ્કોણ કાણાં પાડો</translation> @@ -1674,6 +1703,7 @@ <translation id="6652101503459149953">Windows Helloનો ઉપયોગ કરો</translation> <translation id="6657585470893396449">પાસવર્ડ</translation> <translation id="6660413144148052430">સ્થાન</translation> +<translation id="6662457027866368246">પહેલો રોલ</translation> <translation id="666259744093848177">(x86_64 અનુવાદિત)</translation> <translation id="6665553082534466207">જમણી બાજુએ ત્રણ કાણાં પાડો</translation> <translation id="6671697161687535275">Chromium માંથી ફોર્મ સૂચન દૂર કરીએ?</translation> @@ -1720,6 +1750,7 @@ <translation id="6846340164947227603">વર્ચ્યુઅલ કાર્ડ નંબરનો ઉપયોગ કરો…</translation> <translation id="6852204201400771460">ઍપ ફરીથી લોડ કરીએ?</translation> <translation id="6865412394715372076">હાલમાં આ કાર્ડની ચકાસણી કરી શકાતી નથી</translation> +<translation id="6873456682041376666">સૌથી ઉપરની ટ્રે</translation> <translation id="6874604403660855544">&ઉમેરવું ફરી કરો</translation> <translation id="6881240511396774766">ઝડપથી નવું Google Doc બનાવો</translation> <translation id="6883221904761970440">સુરક્ષિત ચુકવણી માટે લૉગ ઇન વિગતના પ્રમાણીકરણની શીટ બંધ છે</translation> @@ -1800,6 +1831,7 @@ <translation id="7135130955892390533">સ્ટેટસ બતાવો</translation> <translation id="7138472120740807366">વિતરણ પદ્ધતિ</translation> <translation id="7139724024395191329">એમિરેટ</translation> +<translation id="7139892792842608322">પ્રાથમિક ટ્રે</translation> <translation id="714064300541049402">બાજુ 2 છબીને X અક્ષ પર ખસેડો</translation> <translation id="7152423860607593928">નંબર-14 (એન્વલપ)</translation> <translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=1{<ph name="PAYMENT_METHOD_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> વધુ}one{<ph name="PAYMENT_METHOD_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> વધુ}other{<ph name="PAYMENT_METHOD_PREVIEW" /> અને <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> વધુ}}</translation> @@ -1838,6 +1870,7 @@ <translation id="7251437084390964440">નેટવર્ક ગોઠવણી ONC માનકનું પાલન કરતી નથી. કદાચ ગોઠવણીના ભાગોને આયાત કરાશે નહીં. વધારાની વિગતો: <ph name="DEBUG_INFO" /></translation> +<translation id="7256634549594854023">પાછળની ટ્રે</translation> <translation id="725866823122871198"><ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> પર ખાનગી કનેક્શન સ્થાપિત કરી શકાતું નથી કારણ કે તમારા ઉપકરણની તારીખ અને સમય (<ph name="DATE_AND_TIME" />) અયોગ્ય છે.</translation> <translation id="7260504762447901703">ઍક્સેસ રદબાતલ કરો</translation> <translation id="7275334191706090484">મેનેજ કરેલા બુકમાર્ક</translation> @@ -1993,9 +2026,11 @@ <translation id="7734285854693414638">Google Formsમાં ઝડપથી કોઈ નવું ફોર્મ બનાવો</translation> <translation id="773466115871691567">હંમેશાં પેજનો <ph name="SOURCE_LANGUAGE" />માં અનુવાદ કરો</translation> <translation id="7740996059027112821">માનક</translation> +<translation id="77424286611022110">આ સાઇટ ઘૃણાસ્પદ અથવા ગેરમાર્ગે દોરનારી જાહેરાતો બતાવે છે. <ph name="LEARN_MORE_LINK_TEXT" /></translation> <translation id="774634243536837715">જોખમકારક કન્ટેન્ટ બ્લૉક કર્યું.</translation> <translation id="7751971323486164747">Chromeમાં ફૉન્ટના કદ અને ટાઇપફેસ કસ્ટમાઇઝ કરો</translation> <translation id="7752995774971033316">બિનસંચાલિત</translation> +<translation id="7755624218968747854">પ્રાથમિક રોલ</translation> <translation id="7757555340166475417">Dai-Pa-Kai</translation> <translation id="7758069387465995638">ફાયરવોલ અથવા એન્ટિવાયરસ સોફ્ટવેર એ કનેક્શન અવરોધિત કર્યું હોઈ શકે છે.</translation> <translation id="776110834126722255">ટાળેલી</translation> @@ -2073,6 +2108,7 @@ <translation id="8012116502927253373">{NUM_CARDS,plural, =1{આ કાર્ડ અને તેનું બિલિંગ સરનામું સાચવવામાં આવશે. જ્યારે <ph name="USER_EMAIL" />માં સાઇન ઇન કર્યું હશે ત્યારે તમે તેનો ઉપયોગ કરી શકશો.}one{આ કાર્ડ અને તેના બિલિંગ સરનામાં સાચવવામાં આવશે. જ્યારે <ph name="USER_EMAIL" />માં સાઇન ઇન કર્યું હશે ત્યારે તમે તેમનો ઉપયોગ કરી શકશો.}other{આ કાર્ડ અને તેના બિલિંગ સરનામાં સાચવવામાં આવશે. જ્યારે <ph name="USER_EMAIL" />માં સાઇન ઇન કર્યું હશે ત્યારે તમે તેમનો ઉપયોગ કરી શકશો.}}</translation> <translation id="8025119109950072390">આ સાઇટ પરના હુમલાખોરો તમારી વ્યક્તિગત માહિતી (ઉદાહરણ તરીકે, પાસવર્ડ, ફોન નંબર અથવા ક્રેડિટ કાર્ડ)ને દર્શાવવા અથવા સોફ્ટવેર ઇન્સ્ટૉલ કરવા જેવી જોખમી વસ્તુઓને કરવા માટે તમને છેતરવાનો પ્રયાસ કરી શકે છે.</translation> <translation id="8026334261755873520">બ્રાઉઝિંગ ડેટા સાફ કરો</translation> +<translation id="8027077570865220386">ટ્રે 15</translation> <translation id="8028698320761417183"><ph name="CREATE_GOOGLE_FORM_FOCUSED_FRIENDLY_MATCH_TEXT" />, Google Formsમાં ઝડપથી કોઈ નવું ફોર્મ બનાવવા માટે, પહેલાં Tab પછી Enter કી દબાવો</translation> <translation id="8028960012888758725">કાર્ય પછી ટ્રિમ કરો</translation> <translation id="8034522405403831421">આ પૃષ્ઠ <ph name="SOURCE_LANGUAGE" /> માં છે. શું તેનો અનુવાદ <ph name="TARGET_LANGUAGE" /> માં કરીએ?</translation> @@ -2131,6 +2167,7 @@ <translation id="8228419419708659934">બે પેજવાળો વ્યૂ</translation> <translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation> <translation id="8232343881378637145">પ્લૅટફૉર્મનું તાપમાન</translation> +<translation id="8233773197406738106">ફાઇલ તૈયાર કરી રહ્યાં છીએ</translation> <translation id="8238581221633243064">એક નવી છુપી વિંડોમાં પેજ ખોલો</translation> <translation id="8241707690549784388">તમારા દ્વારા દાખલ કરાયેલી વપરાયેલી માહિતી માટે આ પાનું તમે જોઈ રહ્યા છો. તે પૃષ્ઠ પર પાછા જવાથી એવી કોઈપણ ક્રિયા ફરીથી થઈ શકે છે જે તમે પહેલા કરી હતી. શું તમે ચાલુ રાખવા માંગો છો?</translation> <translation id="8241712895048303527">આ સાઇટ પર અવરોધિત કરો</translation> @@ -2148,6 +2185,7 @@ <translation id="8270242299912238708">PDF દસ્તાવેજો</translation> <translation id="8275952078857499577">આ સાઇટનો અનુવાદ કરવાની ઑફર કરશો નહીં</translation> <translation id="8277900682056760511">ચુકવણી માટેની હૅન્ડલર શીટ ખુલ્લી છે</translation> +<translation id="8280630997017109758">ટ્રે 11</translation> <translation id="8281084378435768645">મોટો-ફોટો</translation> <translation id="8282947398454257691">તમારા અનન્ય ઉપકરણ ઓળખકર્તાને જાણો</translation> <translation id="8284769179630993263">Chrome સેટિંગમાં Safe Browsing જેવી તમારી બીજી ઘણી સુવિધાઓ મેનેજ કરો</translation> @@ -2296,6 +2334,7 @@ <translation id="8807160976559152894">પ્રત્યેક પેજ પછી ટ્રિમ કરો</translation> <translation id="8816395686387277279"><ph name="UPDATE_CHROME_FOCUSED_FRIENDLY_MATCH_TEXT" />, તમારા Chrome સેટિંગમાંથી Chrome અપડેટ કરવા માટે Tab પછી Enter દબાવો</translation> <translation id="8820817407110198400">બુકમાર્ક</translation> +<translation id="882338992931677877">મેન્યુઅલ સ્લૉટ</translation> <translation id="883848425547221593">અન્ય બુકમાર્ક</translation> <translation id="884264119367021077">શિપિંગ સરનામું</translation> <translation id="884923133447025588">રદ કરવાની કોઈ મેકેનિઝમ મળી નથી.</translation> @@ -2354,6 +2393,7 @@ <translation id="9036306139374661733">શું માઇક્રોફોનની મંજૂરી આપીએ?</translation> <translation id="9038649477754266430">પૃષ્ઠોને વધુ ઝડપથી લોડ કરવા માટે પૂર્વાનુમાન સેવાનો ઉપયોગ કરો</translation> <translation id="9039213469156557790">વળી, આ પૃષ્ઠમાં અન્ય એવા સાધનો છે જે સુરક્ષિત નથી. ટ્રાંઝિટમાં હોવા પર અન્ય લોકો દ્વારા આ સાધનો જોઈ શકાય છે અને પૃષ્ઠનો વ્યવહાર બદલવા માટે હુમલાખોર દ્વારા સંશોધિત કરવામાં આવી શકે છે.</translation> +<translation id="9042617223719777575">વધુ ક્ષમતા</translation> <translation id="9044359186343685026">Touch IDનો ઉપયોગ કરો</translation> <translation id="9045525010788763347"><ph name="RESULT_MODIFIED_DATE" /> - <ph name="RESULT_PRODUCT_SOURCE" /></translation> <translation id="9049981332609050619">તમે <ph name="DOMAIN" /> સુધી પહોંચવાનો પ્રયાસ કર્યો, પરંતુ સર્વરે અમાન્ય પ્રમાણપત્ર પ્રસ્તુત કર્યું. </translation>
diff --git a/components/strings/components_strings_hy.xtb b/components/strings/components_strings_hy.xtb index 239269a..782372d 100644 --- a/components/strings/components_strings_hy.xtb +++ b/components/strings/components_strings_hy.xtb
@@ -1315,6 +1315,7 @@ <translation id="5252000469029418751">C7 (ծրար)</translation> <translation id="5254043433801397071">Օպտիմալացնել տպվելիք բովանդակությունը</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">Լուսանկարել</translation> <translation id="5265446478903775694">Կառավարել տվյալների գաղտնիությունը Google-ում</translation> <translation id="5266128565379329178">Ամրակար վերևում</translation> <translation id="5269225904387178860">Չորս անցք ներքևում</translation> @@ -1839,6 +1840,7 @@ <translation id="7153618581592392745">Նարդոս</translation> <translation id="7156870133441232244">Սերվերը պետք է թարմացվի TLS 1.2 կամ ավելի բարձր տարբերակով։</translation> <translation id="717330890047184534">Gaia ID՝</translation> +<translation id="7173920250514487165">Էկրանին ցուցադրվող խիստ անձնական բովանդակության լուսանկարում</translation> <translation id="7174545416324379297">Միավորված</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> և ուղարկման ևս <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> տարբերակ}one{<ph name="SHIPPING_OPTION_PREVIEW" /> և ուղարկման ևս <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> տարբերակ}other{<ph name="SHIPPING_OPTION_PREVIEW" /> և ուղարկման ևս <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> տարբերակ}}</translation> <translation id="7179323680825933600">Պահել և ինքնալրացնել վճարային տվյալները</translation> @@ -2098,6 +2100,7 @@ <translation id="7977538094055660992">Արտածման սարք</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">Կարող է հայցել վիրտուալ իրականության ձեր սարքերն ու տվյալները օգտագործելու թույլտվություն</translation> +<translation id="7984699858161118573">Ադմինիստրատորը խորհուրդ չի տալիս սքրինշոթներ կամ տեսագրություններ անել, քանի որ էկրանին խիստ անձնական բովանդակություն է ցուցադրված։</translation> <translation id="7984945080620862648">Այս պահին չեք կարող այցելել <ph name="SITE" />, քանի որ կայքը կոդավորված հավատարմագրեր է ուղարկել, որոնք Chrome-ը չի կարող մշակել: Ցանցային սխալներն ու հարձակումները սովորաբար ժամանակավոր բնույթ են կրում, ուստի, հավանաբար, այս էջը մատչելի կլինի ավելի ուշ:</translation> <translation id="79859296434321399">Լրացված իրականության ռեժիմում բովանդակությունը դիտելու համար տեղադրեք ARCore հավելվածը</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_iw.xtb b/components/strings/components_strings_iw.xtb index 8e37edf..462ae87 100644 --- a/components/strings/components_strings_iw.xtb +++ b/components/strings/components_strings_iw.xtb
@@ -1317,6 +1317,7 @@ <translation id="5252000469029418751">C7 (Envelope)</translation> <translation id="5254043433801397071">אופטימיזציה של תוכן ההדפסה</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">אני בכל זאת רוצה לצלם</translation> <translation id="5265446478903775694">ניהול הפרטיות שלך ב-Google</translation> <translation id="5266128565379329178">כריכה בקצה העליון</translation> <translation id="5269225904387178860">4 ניקובים בחלק התחתון</translation> @@ -1842,6 +1843,7 @@ <translation id="7153618581592392745">לבנדר</translation> <translation id="7156870133441232244">יש לשדרג את השרת ל-TLS 1.2 ואילך.</translation> <translation id="717330890047184534">מזהה GAIA:</translation> +<translation id="7173920250514487165">צילום תוכן סודי שמוצג במסך</translation> <translation id="7174545416324379297">משולבת</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> ועוד <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}two{<ph name="SHIPPING_OPTION_PREVIEW" /> ועוד <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}many{<ph name="SHIPPING_OPTION_PREVIEW" /> ועוד <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> ועוד <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation> <translation id="7179323680825933600">שמירה ומילוי של אמצעי תשלום</translation> @@ -2101,6 +2103,7 @@ <translation id="7977538094055660992">מכשיר פלט</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">האתר יכול לבקש הרשאה להשתמש בנתונים ובמכשירים של מציאות מדומה</translation> +<translation id="7984699858161118573">מנהל המערכת לא ממליץ לבצע צילומי מסך או הקלטות כי במסך מופיע תוכן סודי</translation> <translation id="7984945080620862648">לא ניתן לבקר כעת באתר <ph name="SITE" /> מכיוון שהאתר שלח אישורים משובשים ש-Chrome אינו יכול לעבד. שגיאות רשת ותקיפות מתרחשות בדרך כלל לזמן מוגבל, כך שסביר להניח שדף זה יפעל מאוחר יותר.</translation> <translation id="79859296434321399">כדי להציג תוכן של מציאות רבודה, צריך להתקין את ARCore</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_ja.xtb b/components/strings/components_strings_ja.xtb index 86b86128..ee0e5e0 100644 --- a/components/strings/components_strings_ja.xtb +++ b/components/strings/components_strings_ja.xtb
@@ -32,6 +32,7 @@ <translation id="1074497978438210769">保護されていない通信</translation> <translation id="1076113272840682464">Chrome でのダウンロードを管理</translation> <translation id="1080116354587839789">ウィンドウ幅に合わせる</translation> +<translation id="1081061862829655580">トレイ 19</translation> <translation id="1086953900555227778">Index-5x8</translation> <translation id="1088860948719068836">名義人名の追加</translation> <translation id="1089439967362294234">パスワードを変更</translation> @@ -70,6 +71,7 @@ <translation id="1209221128712833642">[フォームを作成] ボタンです。Enter キーを押すと、Google フォームで新しいフォームをすばやく作成します</translation> <translation id="121201262018556460"><ph name="DOMAIN" /> にアクセスしようとしましたが、サーバーから提示された証明書には脆弱な暗号鍵が含まれています。悪意のあるユーザーによって秘密鍵が破られた可能性があり、アクセスしようとしたサーバーとは異なるサーバーであるおそれがあります(悪意のあるユーザーと通信している可能性があります)。</translation> <translation id="1219129156119358924">システム セキュリティ</translation> +<translation id="1222060260947439312">右トレイ</translation> <translation id="1227224963052638717">不明なポリシー。</translation> <translation id="1228893227497259893">エンティティ識別子が正しくありません</translation> <translation id="1232569758102978740">無題</translation> @@ -91,11 +93,13 @@ <translation id="1257553931232494454">ズームレベル</translation> <translation id="1262388120645841613"><ph name="MANAGE_CHROME_SETTINGS_FOCUSED_FRIENDLY_MATCH_TEXT" /> です。Tab、Enter キーの順に押すと、Chrome の設定を管理します</translation> <translation id="1263231323834454256">リーディング リスト</translation> +<translation id="1264309058268477500">代替</translation> <translation id="1269096320618100013">[ユーザー補助設定を管理] ボタンです。Enter キーを押すと Chrome OS の設定でユーザー補助ツールをカスタマイズします</translation> <translation id="1269516672602708785">Google サイトで新しいサイトをすばやく作成します</translation> <translation id="1270502636509132238">受け取り方法</translation> <translation id="1281476433249504884">スタッカー 1</translation> <translation id="1285320974508926690">このサイトは翻訳しない</translation> +<translation id="1292571435393770077">トレイ 16</translation> <translation id="1292701964462482250">「パソコンにインストールされているソフトウェアが原因で、Chrome からインターネットに安全に接続することができません」(Windows パソコンのみ)</translation> <translation id="1294154142200295408">コマンドラインのバリエーション</translation> <translation id="129553762522093515">最近閉じたタブ</translation> @@ -203,6 +207,7 @@ <translation id="1592005682883173041">ローカルデータへのアクセス</translation> <translation id="1594030484168838125">選択</translation> <translation id="161042844686301425">シアン</translation> +<translation id="1611101756749861742">ロール 2</translation> <translation id="1620510694547887537">カメラ</translation> <translation id="1623104350909869708">このページで追加のダイアログが作成されないようにする</translation> <translation id="16338877384480380">Architecture-B</translation> @@ -275,14 +280,17 @@ <translation id="182139138257690338">自動ダウンロード</translation> <translation id="1821930232296380041">無効なリクエストまたはリクエスト パラメータです</translation> <translation id="1822540298136254167">アクセスしたウェブサイトと閲覧時間</translation> +<translation id="1824402189105105503">ロール 8</translation> <translation id="1826516787628120939">確認中</translation> <translation id="1834321415901700177">このサイトには有害なプログラムが含まれています</translation> <translation id="1838374766361614909">検索をクリア</translation> <translation id="1839551713262164453">ポリシーの値を検証できませんでした(エラーが発生しました)</translation> <translation id="1842969606798536927">お支払い</translation> <translation id="1856713167556118146">シークレット モードで行われないこと</translation> +<translation id="1863257867908022953">トレイ 12</translation> <translation id="1871208020102129563">プロキシは .pac スクリプト URL ではなく固定プロキシ サーバーを使用するように設定されています。</translation> <translation id="1871284979644508959">必須フィールド</translation> +<translation id="1875025161375567525">フォトトレイ</translation> <translation id="1875512691959384712">Google フォーム</translation> <translation id="187918866476621466">起動ページを開く</translation> <translation id="1883255238294161206">リストを折りたたむ</translation> @@ -308,6 +316,7 @@ <translation id="1962204205936693436"><ph name="DOMAIN" /> のブックマーク</translation> <translation id="1973335181906896915">シリアル化エラーです</translation> <translation id="1974060860693918893">詳細設定</translation> +<translation id="1975457531113383421">給紙トレイ</translation> <translation id="1975584088563498795">用紙受け 10</translation> <translation id="1978555033938440688">ファームウェアのバージョン</translation> <translation id="1988881251331415125">タイプミスでない場合は、<ph name="BEGIN_LINK" />接続診断をお試しください<ph name="END_LINK" />。</translation> @@ -321,6 +330,7 @@ <translation id="2025186561304664664">プロキシは自動設定になっています。</translation> <translation id="2025891858974379949">安全でないコンテンツ</translation> <translation id="2032962459168915086"><ph name="BEGIN_LINK" />プロキシとファイアウォールを確認する<ph name="END_LINK" /></translation> +<translation id="2036983605131262583">代替ロール</translation> <translation id="2042213636306070719">トレイ 7</translation> <translation id="204357726431741734">Google アカウントに保存したパスワードを使用するには、ログインしてください</translation> <translation id="2053111141626950936"><ph name="LANGUAGE" />のページは翻訳されません。</translation> @@ -476,6 +486,7 @@ <translation id="2546283357679194313">Cookie とサイトデータ</translation> <translation id="254947805923345898">ポリシーの値が無効です。</translation> <translation id="255002559098805027"><ph name="HOST_NAME" /> から無効な応答が送信されました。</translation> +<translation id="2552246211866555379">はがき</translation> <translation id="2552295903035773204">今後、画面ロックを使用してカードを確認する</translation> <translation id="2553853292994445426">セキュア DNS の設定を確認してください。接続できないセキュア DNS サーバーを設定している可能性があります。</translation> <translation id="2556876185419854533">編集の取り消し(&U)</translation> @@ -526,6 +537,7 @@ <translation id="2713444072780614174">白</translation> <translation id="2715612312510870559"><ph name="UPDATE_CREDIT_CARD_FOCUSED_FRIENDLY_MATCH_TEXT" /> です。Tab キー、Enter キーの順に押すと、Chrome の設定でお支払いとクレジット カードの情報を管理します</translation> <translation id="2721148159707890343">リクエストを正常に送信しました</translation> +<translation id="2726001110728089263">サイドトレイ</translation> <translation id="2728127805433021124">サーバーの証明書は脆弱な署名アルゴリズムを使用して署名されています。</translation> <translation id="2730326759066348565"><ph name="BEGIN_LINK" />接続診断ツールを実行する<ph name="END_LINK" /></translation> <translation id="2738330467931008676">受け取り場所の住所を選択</translation> @@ -557,6 +569,7 @@ <translation id="2880660355386638022">ウィンドウの配置</translation> <translation id="2881276955470682203">カードを保存しますか?</translation> <translation id="2882949212241984732">両観音折り</translation> +<translation id="2893773853358652045">ロール 4</translation> <translation id="2900528713135656174">予定を作成</translation> <translation id="2903493209154104877">住所</translation> <translation id="290376772003165898"><ph name="LANGUAGE" />のページではない場合</translation> @@ -615,6 +628,7 @@ <translation id="3096100844101284527">受け取り場所の住所を追加</translation> <translation id="3105172416063519923">アセット ID:</translation> <translation id="3107591622054137333"><ph name="BEGIN_LINK" />セキュア DNS の設定を確認する<ph name="END_LINK" /></translation> +<translation id="3108943290502734357">中央トレイ</translation> <translation id="3109728660330352905">このページを表示する権限がありません。</translation> <translation id="3113284927548439113">3 番目のシフト</translation> <translation id="3115874930288085374"><ph name="ENROLLMENT_DOMAIN" /> が、データをバックアップして、この <ph name="DEVICE_TYPE" />を返却するよう求めています。</translation> @@ -628,6 +642,7 @@ <translation id="3154506275960390542">このページのフォームは安全に送信されない可能性があります。送信中にデータが他者に閲覧されたり、悪意のあるユーザーによりデータが変更されてサーバーに別の内容が届いたりする可能性があります。</translation> <translation id="315504272643575312">あなたのアカウントは <ph name="MANAGER" /> によって管理されています。</translation> <translation id="3157931365184549694">復元</translation> +<translation id="3158539265159265653">ディスク</translation> <translation id="3162559335345991374">ご利用の Wi-Fi ネットワークでは、ログインページへのアクセスが必要な可能性があります。</translation> <translation id="3169472444629675720">Discover</translation> <translation id="3174168572213147020">島</translation> @@ -791,6 +806,7 @@ <translation id="3658742229777143148">変更履歴</translation> <translation id="3664782872746246217">キーワード:</translation> <translation id="3671540257457995106">サイズ変更を許可しますか?</translation> +<translation id="3675563144891642599">ロール 3</translation> <translation id="3676592649209844519">デバイス ID:</translation> <translation id="3677008721441257057">もしかして: <a href="#" id="dont-proceed-link"><ph name="DOMAIN" /></a></translation> <translation id="3678029195006412963">リクエストに署名できませんでした</translation> @@ -905,6 +921,7 @@ <translation id="4084120443451129199">検索モードです。「<ph name="KEYWORD_SUFFIX" />」を検索するには Enter キーを押してください。</translation> <translation id="4087296516249690906">[イベントを作成] ボタンです。Enter キーを押すと、Google カレンダーで新しいイベントをすばやく作成します</translation> <translation id="4088981014127559358">1 面の画像の Y 軸移動</translation> +<translation id="4089152113577680600">トレイ 14</translation> <translation id="4098354747657067197">偽のサイトにアクセスしようとしています</translation> <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" /> です。Tab、Enter キーの順に押すと、Chrome のフォントサイズと書体をカスタマイズします</translation> <translation id="4101413244023615925">テキストとグラフィック</translation> @@ -939,6 +956,7 @@ <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation> <translation id="4194250254487269611">現在、カードを保存できません</translation> <translation id="4196861286325780578">移動のやり直し(&R)</translation> +<translation id="4202554117186904723">ロール 5</translation> <translation id="4203896806696719780"><ph name="BEGIN_LINK" />ファイアウォールとウイルス対策の設定を確認する<ph name="END_LINK" /></translation> <translation id="4209092469652827314">大</translation> <translation id="4209166701302774460">アクセスしているサーバー <ph name="ORIGIN" /> では、サーバーへのすべてのリクエストにオリジン ポリシーを適用することが求められていますが、ポリシーがサーバーから送信されなかったため、ブラウザは <ph name="SITE" /> のリクエストを満たすことができません。オリジン ポリシーは、サイトのセキュリティやその他のプロパティを設定する目的でパブリッシャーが使用するものです。</translation> @@ -996,6 +1014,7 @@ <translation id="4314815835985389558">同期の管理</translation> <translation id="4318312030194671742">Paint Preview Compositor サービス</translation> <translation id="4318566738941496689">デバイスの名前とネットワーク アドレス</translation> +<translation id="4325600325087822253">トレイ 17</translation> <translation id="4325863107915753736">記事が見つかりませんでした</translation> <translation id="4326324639298822553">有効期限の「日」を確認してもう一度お試しください</translation> <translation id="4329871760342656885">ポリシー解析エラー: <ph name="ERROR" /></translation> @@ -1007,6 +1026,7 @@ <translation id="4346833872170306413">Roc-16K</translation> <translation id="4348834659292907206"><ph name="SITE" /> への接続は安全ではありません</translation> <translation id="4349531505348777662">偽のサイトでパスワードを入力しました。<ph name="WEBSITE_1" />、<ph name="WEBSITE_2" /> のほか、このパスワードを使用しているサイトで、パスワードを今すぐ変更することをおすすめします。</translation> +<translation id="4350629523305688469">多機能トレイ</translation> <translation id="4351060348582610152"><ph name="ORIGIN" /> が近くの Bluetooth デバイスのスキャンを求めています。検出済みのデバイスは次のとおりです。</translation> <translation id="4356973930735388585">このサイトを利用すると、悪意のあるユーザーによって、危険なプログラム(写真、パスワード、メッセージ、クレジット カード番号などの情報を盗み取るか削除するプログラム)がお使いのパソコンにインストールされる可能性があります。</translation> <translation id="4358059973562876591">DnsOverHttpsMode ポリシーに問題があるため、指定したテンプレートを適用できない可能性があります。</translation> @@ -1061,6 +1081,7 @@ <translation id="4515275063822566619">Chrome と Google アカウント(<ph name="ACCOUNT_EMAIL" />)に保存されているクレジット カードと住所です。[<ph name="BEGIN_LINK" />設定<ph name="END_LINK" />] で管理できます。</translation> <translation id="4517607026994743406">Comm-10(封筒)</translation> <translation id="4521157617044179198"><ph name="WIDTH" /> × <ph name="HEIGHT" /> mm(<ph name="ORIENTATION" />)</translation> +<translation id="4521916730539354575">左トレイ</translation> <translation id="4522570452068850558">詳細</translation> <translation id="4524138615196389145">今後 WebAuthn を使用して、カードの確認をより迅速に行います</translation> <translation id="4524805452350978254">カードを管理</translation> @@ -1175,6 +1196,7 @@ <translation id="4889420713887366944">シークレット ウィンドウを開くボタンです。Enter キーを押すと、新しいシークレット ウィンドウを開いてシークレット モードでブラウジングします</translation> <translation id="4892518386797173871">背面</translation> <translation id="4895877746940133817"><ph name="TYPE_1" />、<ph name="TYPE_2" />、<ph name="TYPE_3" /></translation> +<translation id="4900217275619098670">ロール 9</translation> <translation id="4901778704868714008">保存...</translation> <translation id="4913987521957242411">パンチ(左上)</translation> <translation id="4918221908152712722"><ph name="APP_NAME" /> をインストール(ダウンロードは不要です)</translation> @@ -1223,6 +1245,7 @@ <translation id="5068524481479508725">A10</translation> <translation id="5068778127327928576">{NUM_COOKIES,plural, =1{(1 個が使用中)}other{(# 個が使用中)}}</translation> <translation id="5070335125961472645"><ph name="BEGIN_LINK" />プロキシ アドレスを確認する<ph name="END_LINK" /></translation> +<translation id="5070838744279127212">ロール 10</translation> <translation id="507130231501693183">用紙受け 4</translation> <translation id="5087286274860437796">サーバーの証明書が現在有効ではありません。</translation> <translation id="5087580092889165836">カードを追加</translation> @@ -1235,6 +1258,7 @@ <translation id="5097501891273180634">A2</translation> <translation id="5108881358339761672">サイトは安全ではありません</translation> <translation id="5112422516732747637">A5</translation> +<translation id="5114288597538800140">トレイ 18</translation> <translation id="5114987907971894280">バーチャル リアリティ</translation> <translation id="5115216390227830982">European-Edp</translation> <translation id="5115232566827194440">制限付き管理対象ゲスト セッションのオーバーライド</translation> @@ -1268,8 +1292,10 @@ <translation id="5201306358585911203">このページに埋め込まれているページの内容</translation> <translation id="5205222826937269299">名前は必須です</translation> <translation id="5209518306177824490">SHA-1 指紋</translation> +<translation id="5209670883520018268">トレイ 20</translation> <translation id="5215116848420601511">Google Pay のお支払い方法と住所</translation> <translation id="5215363486134917902">Folio-Sp</translation> +<translation id="521659676233207110">トレイ 13</translation> <translation id="5222812217790122047">メールアドレスは必須です</translation> <translation id="5230733896359313003">配送先住所</translation> <translation id="5230815978613972521">B8</translation> @@ -1280,6 +1306,7 @@ <translation id="5252000469029418751">C7(封筒)</translation> <translation id="5254043433801397071">印刷コンテンツの最適化</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">このままキャプチャする</translation> <translation id="5265446478903775694">Google でのプライバシーを管理します</translation> <translation id="5266128565379329178">製本(上綴じ)</translation> <translation id="5269225904387178860">4 穴パンチ(下)</translation> @@ -1473,6 +1500,7 @@ <translation id="5967592137238574583">連絡先情報の編集</translation> <translation id="5967867314010545767">履歴から削除</translation> <translation id="5968793460449681917">アクセスするたびに確認</translation> +<translation id="5974052231147553524">ロール 6</translation> <translation id="5975083100439434680">縮小する</translation> <translation id="5979084224081478209">パスワードを確認</translation> <translation id="5980920751713728343">Index-3x5</translation> @@ -1627,11 +1655,13 @@ <translation id="6499038740797743453">パスワードを再設定しますか?</translation> <translation id="6502991525169604759">変更前のバージョン</translation> <translation id="6505563257409036437">シークレット ウィンドウを閉じる</translation> +<translation id="6506959208958864820">封筒</translation> <translation id="6508722015517270189">Chrome を再起動する</translation> <translation id="6513005815064132016">カメラ位置の追跡を要求できる</translation> <translation id="6517596291481585650">警告: このポリシーはリストでないため、ポリシーで指定されているとおりにリストとして統合されませんでした。</translation> <translation id="6518133107902771759">確認</translation> <translation id="6521745193039995384">無効</translation> +<translation id="6529173248185917884">ロール 7</translation> <translation id="6529602333819889595">削除のやり直し(&R)</translation> <translation id="6545864417968258051">Bluetooth のスキャン</translation> <translation id="6547208576736763147">2 穴パンチ(左)</translation> @@ -1666,6 +1696,7 @@ <translation id="6652101503459149953">Windows Hello を使用</translation> <translation id="6657585470893396449">パスワード</translation> <translation id="6660413144148052430">現在地情報</translation> +<translation id="6662457027866368246">ロール 1</translation> <translation id="666259744093848177">(x86_64 翻訳)</translation> <translation id="6665553082534466207">3 穴パンチ(右)</translation> <translation id="6671697161687535275">Chromium から候補を削除してもよろしいですか?</translation> @@ -1712,6 +1743,7 @@ <translation id="6846340164947227603">仮想カード番号を使用...</translation> <translation id="6852204201400771460">アプリを再読み込みしますか?</translation> <translation id="6865412394715372076">現在、このカードを確認できません</translation> +<translation id="6873456682041376666">上トレイ</translation> <translation id="6874604403660855544">追加のやり直し(&R)</translation> <translation id="6881240511396774766">新しい Google ドキュメントをすばやく作成します</translation> <translation id="6883221904761970440">保護されたお支払い認証情報の認証シートは閉じています</translation> @@ -1792,12 +1824,14 @@ <translation id="7135130955892390533">ステータスを表示</translation> <translation id="7138472120740807366">配達方法</translation> <translation id="7139724024395191329">管轄区域</translation> +<translation id="7139892792842608322">メイントレイ</translation> <translation id="714064300541049402">2 面の画像の X 軸移動</translation> <translation id="7152423860607593928">Number-14(封筒)</translation> <translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=1{<ph name="PAYMENT_METHOD_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> 件)}other{<ph name="PAYMENT_METHOD_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" /> 件)}}</translation> <translation id="7153618581592392745">ラベンダー</translation> <translation id="7156870133441232244">サーバーを TLS 1.2 以降にアップグレードする必要があります。</translation> <translation id="717330890047184534">GAIA ID:</translation> +<translation id="7173920250514487165">スクリーン キャプチャの対象に機密コンテンツが含まれています。</translation> <translation id="7174545416324379297">統合された値</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> 件)}other{<ph name="SHIPPING_OPTION_PREVIEW" />(他 <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> 件)}}</translation> <translation id="7179323680825933600">お支払い方法の保存と入力</translation> @@ -1830,6 +1864,7 @@ <translation id="7251437084390964440">ネットワーク設定が ONC 標準に準拠していません。設定の一部がインポートされない可能性があります。 詳細: <ph name="DEBUG_INFO" /></translation> +<translation id="7256634549594854023">背面トレイ</translation> <translation id="725866823122871198">パソコンの日時(<ph name="DATE_AND_TIME" />)が正しくないため、<ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> へのプライベート接続を確立できません。</translation> <translation id="7260504762447901703">アクセス権を取り消します</translation> <translation id="7275334191706090484">管理対象のブックマーク</translation> @@ -1985,9 +2020,11 @@ <translation id="7734285854693414638">Google フォームで新しいフォームをすばやく作成します</translation> <translation id="773466115871691567"><ph name="SOURCE_LANGUAGE" />のページを常に翻訳する</translation> <translation id="7740996059027112821">標準</translation> +<translation id="77424286611022110">このサイトでは煩わしい広告または誤解を招く広告が表示されます。<ph name="LEARN_MORE_LINK_TEXT" /></translation> <translation id="774634243536837715">危険なコンテンツがブロックされました。</translation> <translation id="7751971323486164747">Chrome のフォントサイズと書体をカスタマイズします</translation> <translation id="7752995774971033316">管理されていません</translation> +<translation id="7755624218968747854">メインロール</translation> <translation id="7757555340166475417">Dai-Pa-Kai</translation> <translation id="7758069387465995638">ファイアウォールまたはウイルス対策ソフトウェアによって接続がブロックされた可能性があります。</translation> <translation id="776110834126722255">廃止</translation> @@ -2054,6 +2091,7 @@ <translation id="7977538094055660992">出力デバイス</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">バーチャル リアリティ デバイスとデータの使用を要求できる</translation> +<translation id="7984699858161118573">画面上に機密コンテンツがあるため、スクリーンショットの撮影や録画は管理者によって推奨されていません。</translation> <translation id="7984945080620862648"><ph name="SITE" /> から、Chrome で処理できないスクランブル化された認証情報が返されたため、現在このサイトにはアクセスできません。通常、ネットワーク エラーや不正な操作は一時的なものです。少し時間をおくと、またページにアクセスできるようになる可能性があります。</translation> <translation id="79859296434321399">拡張現実(AR)コンテンツを表示するには ARCore をインストールしてください</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation> @@ -2065,6 +2103,7 @@ <translation id="8012116502927253373">{NUM_CARDS,plural, =1{このカードと請求先住所は保存され、<ph name="USER_EMAIL" /> にログインすると使用できます。}other{これらのカードと請求先住所は保存され、<ph name="USER_EMAIL" /> にログインすると使用できます。}}</translation> <translation id="8025119109950072390">このサイトを利用すると、悪意のあるユーザーによって、ソフトウェアのインストールや個人情報(例: パスワード、電話番号、クレジット カード番号)の入力などの危険な操作を行うよう誘導される可能性があります。</translation> <translation id="8026334261755873520">閲覧履歴データの削除</translation> +<translation id="8027077570865220386">トレイ 15</translation> <translation id="8028698320761417183"><ph name="CREATE_GOOGLE_FORM_FOCUSED_FRIENDLY_MATCH_TEXT" /> です。Tab キー、Enter キーの順に押すと、Google フォームで新しいフォームをすばやく作成します</translation> <translation id="8028960012888758725">トリミング(ジョブ後)</translation> <translation id="8034522405403831421">このページの言語は<ph name="SOURCE_LANGUAGE" />です。<ph name="TARGET_LANGUAGE" />に翻訳しますか?</translation> @@ -2123,6 +2162,7 @@ <translation id="8228419419708659934">2 ページ表示</translation> <translation id="822964464349305906"><ph name="TYPE_1" />、<ph name="TYPE_2" /></translation> <translation id="8232343881378637145">プラットフォームの温度</translation> +<translation id="8233773197406738106">ファイルを準備しています</translation> <translation id="8238581221633243064">ページを新しいシークレット タブで開く</translation> <translation id="8241707690549784388">検索しているページは、入力した情報を使用しています。このページに戻った場合、操作のやり直しが発生する可能性があります。続行しますか?</translation> <translation id="8241712895048303527">このサイトでブロック</translation> @@ -2140,6 +2180,7 @@ <translation id="8270242299912238708">PDF ドキュメント</translation> <translation id="8275952078857499577">このサイトを翻訳するか尋ねない</translation> <translation id="8277900682056760511">支払いハンドラのシートが開いています</translation> +<translation id="8280630997017109758">トレイ 11</translation> <translation id="8281084378435768645">Large-Photo</translation> <translation id="8282947398454257691">デバイス固有の ID の認識</translation> <translation id="8284769179630993263">Chrome の設定でセーフ ブラウジングなどを管理する</translation> @@ -2289,6 +2330,7 @@ <translation id="8807160976559152894">トリミング(ページ単位)</translation> <translation id="8816395686387277279"><ph name="UPDATE_CHROME_FOCUSED_FRIENDLY_MATCH_TEXT" /> です。Tab キー、Enter キーの順に押すと、Chrome の設定で Chrome を更新します</translation> <translation id="8820817407110198400">ブックマーク</translation> +<translation id="882338992931677877">手動スロット</translation> <translation id="883848425547221593">その他のブックマーク</translation> <translation id="884264119367021077">配送先住所</translation> <translation id="884923133447025588">取り消し機構が見つかりません。</translation> @@ -2347,6 +2389,7 @@ <translation id="9036306139374661733">マイクの使用を許可しますか?</translation> <translation id="9038649477754266430">予測サービスを使用してページをより迅速に読み込む</translation> <translation id="9039213469156557790">加えて、このページには安全でない他のリソースが含まれています。このリソースは送信中に他のユーザーから見られる可能性があります。また、悪意のあるユーザーによって改変されページの動作が変わる可能性もあります。</translation> +<translation id="9042617223719777575">大容量</translation> <translation id="9044359186343685026">Touch ID を使用</translation> <translation id="9045525010788763347"><ph name="RESULT_MODIFIED_DATE" /> - <ph name="RESULT_PRODUCT_SOURCE" /></translation> <translation id="9049981332609050619"><ph name="DOMAIN" /> にアクセスしようとしましたが、サーバーから無効な証明書が提示されました。</translation>
diff --git a/components/strings/components_strings_kk.xtb b/components/strings/components_strings_kk.xtb index d2f64b3..22cb1a3 100644 --- a/components/strings/components_strings_kk.xtb +++ b/components/strings/components_strings_kk.xtb
@@ -1314,6 +1314,7 @@ <translation id="5252000469029418751">C7 (Envelope)</translation> <translation id="5254043433801397071">Баспа мазмұнын оңтайландыру</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">Бәрібір түсіру</translation> <translation id="5265446478903775694">Google-дағы құпиялылықты басқару</translation> <translation id="5266128565379329178">Жоғарғы жағын байлау</translation> <translation id="5269225904387178860">Төменгі жағын төрт рет тесу</translation> @@ -1838,6 +1839,7 @@ <translation id="7153618581592392745">Ақшыл көк</translation> <translation id="7156870133441232244">Серверде TLS 1.2 протоколы немесе одан кейінгі нұсқасы орнатылуы тиіс.</translation> <translation id="717330890047184534">GAIA идентификаторы:</translation> +<translation id="7173920250514487165">Экрандағы құпия мазмұнды түсіру</translation> <translation id="7174545416324379297">Біріктірілген</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> және тағы <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> және тағы <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation> <translation id="7179323680825933600">Төлеу әдістерін сақтау және толтыру</translation> @@ -2097,6 +2099,7 @@ <translation id="7977538094055660992">Шығару құрылғысы</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">Виртуалды шындық құрылғыларын және деректерді пайдалануға рұқсат сұрай алады.</translation> +<translation id="7984699858161118573">Экрандағы құпия мазмұнға байланысты әкімші суретке түсіруді немесе бейнеге жазуды ұсынбайды.</translation> <translation id="7984945080620862648">Қазір <ph name="SITE" /> сайтына кіру мүмкін емес, себебі веб-сайт Chrome өңдей алмайтын шифрланған есептік деректерді жіберді. Желі қателері мен шабуылдары әдетте уақытша болғандықтан, бұл бет кейінірек жұмыс істеуі мүмкін.</translation> <translation id="79859296434321399">Толықтырылған шындық мазмұнын көру үшін ARCore платформасын орнатыңыз</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_ko.xtb b/components/strings/components_strings_ko.xtb index 9c3f67e..eb15531 100644 --- a/components/strings/components_strings_ko.xtb +++ b/components/strings/components_strings_ko.xtb
@@ -1306,6 +1306,7 @@ <translation id="5252000469029418751">C7(봉투)</translation> <translation id="5254043433801397071">인쇄 콘텐츠 최적화</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">무시하고 캡처</translation> <translation id="5265446478903775694">Google의 개인 정보 보호 설정 관리</translation> <translation id="5266128565379329178">상단 바인드</translation> <translation id="5269225904387178860">하단 4공 펀칭</translation> @@ -1830,6 +1831,7 @@ <translation id="7153618581592392745">라벤더색</translation> <translation id="7156870133441232244">서버를 TLS 1.2 이상으로 업그레이드해야 합니다.</translation> <translation id="717330890047184534">GAIA ID:</translation> +<translation id="7173920250514487165">화면의 기밀 콘텐츠 캡처</translation> <translation id="7174545416324379297">병합됨</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />개}other{<ph name="SHIPPING_OPTION_PREVIEW" /> 외 <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />개}}</translation> <translation id="7179323680825933600">결제 수단 저장 및 자동 입력</translation> @@ -2088,6 +2090,7 @@ <translation id="7977538094055660992">출력 기기</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">가상 현실 기기 및 데이터의 사용을 요청할 수 있음</translation> +<translation id="7984699858161118573">화면에 기밀 콘텐츠가 표시되어 있으므로 관리자가 스크린샷을 찍거나 녹화하도록 권장하지 않습니다.</translation> <translation id="7984945080620862648">현재 <ph name="SITE" />에서 Chrome이 처리할 수 없는 암호화된 자격증명 정보를 전송했기 때문에 방문할 수 없습니다. 네트워크 오류와 공격은 대부분 일시적이므로 잠시 후 페이지가 정상화될 것입니다.</translation> <translation id="79859296434321399">증강 현실 콘텐츠를 보려면 ARCore를 설치하세요.</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_sk.xtb b/components/strings/components_strings_sk.xtb index bb7bad8..d16d6c6f 100644 --- a/components/strings/components_strings_sk.xtb +++ b/components/strings/components_strings_sk.xtb
@@ -1059,7 +1059,7 @@ <translation id="4465818729556336129">Tento dokument je dôverný a správca jeho vytlačenie neodporúča.</translation> <translation id="4476953670630786061">Tento formulár nie je zabezpečený. Automatické dopĺňanie bolo vypnuté.</translation> <translation id="4477350412780666475">Ďalšia stopa</translation> -<translation id="4481251927743463293">Čo robí režim inkognito</translation> +<translation id="4481251927743463293">Čo režim inkognito robí</translation> <translation id="4481394504112738036">Dôverný súbor</translation> <translation id="4482953324121162758">Tento web nebude preložený.</translation> <translation id="4490717597759821841">A7</translation> @@ -1164,11 +1164,11 @@ <translation id="4819347708020428563">Chcete upraviť poznámky v predvolenom zobrazení?</translation> <translation id="4825496307559726072"><ph name="CREATE_GOOGLE_SHEET_FOCUSED_FRIENDLY_MATCH_TEXT" />, postupným stlačením klávesov Tab a Enter vytvoríte rýchlym spôsobom novú tabuľku Google</translation> <translation id="4825507807291741242">Pôsobivé</translation> -<translation id="4827402517081186284">Režim inkognito vás na internete nedokáže úplne skryť: +<translation id="4827402517081186284">Režim inkognito neznamená vašu neviditeľnosť na internete: <ph name="BEGIN_LIST" /> <ph name="LIST_ITEM" />weby vedia o vašej návšteve;<ph name="END_LIST_ITEM" /> - <ph name="LIST_ITEM" />zamestnanci alebo školy môžu sledovať aktivitu prehliadania;<ph name="END_LIST_ITEM" /> - <ph name="LIST_ITEM" />poskytovatelia internetu môžu monitorovať webovú premávku.<ph name="END_LIST_ITEM" /> + <ph name="LIST_ITEM" />zamestnávateľ či škola môže sledovať vašu aktivitu prehliadania;<ph name="END_LIST_ITEM" /> + <ph name="LIST_ITEM" />poskytovateľ internetu môže monitorovať webovú premávku.<ph name="END_LIST_ITEM" /> <ph name="END_LIST" /></translation> <translation id="483241715238664915">Zapnúť upozornenia</translation> <translation id="4838327282952368871">Rozprávkové</translation>
diff --git a/components/strings/components_strings_sq.xtb b/components/strings/components_strings_sq.xtb index 8716c84..3809564 100644 --- a/components/strings/components_strings_sq.xtb +++ b/components/strings/components_strings_sq.xtb
@@ -1312,6 +1312,7 @@ <translation id="5252000469029418751">C7 (Zarf)</translation> <translation id="5254043433801397071">Optimizo përmbajtjen e printimit</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">Shkrepe gjithsesi</translation> <translation id="5265446478903775694">Menaxho privatësinë time në Google</translation> <translation id="5266128565379329178">Lidhje lart</translation> <translation id="5269225904387178860">Katër shpime poshtë</translation> @@ -1835,6 +1836,7 @@ <translation id="7153618581592392745">Vjollcë e çelur</translation> <translation id="7156870133441232244">Serveri duhet të përmirësohet në versionin TLS 1.2 ose një version të mëvonshëm.</translation> <translation id="717330890047184534">ID-ja e Gaia:</translation> +<translation id="7173920250514487165">Shkrep përmbajtje konfidenciale në ekranin tënd</translation> <translation id="7174545416324379297">E shkrirë</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> dhe <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> tjetër}other{<ph name="SHIPPING_OPTION_PREVIEW" /> dhe <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> të tjera}}</translation> <translation id="7179323680825933600">Ruaj dhe plotëso mënyrat e pagesës</translation> @@ -2094,6 +2096,7 @@ <translation id="7977538094055660992">Pajisja e daljes</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">Mund të kërkojë të përdorë të dhënat dhe pajisjet e realitetit virtual</translation> +<translation id="7984699858161118573">Administratori nuk rekomandon nxjerrjen e pamjeve të ekranit apo të regjistrimeve për shkak të përmbajtjes konfidenciale në ekran</translation> <translation id="7984945080620862648">Nuk mund ta vizitosh <ph name="SITE" /> tani sepse sajti i uebit dërgoi kredenciale të koduara që nuk mund të përpunohen nga Chrome. Gabimet dhe sulmet në rrjet zakonisht janë të përkohshme, kështu që kjo faqe ndoshta do të punojë më vonë.</translation> <translation id="79859296434321399">Për të parë përmbajtje realiteti të zgjeruar, instalo ARCore</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_sw.xtb b/components/strings/components_strings_sw.xtb index a903d5c..26d25317 100644 --- a/components/strings/components_strings_sw.xtb +++ b/components/strings/components_strings_sw.xtb
@@ -1314,6 +1314,7 @@ <translation id="5252000469029418751">C7 (Bahasha)</translation> <translation id="5254043433801397071">Boresha maudhui ya kuchapisha</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">Nasa licha ya hayo</translation> <translation id="5265446478903775694">Dhibiti faragha yangu kwenye Google</translation> <translation id="5266128565379329178">Unganisha juu</translation> <translation id="5269225904387178860">Toboa mara nne chini</translation> @@ -1838,6 +1839,7 @@ <translation id="7153618581592392745">Urujuani</translation> <translation id="7156870133441232244">Seva inahitaji kupata toleo la TLS 1.2 au jipya zaidi.</translation> <translation id="717330890047184534">Kitambulisho cha Gaia</translation> +<translation id="7173920250514487165">Kunasa maudhui ya siri kwenye skrini yako</translation> <translation id="7174545416324379297">Vimeunganishwa</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> na nyingine <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> na nyingine <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation> <translation id="7179323680825933600">Hifadhi na Ujaze Njia za Kulipa</translation> @@ -2095,6 +2097,7 @@ <translation id="7977538094055660992">Kifaa cha kutoa maudhui</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">Inaweza kuomba ruhusa ya kutumia data na vifaa vya uhalisia pepe</translation> +<translation id="7984699858161118573">Msimamizi hapendekezi kupiga picha za skrini au kurekodi kwa sababu kuna maudhui ya siri kwenye skrini yako</translation> <translation id="7984945080620862648">Huwezi kutembelea <ph name="SITE" /> sasa hivi kwa sababu tovuti ilituma kitambulisho kilichoharibika ambacho Chrome haiwezi kuchakata. Hitilafu na uvamizi wa mtandao kwa kawaida huwa vya muda, kwa hivyo ukurasa huu huenda utafanya kazi baadaye.</translation> <translation id="79859296434321399">Sakinisha ARCore ili uangalie maudhui ya uhalisia ulioboreshwa</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_ta.xtb b/components/strings/components_strings_ta.xtb index f2913dc..63d4c18 100644 --- a/components/strings/components_strings_ta.xtb +++ b/components/strings/components_strings_ta.xtb
@@ -32,6 +32,7 @@ <translation id="1074497978438210769">பாதுகாப்பற்றது</translation> <translation id="1076113272840682464">Chromeமில் பதிவிறக்கியவற்றை நிர்வகிக்கவும்</translation> <translation id="1080116354587839789">அகலத்திற்குப் பொருத்து</translation> +<translation id="1081061862829655580">டிரே 19</translation> <translation id="1086953900555227778">Index-5x8</translation> <translation id="1088860948719068836">கார்டிலுள்ள பெயரைச் சேர்க்கவும்</translation> <translation id="1089439967362294234">கடவுச்சொல்லை மாற்று</translation> @@ -70,6 +71,7 @@ <translation id="1209221128712833642">படிவத்தை உருவாக்குவதற்கான பட்டன். Google Formsஸில் புதிய படிவத்தை விரைவாக உருவாக்க Enter பட்டனை அழுத்துங்கள்</translation> <translation id="121201262018556460">நீங்கள் <ph name="DOMAIN" /> ஐ அடைய முயற்சித்தீர்கள் ஆனால் சேவையகம் ஒரு வலுவற்ற விசை கொண்ட சான்றிதழை வழங்கியது. தனிப்பட்ட விசையை தீங்கிழைப்பவர் களவாடி இருப்பதால், சேவையகம் நீங்கள் எதிர்பார்த்த (தீங்கிழைப்பவருடன் நீங்கள் தகவல் பரிமாற்றம் செய்துகொண்டிருக்கலாம்) சேவையகமாக இல்லாமல் இருக்கலாம்.</translation> <translation id="1219129156119358924">முறைமைப் பாதுகாப்பு</translation> +<translation id="1222060260947439312">வலதுபக்க டிரே</translation> <translation id="1227224963052638717">அறியாத கொள்கை.</translation> <translation id="1228893227497259893">தவறான உட்பொருள் அடையாளங்காட்டி</translation> <translation id="1232569758102978740">தலைப்பிடாதது</translation> @@ -91,11 +93,13 @@ <translation id="1257553931232494454">அளவுமாற்ற நிலைகள்</translation> <translation id="1262388120645841613"><ph name="MANAGE_CHROME_SETTINGS_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chrome அமைப்புகளை நிர்வகிக்க, Tab பட்டனை அழுத்திவிட்டு Enter பட்டனை அழுத்துங்கள்</translation> <translation id="1263231323834454256">வாசிப்புப் பட்டியல்</translation> +<translation id="1264309058268477500">மாற்று</translation> <translation id="1269096320618100013">அணுகல்தன்மை அமைப்புகளை நிர்வகிக்கும் பட்டன். Chrome OS அமைப்புகளில் அணுகல்தன்மைக் கருவிகளைப் பிரத்தியேகமாக்க, Enter பட்டனை அழுத்துங்கள்.</translation> <translation id="1269516672602708785">Google Sitesஸில் புதிய தளத்தை விரைவாக உருவாக்கும்</translation> <translation id="1270502636509132238">பிக்அப் முறை</translation> <translation id="1281476433249504884">ஸ்டேக்கர் 1</translation> <translation id="1285320974508926690">இந்த தளத்தை எப்போதும் மொழிபெயர்க்க வேண்டாம்</translation> +<translation id="1292571435393770077">டிரே 16</translation> <translation id="1292701964462482250">"உங்கள் கம்ப்யூட்டரில் உள்ள மென்பொருள் இணையத்துடன் பாதுகாப்பாக இணைவதிலிருந்து Chromeமைத் தடுக்கிறது" (Windows கம்ப்யூட்டர்கள் மட்டும்)</translation> <translation id="1294154142200295408">கட்டளை வரி மாற்று வடிவங்கள்</translation> <translation id="129553762522093515">சமீபத்தில் மூடியவை</translation> @@ -203,6 +207,7 @@ <translation id="1592005682883173041">அகத் தரவு அணுகல்</translation> <translation id="1594030484168838125">தேர்வுசெய்</translation> <translation id="161042844686301425">சியான்</translation> +<translation id="1611101756749861742">ரோல் 2</translation> <translation id="1620510694547887537">கேமரா</translation> <translation id="1623104350909869708">கூடுதல் உரையாடல்களை உருவாக்குவதிலிருந்து இந்தப் பக்கத்தைத் தடு</translation> <translation id="16338877384480380">Architecture-B</translation> @@ -279,14 +284,17 @@ <translation id="182139138257690338">தானியங்குப் பதிவிறக்கங்கள்</translation> <translation id="1821930232296380041">தவறான கோரிக்கை அல்லது கோரிக்கை அளவுருக்கள்</translation> <translation id="1822540298136254167">நீங்கள் பார்வையிட்ட இணையதளங்களும் அவற்றில் செலவழித்த நேரமும்</translation> +<translation id="1824402189105105503">ரோல் 8</translation> <translation id="1826516787628120939">சரிபார்க்கிறது</translation> <translation id="1834321415901700177">இந்தத் தளத்தில் தீங்கிழைக்கும் நிரல்கள் உள்ளன</translation> <translation id="1838374766361614909">தேடலை அழி</translation> <translation id="1839551713262164453">கொள்கை மதிப்புகளின் சரிபார்ப்பு பிழைகளுடன் தோல்வியில் முடிந்தது.</translation> <translation id="1842969606798536927">பணம் செலுத்துக</translation> <translation id="1856713167556118146">மறைநிலையில் செய்யப்படாதவை:</translation> +<translation id="1863257867908022953">டிரே 12</translation> <translation id="1871208020102129563">நிலையான ப்ராக்ஸி சேவையகங்களைப் பயன்படுத்த ப்ராக்ஸி அமைக்கப்பட்டுள்ளது, .pac ஸ்கிரிப்ட் URL அல்ல.</translation> <translation id="1871284979644508959">அவசியமானவை</translation> +<translation id="1875025161375567525">பட டிரே</translation> <translation id="1875512691959384712">Google Forms</translation> <translation id="187918866476621466">துவக்கப் பக்கங்களைத் திற</translation> <translation id="1883255238294161206">பட்டியலைச் சுருக்கு</translation> @@ -312,6 +320,7 @@ <translation id="1962204205936693436"><ph name="DOMAIN" /> புக்மார்க்குகள்</translation> <translation id="1973335181906896915">தொடராக்க பிழை</translation> <translation id="1974060860693918893">மேம்பட்டவை</translation> +<translation id="1975457531113383421">இன்புட் டிரே</translation> <translation id="1975584088563498795">அஞ்சல் பெட்டி 10</translation> <translation id="1978555033938440688">நிலைப்பொருளின் பதிப்பு</translation> <translation id="1988881251331415125">எழுத்துப்பிழை இல்லையெனில் <ph name="BEGIN_LINK" />இணைப்புநிலை சரிபார்ப்பை இயக்கிப் பார்க்கவும்<ph name="END_LINK" />.</translation> @@ -325,6 +334,7 @@ <translation id="2025186561304664664">ப்ராக்ஸி, தானியங்கி உள்ளமைவுக்கு அமைக்கப்பட்டுள்ளது</translation> <translation id="2025891858974379949">பாதுகாப்பற்ற உள்ளடக்கம்</translation> <translation id="2032962459168915086"><ph name="BEGIN_LINK" />ப்ராக்ஸி மற்றும் ஃபயர்வாலைச் சரிபார்த்தல்<ph name="END_LINK" /></translation> +<translation id="2036983605131262583">மாற்று ரோல்</translation> <translation id="2042213636306070719">தட்டு 7</translation> <translation id="204357726431741734">உங்கள் Google கணக்கில் சேமிக்கப்பட்டுள்ள கடவுச்சொற்களைப் பயன்படுத்த உள்நுழைக</translation> <translation id="2053111141626950936"><ph name="LANGUAGE" /> மொழியில் உள்ள பக்கங்கள் மொழிபெயர்க்கப்படாது.</translation> @@ -480,6 +490,7 @@ <translation id="2546283357679194313">குக்கீகளும் தள தரவும்</translation> <translation id="254947805923345898">கொள்கையின் மதிப்பு சரியானதில்லை.</translation> <translation id="255002559098805027"><ph name="HOST_NAME" /> தவறான பதிலை அனுப்பியது.</translation> +<translation id="2552246211866555379">ஹாகாகி</translation> <translation id="2552295903035773204">இனி கார்டுகளை உறுதிப்படுத்த திரைப் பூட்டைப் பயன்படுத்து</translation> <translation id="2553853292994445426">உங்கள் பாதுகாப்பான DNS அமைப்புகளைச் சரிபாருங்கள். நீங்கள் பாதுகாப்பான DNS சேவையகத்தை உள்ளமைத்து இருக்கக்கூடும், ஆனால் அதன் இணைப்புகள் தோல்வியடைகின்றன.</translation> <translation id="2556876185419854533">&திருத்தலைச் செயல்தவிர்</translation> @@ -530,6 +541,7 @@ <translation id="2713444072780614174">வெள்ளை</translation> <translation id="2715612312510870559"><ph name="UPDATE_CREDIT_CARD_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chrome அமைப்புகளில் பேமெண்ட்டுகள், கிரெடிட் கார்டு ஆகியவை குறித்த தகவலை நிர்வகிக்க Tab விசையை அழுத்திய பிறகு Enter விசையை அழுத்துங்கள்</translation> <translation id="2721148159707890343">கோரிக்கை வெற்றியடைந்தது</translation> +<translation id="2726001110728089263">சைடு டிரே</translation> <translation id="2728127805433021124">சேவையகச் சான்றிதழ் ஒரு வலுவற்ற கையொப்ப அல்காரிதமைப் பயன்படுத்தி கையொப்பமிடப்பட்டுள்ளது.</translation> <translation id="2730326759066348565"><ph name="BEGIN_LINK" />கனெக்டிவிட்டி டயக்னஸ்டிக்ஸ் கருவியை இயக்கவும்<ph name="END_LINK" /></translation> <translation id="2738330467931008676">பிக்அப் முகவரியைத் தேர்வு செய்</translation> @@ -561,6 +573,7 @@ <translation id="2880660355386638022">சாளரத்தைக் காட்டுமிடம்</translation> <translation id="2881276955470682203">கார்டைச் சேமிக்கவா?</translation> <translation id="2882949212241984732">டபுள்-கேட் ஃபோல்டு</translation> +<translation id="2893773853358652045">ரோல் 4</translation> <translation id="2900528713135656174">நிகழ்வை உருவாக்கவும்</translation> <translation id="2903493209154104877">முகவரிகள்</translation> <translation id="290376772003165898"><ph name="LANGUAGE" /> மொழியில் பக்கம் இல்லையா?</translation> @@ -619,6 +632,7 @@ <translation id="3096100844101284527">பிக்அப் முகவரியைச் சேர்</translation> <translation id="3105172416063519923">பண்பு ஐடி:</translation> <translation id="3107591622054137333"><ph name="BEGIN_LINK" />உங்களின் பாதுகாப்பான DNS உள்ளமைவைச் சரிபாருங்கள்<ph name="END_LINK" /></translation> +<translation id="3108943290502734357">நடு டிரே</translation> <translation id="3109728660330352905">இந்தப் பக்கத்தைக் காண உங்களுக்கு அங்கீகாரம் அளிக்கப்படவில்லை.</translation> <translation id="3113284927548439113">மூன்றாம் ஷிஃப்ட்</translation> <translation id="3115874930288085374"><ph name="ENROLLMENT_DOMAIN" /> டொமைனைப் பயன்படுத்த, உங்கள் தரவைக் காப்புப் பிரதி எடுத்துவிட்டு இந்த <ph name="DEVICE_TYPE" /> சாதனத்தைத் திருப்பியளிக்க வேண்டும்.</translation> @@ -632,6 +646,7 @@ <translation id="3154506275960390542">பாதுகாப்பற்ற முறையில் சமர்ப்பிக்கப்படக்கூடிய படிவம் இந்தப் பக்கத்தில் உள்ளது. நீங்கள் அனுப்பும் தரவு சேவையகத்தை அடையும் முன்பு பிறர் அதைப் பார்க்கலாம் அல்லது சேவையகம் பெறும் தரவை தீங்கிழைப்பவர் மாற்றியமைக்கலாம்.</translation> <translation id="315504272643575312">உங்கள் கணக்கை <ph name="MANAGER" /> நிர்வகிக்கிறது.</translation> <translation id="3157931365184549694">மீட்டமை</translation> +<translation id="3158539265159265653">டிஸ்க்</translation> <translation id="3162559335345991374">நீங்கள் பயன்படுத்திக் கொண்டிருக்கும் வைஃபை, அதன் உள்நுழைவுப் பக்கத்தை நீங்கள் பார்க்கக் கோரலாம்.</translation> <translation id="3169472444629675720">Discover</translation> <translation id="3174168572213147020">தீவு</translation> @@ -791,6 +806,7 @@ <translation id="3658742229777143148">மீள்திருத்தங்கள்</translation> <translation id="3664782872746246217">தேடல் குறிப்புகள்:</translation> <translation id="3671540257457995106">அளவை மாற்ற அனுமதிக்கவா?</translation> +<translation id="3675563144891642599">ரோல் 3</translation> <translation id="3676592649209844519">சாதன ஐடி:</translation> <translation id="3677008721441257057">இதைக் குறிப்பிட்டீர்களா: <a href="#" id="dont-proceed-link"><ph name="DOMAIN" /></a>?</translation> <translation id="3678029195006412963">கோரிக்கையில் கையொப்பமிட முடியவில்லை</translation> @@ -906,6 +922,7 @@ <translation id="4084120443451129199">தேடல் பயன்முறை, <ph name="KEYWORD_SUFFIX" /> ஐத் தேட Enter விசையை அழுத்துங்கள்</translation> <translation id="4087296516249690906">நிகழ்வை உருவாக்குவதற்கான பட்டன். Google Calendarரில் புதிய நிகழ்வை விரைவாக உருவாக்க Enter பட்டனை அழுத்துங்கள்</translation> <translation id="4088981014127559358">சைடு 1 இமேஜ் Y ஷிஃப்ட்</translation> +<translation id="4089152113577680600">டிரே 14</translation> <translation id="4098354747657067197">மோசடிசெய்யும் தளம் உள்ளது</translation> <translation id="4099391883283080991"><ph name="CUSTOMIZE_CHROME_FONTS_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chromeமில் எழுத்து வடிவ அளவுகளையும் வகைகளையும் பிரத்தியேகமாக்க, Tab பட்டனை அழுத்திவிட்டு Enter பட்டனை அழுத்துங்கள்</translation> <translation id="4101413244023615925">உரை & கிராஃபிக்</translation> @@ -940,6 +957,7 @@ <translation id="4179515394835346607"><ph name="ROW_NAME" /> <ph name="ROW_CONTENT" /></translation> <translation id="4194250254487269611">உங்கள் கார்டு விவரங்களைத் தற்போது சேமிக்க இயலாது</translation> <translation id="4196861286325780578">&நகர்த்தலை மீண்டும் செய்</translation> +<translation id="4202554117186904723">ரோல் 5</translation> <translation id="4203896806696719780"><ph name="BEGIN_LINK" />ஃபயர்வால் மற்றும் வைரஸ் எதிர்ப்பு உள்ளமைவைச் சரிபார்த்தல்<ph name="END_LINK" /></translation> <translation id="4209092469652827314">பெரிய</translation> <translation id="4209166701302774460">நீங்கள் செல்லும் சேவையகமான <ph name="ORIGIN" />, @@ -1001,6 +1019,7 @@ <translation id="4314815835985389558">ஒத்திசைவை நிர்வகிக்கும் பக்கம்</translation> <translation id="4318312030194671742">பெயிண்ட் மாதிரிக்காட்சித் தொகுப்பான் சேவை</translation> <translation id="4318566738941496689">உங்கள் சாதனப் பெயர் மற்றும் நெட்வொர்க் முகவரி</translation> +<translation id="4325600325087822253">டிரே 17</translation> <translation id="4325863107915753736">கட்டுரையைக் கண்டறிய முடியவில்லை</translation> <translation id="4326324639298822553">காலாவதித் தேதியைச் சரிபார்த்து, மீண்டும் முயலவும்</translation> <translation id="4329871760342656885">கொள்கையைப் பாகுபடுத்துவதில் பிழை: <ph name="ERROR" /></translation> @@ -1012,6 +1031,7 @@ <translation id="4346833872170306413">Roc-16K</translation> <translation id="4348834659292907206"><ph name="SITE" /> தளத்திற்கான இணைப்பு பாதுகாப்பற்றது</translation> <translation id="4349531505348777662">மோசடி செய்யும் இணையதளத்தில் உங்கள் கடவுச்சொல்லை உள்ளிட்டுள்ளீர்கள். இந்தக் கடவுச்சொல்லைப் பயன்படுத்தி உள்நுழையும் <ph name="WEBSITE_1" />, <ph name="WEBSITE_2" /> மற்றும் பிற தளங்களுக்குச் சென்று இதை இப்போதே மாற்றுமாறு Chrome பரிந்துரைக்கிறது.</translation> +<translation id="4350629523305688469">மல்டிபங்க்ஷன் டிரே</translation> <translation id="4351060348582610152">அருகிலுள்ள புளூடூத் சாதனங்களை <ph name="ORIGIN" /> ஸ்கேன் செய்ய விரும்புகிறது. இவை கண்டறியப்பட்டுள்ளன:</translation> <translation id="4356973930735388585">இந்தத் தளத்தில் உள்ள தீங்கிழைப்பவர்கள், உங்கள் தகவலைத் (எடுத்துக்காட்டு: படங்கள், கடவுச்சொற்கள், செய்திகள் மற்றும் கிரெடிட் கார்டுகள்) திருடக்கூடிய அல்லது நீக்கக்கூடிய தீங்கிழைக்கும் நிரல்களை உங்கள் கம்ப்யூட்டரில் நிறுவ முயலலாம்.</translation> <translation id="4358059973562876591">DnsOverHttpsMode கொள்கையில் ஏற்பட்ட பிழை காரணமாக நீங்கள் குறிப்பிட்ட டெம்ப்ளேட்கள் பயன்படுத்தப்படாமல் போகக்கூடும்.</translation> @@ -1066,6 +1086,7 @@ <translation id="4515275063822566619">கார்டுகளும் முகவரிகளும் Chromeமிலிருந்தும் <ph name="ACCOUNT_EMAIL" /> எனும் உங்கள் Google கணக்கிலிருந்தும் பெறப்பட்டவையாகும். <ph name="BEGIN_LINK" />அமைப்புகளில்<ph name="END_LINK" /> அவற்றை நிர்வகிக்கலாம்.</translation> <translation id="4517607026994743406">Comm-10 (என்வலப்)</translation> <translation id="4521157617044179198"><ph name="WIDTH" /> × <ph name="HEIGHT" /> மிமீ (<ph name="ORIENTATION" />)</translation> +<translation id="4521916730539354575">இடதுபுற டிரே</translation> <translation id="4522570452068850558">விவரங்கள்</translation> <translation id="4524138615196389145">இப்போதிலிருந்து WebAuthnனைப் பயன்படுத்தி மேலும் விரைவாக உங்கள் கார்டுகளை உறுதிப்படுத்துங்கள்</translation> <translation id="4524805452350978254">கார்டுகளை நிர்வகி</translation> @@ -1180,6 +1201,7 @@ <translation id="4889420713887366944">’மறைநிலை சாளரத்தைத் திற’ பட்டன், தனிப்பட்ட முறையில் உலாவுவதற்குப் புதிய மறைநிலை சாளரத்தைத் திறக்க Enter விசையை அழுத்துங்கள்</translation> <translation id="4892518386797173871">பின்பக்கம்</translation> <translation id="4895877746940133817"><ph name="TYPE_1" />, <ph name="TYPE_2" />, <ph name="TYPE_3" /></translation> +<translation id="4900217275619098670">ரோல் 9</translation> <translation id="4901778704868714008">சேமி...</translation> <translation id="4913987521957242411">பஞ்ச் டாப் லெஃப்ட்</translation> <translation id="4918221908152712722"><ph name="APP_NAME" />ஐ நிறுவு (பதிவிறக்க வேண்டியதில்லை)</translation> @@ -1228,6 +1250,7 @@ <translation id="5068524481479508725">A10</translation> <translation id="5068778127327928576">{NUM_COOKIES,plural, =1{(ஒன்று பயன்பாட்டில் உள்ளது)}other{(# பயன்பாட்டில் உள்ளன)}}</translation> <translation id="5070335125961472645"><ph name="BEGIN_LINK" />ப்ராக்ஸி முகவரியைச் சரிபார்த்தல்<ph name="END_LINK" /></translation> +<translation id="5070838744279127212">ரோல் 10</translation> <translation id="507130231501693183">அஞ்சல் பெட்டி 4</translation> <translation id="5087286274860437796">தற்போது சேவையகத்தின் சான்றிதழ் செல்லுபடியாகாது.</translation> <translation id="5087580092889165836">கார்டைச் சேர்</translation> @@ -1240,6 +1263,7 @@ <translation id="5097501891273180634">A2</translation> <translation id="5108881358339761672">பாதுகாப்பற்ற தளம்</translation> <translation id="5112422516732747637">A5</translation> +<translation id="5114288597538800140">டிரே 18</translation> <translation id="5114987907971894280">விர்ச்சுவல் ரியாலிட்டி</translation> <translation id="5115216390227830982">European-Edp</translation> <translation id="5115232566827194440">கட்டுப்பாடுகளுடைய நிர்வகிக்கப்பட்ட கெஸ்ட் அமர்வுகளை மீறிச்செயல்படுதல்</translation> @@ -1273,8 +1297,10 @@ <translation id="5201306358585911203">இந்தப் பக்கத்திலுள்ள உட்பொதிக்கப்பட்ட பக்கம் தெரிவிப்பது:</translation> <translation id="5205222826937269299">பெயர் தேவை</translation> <translation id="5209518306177824490">SHA-1 விரல்அச்சு</translation> +<translation id="5209670883520018268">டிரே 20</translation> <translation id="5215116848420601511">Google Payவைப் பயன்படுத்தும் கட்டண முறைகளும் முகவரிகளும்</translation> <translation id="5215363486134917902">Folio-Sp</translation> +<translation id="521659676233207110">டிரே 13</translation> <translation id="5222812217790122047">மின்னஞ்சல் தேவை</translation> <translation id="5230733896359313003">ஷிப்பிங் முகவரி</translation> <translation id="5230815978613972521">B8</translation> @@ -1478,6 +1504,7 @@ <translation id="5967592137238574583">தொடர்புத் தகவலைத் திருத்தவும்</translation> <translation id="5967867314010545767">வரலாற்றிலிருந்து அகற்று</translation> <translation id="5968793460449681917">ஒவ்வொரு முறை வரும்போதும்</translation> +<translation id="5974052231147553524">ரோல் 6</translation> <translation id="5975083100439434680">சிறிதாக்கு</translation> <translation id="5979084224081478209">கடவுச்சொற்களைச் சோதித்துப் பார்க்கவும்</translation> <translation id="5980920751713728343">Index-3x5</translation> @@ -1631,11 +1658,13 @@ <translation id="6499038740797743453">கடவுச்சொல்லை மீட்டமைக்கவா?</translation> <translation id="6502991525169604759">அசல் ஆவணத்தைப் பதிவிறக்கு</translation> <translation id="6505563257409036437">மறைநிலைச் சாளரங்களை மூடுக</translation> +<translation id="6506959208958864820">என்வலப்</translation> <translation id="6508722015517270189">Chromeஐ மீண்டும் தொடங்கவும்</translation> <translation id="6513005815064132016">கேமராவின் நிலையைக் கண்காணிக்க முயலும்போது அனுமதி கேட்க வேண்டும்</translation> <translation id="6517596291481585650">எச்சரிக்கை: இது பட்டியல் இல்லை என்பதால் கொள்கையில் குறிப்பிட்டுள்ளபடி ஒன்றிணைக்கப்படவில்லை.</translation> <translation id="6518133107902771759">சரிபார்</translation> <translation id="6521745193039995384">செயலில் இல்லை</translation> +<translation id="6529173248185917884">ரோல் 7</translation> <translation id="6529602333819889595">&நீக்குதலை மீண்டும் செய்</translation> <translation id="6545864417968258051">புளூடூத் ஸ்கேனிங்</translation> <translation id="6547208576736763147">டூயல் பஞ்ச் லெஃப்ட்</translation> @@ -1670,6 +1699,7 @@ <translation id="6652101503459149953">Windows Helloவைப் பயன்படுத்து</translation> <translation id="6657585470893396449">கடவுச்சொல்</translation> <translation id="6660413144148052430">இருப்பிடம்</translation> +<translation id="6662457027866368246">ரோல் 1</translation> <translation id="666259744093848177">(x86_64க்கு ஏற்றவாறு மாற்றியமைக்கப்பட்டது)</translation> <translation id="6665553082534466207">டிரிப்பில் பஞ்ச் ரைட்</translation> <translation id="6671697161687535275">Chromium இலிருந்து படிவப் பரிந்துரையை அகற்றவா?</translation> @@ -1716,6 +1746,7 @@ <translation id="6846340164947227603">விர்ச்சுவல் கார்டு எண்ணைப் பயன்படுத்துக...</translation> <translation id="6852204201400771460">ஆப்ஸை ரெஃப்ரெஷ் செய்யவா?</translation> <translation id="6865412394715372076">இந்தக் கார்டை இப்போது சரிபார்க்க முடியாது</translation> +<translation id="6873456682041376666">மேல்பக்க டிரே</translation> <translation id="6874604403660855544">&சேர்த்தலை மீண்டும் செய்</translation> <translation id="6881240511396774766">புதிய Google ஆவணத்தை விரைவாக உருவாக்குங்கள்</translation> <translation id="6883221904761970440">பாதுகாப்பான பேமெண்ட்டின் அனுமதிச் சான்றை அங்கீகரிப்பதற்கான தாள் மூடப்பட்டது</translation> @@ -1796,6 +1827,7 @@ <translation id="7135130955892390533">நிலையைக் காட்டு</translation> <translation id="7138472120740807366">டெலிவரி முறை</translation> <translation id="7139724024395191329">எமிரேட்</translation> +<translation id="7139892792842608322">முதன்மை டிரே</translation> <translation id="714064300541049402">சைடு 2 இமேஜ் X ஷிஃப்ட்</translation> <translation id="7152423860607593928">Number-14 (என்வலப்)</translation> <translation id="7153549335910886479">{PAYMENT_METHOD,plural, =0{<ph name="PAYMENT_METHOD_PREVIEW" />}=1{<ph name="PAYMENT_METHOD_PREVIEW" />, மேலும் <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}other{<ph name="PAYMENT_METHOD_PREVIEW" />, மேலும் <ph name="NUMBER_OF_ADDITIONAL_PAYMENT_METHODS" />}}</translation> @@ -1834,6 +1866,7 @@ <translation id="7251437084390964440">நெட்வொர்க் உள்ளமைவானது ONC தரத்துடன் இணங்கவில்லை. உள்ளமைவின் பகுதிகள் இறக்குமதியாகாமல் போகக்கூடும். கூடுதல் விவரங்கள்: <ph name="DEBUG_INFO" /></translation> +<translation id="7256634549594854023">பின்பக்க டிரே</translation> <translation id="725866823122871198">உங்கள் கம்ப்யூட்டரின் தேதியும் நேரமும் (<ph name="DATE_AND_TIME" />) தவறாக இருப்பதால் <ph name="BEGIN_BOLD" /><ph name="DOMAIN" /><ph name="END_BOLD" /> க்கான தனிப்பட்ட இணைப்பை ஏற்படுத்த முடியவில்லை.</translation> <translation id="7260504762447901703">அணுகலை ரத்துசெய்</translation> <translation id="7275334191706090484">நிர்வகிக்கப்படும் புக்மார்க்குகள்</translation> @@ -1989,9 +2022,11 @@ <translation id="7734285854693414638">Google Formsஸில் புதிய படிவத்தை விரைவாக உருவாக்கும்</translation> <translation id="773466115871691567"><ph name="SOURCE_LANGUAGE" /> மொழியில் உள்ள பக்கங்களை எப்போதும் மொழிபெயர்</translation> <translation id="7740996059027112821">நிலையானது</translation> +<translation id="77424286611022110">குறுக்கிடும் அல்லது தவறாக வழிநடத்தும் விளம்பரங்களை இந்தத் தளம் காட்டுகிறது. <ph name="LEARN_MORE_LINK_TEXT" /></translation> <translation id="774634243536837715">ஆபத்தான உள்ளடக்கம் தடுக்கப்பட்டது.</translation> <translation id="7751971323486164747">Chromeமில் எழுத்து வடிவ அளவுகளையும் வகைகளையும் பிரத்தியேகமாக்கலாம்</translation> <translation id="7752995774971033316">நிர்வகிக்கப்படாதது</translation> +<translation id="7755624218968747854">முதன்மை ரோல்</translation> <translation id="7757555340166475417">Dai-Pa-Kai</translation> <translation id="7758069387465995638">ஃபயர்வால் அல்லது வைரஸ்தடுப்பு மென்பொருள் உங்கள் இணைப்பைத் தடுத்திருக்கலாம்.</translation> <translation id="776110834126722255">நிறுத்தப்பட்டது</translation> @@ -2069,6 +2104,7 @@ <translation id="8012116502927253373">{NUM_CARDS,plural, =1{இந்தக் கார்டும் அதன் பில்லிங் முகவரியும் சேமிக்கப்படும். <ph name="USER_EMAIL" /> இல் உள்நுழைந்திருக்கும்போது இதைப் பயன்படுத்தலாம்.}other{இந்தக் கார்டுகளும் அவற்றின் பில்லிங் முகவரிகளும் சேமிக்கப்படும். <ph name="USER_EMAIL" /> இல் உள்நுழைந்திருக்கும்போது இவற்றைப் பயன்படுத்தலாம்.}}</translation> <translation id="8025119109950072390">இந்தத் தளத்தில் உள்ள ஹேக்கர்கள், உங்களை ஏமாற்றி, மென்பொருளை நிறுவுவது அல்லது தனிப்பட்ட தகவலை (எடுத்துக்காட்டாக, கடவுச்சொற்கள், ஃபோன் எண்கள் அல்லது கிரெடிட் கார்டுகள்) வெளிப்படுத்துவது போன்ற உங்களுக்கு ஆபத்தை விளைவிக்கும் செயல்களைச் செய்ய வைக்கலாம்.</translation> <translation id="8026334261755873520">உலாவிய தரவை அழி</translation> +<translation id="8027077570865220386">டிரே 15</translation> <translation id="8028698320761417183"><ph name="CREATE_GOOGLE_FORM_FOCUSED_FRIENDLY_MATCH_TEXT" />, Google Formsஸில் புதிய படிவத்தை விரைவாக உருவாக்க Tab பட்டனை அழுத்திவிட்டு Enter பட்டனை அழுத்துங்கள்</translation> <translation id="8028960012888758725">டிரிம் ஆஃப்டர் ஜாப்</translation> <translation id="8034522405403831421">இந்தப் பக்கம் <ph name="SOURCE_LANGUAGE" /> மொழியில் உள்ளது. இதை <ph name="TARGET_LANGUAGE" /> க்கு மொழிபெயர்க்கவா?</translation> @@ -2127,6 +2163,7 @@ <translation id="8228419419708659934">இரண்டு பக்கப்பார்வை</translation> <translation id="822964464349305906"><ph name="TYPE_1" />, <ph name="TYPE_2" /></translation> <translation id="8232343881378637145">பிளாட்ஃபார்ம் வெப்பநிலை</translation> +<translation id="8233773197406738106">ஃபைலைத் தயார்செய்கிறது</translation> <translation id="8238581221633243064">புதிய மறைநிலைத் தாவலில் பக்கத்தைத் திறக்கவும்</translation> <translation id="8241707690549784388">நீங்கள் தேடும் பக்கமானது நீங்கள் உள்ளிட்ட தகவலைப் பயன்படுத்தியது. மீண்டும் அந்த பக்கத்திற்கு திரும்பினால், நீங்கள் செய்த ஏதேனும் செயலை மீண்டும் செய்ய வேண்டியிருக்கலாம். தொடர விரும்புகிறீர்களா?</translation> <translation id="8241712895048303527">இந்தத் தளத்தில் தடு</translation> @@ -2144,6 +2181,7 @@ <translation id="8270242299912238708">PDF ஆவணங்கள்</translation> <translation id="8275952078857499577">இந்தத் தளத்தை மொழிபெயர்க்க அனுமதிக்காதே</translation> <translation id="8277900682056760511">பேமெண்ட் ஹேண்ட்லர் ஷீட் திறந்துள்ளது</translation> +<translation id="8280630997017109758">டிரே 11</translation> <translation id="8281084378435768645">Large-Photo</translation> <translation id="8282947398454257691">உங்கள் தனிப்பட்ட சாதன அடையாளங்காட்டியை அறியும்</translation> <translation id="8284769179630993263">Chrome அமைப்புகளில் பாதுகாப்பு உலாவலையும் மேலும் பலவற்றையும் நிர்வகியுங்கள்</translation> @@ -2292,6 +2330,7 @@ <translation id="8807160976559152894">டிரிம் ஆஃப்டர் ஈச் பேஜ்</translation> <translation id="8816395686387277279"><ph name="UPDATE_CHROME_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chrome அமைப்புகளில் Chromeமைப் புதுப்பிக்க Tab விசையை அழுத்திய பிறகு Enter விசையை அழுத்துங்கள்</translation> <translation id="8820817407110198400">புக்மார்க்குகள்</translation> +<translation id="882338992931677877">மேனுவல் ஸ்லாட்</translation> <translation id="883848425547221593">மற்ற புக்மார்க்குகள்</translation> <translation id="884264119367021077">ஷிப்பிங் முகவரி</translation> <translation id="884923133447025588">திரும்பப்பெறுதல் செயல்முறை காணப்படவில்லை.</translation> @@ -2350,6 +2389,7 @@ <translation id="9036306139374661733">மைக்ரோஃபோன் அணுகலை வழங்கவா?</translation> <translation id="9038649477754266430">பக்கங்களை இன்னும் விரைவாக ஏற்ற, யூக சேவையைப் பயன்படுத்தவும்</translation> <translation id="9039213469156557790">மேலும், பாதுகாப்பற்ற பிற ஆதாரங்கள் இந்தப் பக்கத்தில் உள்ளன. இந்த ஆதாரங்களை ட்ரான்ஸிட்டில் இருக்கும்போதும் பிறர் பார்வையிடலாம், மேலும் பக்கத்தின் செயல்பாட்டை மாற்ற, தீங்கிழைப்பவர் அதை மாற்றியமைக்கலாம்.</translation> +<translation id="9042617223719777575">அதிகக் கொள்ளளவு</translation> <translation id="9044359186343685026">Touch IDயைப் பயன்படுத்து</translation> <translation id="9045525010788763347"><ph name="RESULT_MODIFIED_DATE" /> - <ph name="RESULT_PRODUCT_SOURCE" /></translation> <translation id="9049981332609050619">நீங்கள் <ph name="DOMAIN" /> ஐ அடைய முயற்சி செய்தீர்கள், ஆனால் சேவையகம் ஒரு செல்லாத சான்றிதழை வழங்கியது.</translation>
diff --git a/components/strings/components_strings_te.xtb b/components/strings/components_strings_te.xtb index 8fa28e2..eaf640e 100644 --- a/components/strings/components_strings_te.xtb +++ b/components/strings/components_strings_te.xtb
@@ -1317,6 +1317,7 @@ <translation id="5252000469029418751">C7 (ఎన్వలప్)</translation> <translation id="5254043433801397071">ప్రింట్ కంటెంట్ను ఆప్టిమైజ్ చేయి</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">ఏదేమైనా క్యాప్చర్ చేయి</translation> <translation id="5265446478903775694">Googleలో నా గోప్యతను మేనేజ్ చేయి</translation> <translation id="5266128565379329178">ఎగువ భాగంలో బైండ్</translation> <translation id="5269225904387178860">దిగువ భాగంలో నాలుగు రంధ్రాలు</translation> @@ -1841,6 +1842,7 @@ <translation id="7153618581592392745">లావెండర్ రంగు</translation> <translation id="7156870133441232244">సర్వర్ను TLS 1.2 లేదా ఆపై వెర్షన్లకు అప్గ్రేడ్ చేయాలి.</translation> <translation id="717330890047184534">Gaia ID:</translation> +<translation id="7173920250514487165">మీ స్క్రీన్పై ఉన్న గోప్యమైన కంటెంట్ను క్యాప్చర్ చేయండి</translation> <translation id="7174545416324379297">విలీనం చేయబడ్డాయి</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> మరియు మరో <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}other{<ph name="SHIPPING_OPTION_PREVIEW" /> మరియు మరో <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" />}}</translation> <translation id="7179323680825933600">పేమెంట్ ఆప్షన్లను సేవ్ చేసి, ఆటోమేటిక్గా ఫిల్ చేయండి</translation> @@ -2100,6 +2102,7 @@ <translation id="7977538094055660992">అవుట్పుట్ పరికరం</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">వర్చువల్ రియాలిటీ పరికరాలు, డేటాను ఉపయోగించడానికి సైట్ అనుమతి అడగవచ్చు</translation> +<translation id="7984699858161118573">స్క్రీన్పై గోప్యమైన కంటెంట్ ఉండటం వలన స్క్రీన్షాట్లు తీసుకోవడాన్ని లేదా రికార్డింగ్లను అడ్మినిస్ట్రేటర్ సిఫార్సు చేయరు</translation> <translation id="7984945080620862648">Chrome ప్రాసెస్ చేయలేని, గజిబిజిగా ఉండే ఆధారాలను వెబ్సైట్ పంపినందున మీరు ప్రస్తుతం <ph name="SITE" />ని సందర్శించలేరు. నెట్వర్క్ లోపాలు మరియు దాడులు సాధారణంగా తాత్కాలికంగానే ఉంటాయి, కావున ఈ పేజీ కాసేపటి తర్వాత పని చేసే అవకాశం ఉంది.</translation> <translation id="79859296434321399">మెరుగైన వాస్తవిక అనుభవ కంటెంట్ను చూడడానికి, ARCoreని ఇన్స్టాల్ చేయండి</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_th.xtb b/components/strings/components_strings_th.xtb index 08edf86..360e28e2 100644 --- a/components/strings/components_strings_th.xtb +++ b/components/strings/components_strings_th.xtb
@@ -1305,6 +1305,7 @@ <translation id="5252000469029418751">C7 (ซองจดหมาย)</translation> <translation id="5254043433801397071">เพิ่มประสิทธิภาพเนื้อหาที่พิมพ์</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">จับภาพเลย</translation> <translation id="5265446478903775694">จัดการความเป็นส่วนตัวของฉันบน Google</translation> <translation id="5266128565379329178">เย็บเล่มด้านบน</translation> <translation id="5269225904387178860">เจาะรูด้านล่าง 4 รู</translation> @@ -1829,6 +1830,7 @@ <translation id="7153618581592392745">ลาเวนเดอร์</translation> <translation id="7156870133441232244">ควรอัปเกรดเซิร์ฟเวอร์เป็น TLS 1.2 ขึ้นไป</translation> <translation id="717330890047184534">รหัส GAIA:</translation> +<translation id="7173920250514487165">จับภาพเนื้อหาที่เป็นความลับในหน้าจอ</translation> <translation id="7174545416324379297">รวมแล้ว</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> และอีก <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> วิธี}other{<ph name="SHIPPING_OPTION_PREVIEW" /> และอีก <ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> วิธี}}</translation> <translation id="7179323680825933600">บันทึกและกรอกวิธีการชำระเงิน</translation> @@ -2088,6 +2090,7 @@ <translation id="7977538094055660992">อุปกรณ์กระดาษออก</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">สามารถขอใช้อุปกรณ์และข้อมูล Virtual Reality ได้</translation> +<translation id="7984699858161118573">ผู้ดูแลระบบไม่แนะนำให้จับภาพหน้าจอหรือบันทึกเนื่องจากมีเนื้อหาที่เป็นความลับในหน้าจอ</translation> <translation id="7984945080620862648">คุณไม่สามารถไปที่ <ph name="SITE" /> ได้ในขณะนี้ เนื่องจากเว็บไซต์ดังกล่าวส่งข้อมูลรับรองที่สลับกัน ซึ่ง Chrome ไม่สามารถเข้าถึงได้ โดยปกติข้อผิดพลาดของเครือข่ายและการบุกรุกจะเกิดขึ้นเพียงชั่วคราว หน้านี้จึงน่าจะใช้งานได้ในภายหลัง</translation> <translation id="79859296434321399">ติดตั้ง ARCore เพื่อดูเนื้อหา Augmented Reality</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/strings/components_strings_zu.xtb b/components/strings/components_strings_zu.xtb index 0ea1776..400c9c86 100644 --- a/components/strings/components_strings_zu.xtb +++ b/components/strings/components_strings_zu.xtb
@@ -1312,6 +1312,7 @@ <translation id="5252000469029418751">C7 (Envelope)</translation> <translation id="5254043433801397071">Lungiselela ukuphrinta okuqukethwe</translation> <translation id="5254958791078852567">E1</translation> +<translation id="5255690596502591079">Thatha noma kunjalo</translation> <translation id="5265446478903775694">Phatha ubumfihlo ku-Google</translation> <translation id="5266128565379329178">Ukubophezela phezulu</translation> <translation id="5269225904387178860">Ukushaya okune phansi</translation> @@ -1836,6 +1837,7 @@ <translation id="7153618581592392745">Ilavenda</translation> <translation id="7156870133441232244">Iseva kufanele ithuthukele ku-TLS 1.2 noma yakamuva.</translation> <translation id="717330890047184534">I-Gaia ID:</translation> +<translation id="7173920250514487165">Thatha okuqukethwe okuyimfihlo esikrinini sakho</translation> <translation id="7174545416324379297">Ahlanganisiwe</translation> <translation id="7175401108899573750">{SHIPPING_OPTIONS,plural, =0{<ph name="SHIPPING_OPTION_PREVIEW" />}=1{<ph name="SHIPPING_OPTION_PREVIEW" /> nongu-<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ngaphezulu}one{<ph name="SHIPPING_OPTION_PREVIEW" /> nongu-<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ngaphezulu}other{<ph name="SHIPPING_OPTION_PREVIEW" /> nongu-<ph name="NUMBER_OF_ADDITIONAL_SHIPPING_OPTIONS" /> ngaphezulu}}</translation> <translation id="7179323680825933600">Londoloza uphinde ugcwalise izindlela zokukhokha</translation> @@ -2095,6 +2097,7 @@ <translation id="7977538094055660992">Idivaysi yokukhishwayo</translation> <translation id="7977894662897852582">Edp</translation> <translation id="798134797138789862">Amasayithi angacela ukusebenzisa amadivayisi ento engekho ngokoqobo nedatha</translation> +<translation id="7984699858161118573">Umlawuli akakuncomi ukuthatha izithombe-skrini noma ukurekhodwa ngenxa yokuqukethwe okuyimfihlo esikrinini</translation> <translation id="7984945080620862648">Ngeke ukwazi ukuvakashela i-<ph name="SITE" /> njengamanje ngoba iwebhusayithi ithumele izifakazelo ezihlukanisiwe i-Chrome engeke ikwazi ukuzisebenzisa. Ngokuvamile amaphutha enethiwekhi nokuhlasela kungokwesikhashana, ngakho-ke leli khasi lingase lisebenze futhi ngemva kwesikhathi.</translation> <translation id="79859296434321399">Ukuze ubuke okuqukethwe kwe-augmented reality, faka i-ARCore</translation> <translation id="7986319120639858961"><ph name="CARD_TITLE" /> <ph name="TIME" /> <ph name="BOOKMARKED" /> <ph name="TITLE" /> <ph name="DOMAIN" /></translation>
diff --git a/components/variations/BUILD.gn b/components/variations/BUILD.gn index eabd779..3880eae 100644 --- a/components/variations/BUILD.gn +++ b/components/variations/BUILD.gn
@@ -188,6 +188,7 @@ "field_trial_config:field_trial_config", "proto", "//base/test:test_support", + "//components/variations/service:constants", "//third_party/zlib/google:compression_utils", ] }
diff --git a/components/variations/fuzzers/create_trial_from_study_fuzzer.cc b/components/variations/fuzzers/create_trial_from_study_fuzzer.cc index 60b54f9..6952c15 100644 --- a/components/variations/fuzzers/create_trial_from_study_fuzzer.cc +++ b/components/variations/fuzzers/create_trial_from_study_fuzzer.cc
@@ -48,19 +48,18 @@ }; struct Environment { - Environment() - : field_trial_list(std::make_unique<SHA1EntropyProvider>("client_id")) { - base::CommandLine::Init(0, nullptr); - base::FeatureList::InitializeInstance(std::string(), std::string()); - } + Environment() { base::CommandLine::Init(0, nullptr); } - base::FieldTrialList field_trial_list; base::AtExitManager at_exit_manager; }; } // namespace void CreateTrialFromStudyFuzzer(const Study& study) { + base::FieldTrialList field_trial_list( + std::make_unique<SHA1EntropyProvider>("client_id")); + base::FeatureList feature_list; + TestOverrideStringCallback override_callback; base::MockEntropyProvider mock_low_entropy_provider(0.9); @@ -69,7 +68,7 @@ if (processed_study.Init(&study, is_expired)) { VariationsSeedProcessor().CreateTrialFromStudy( processed_study, override_callback.callback(), - &mock_low_entropy_provider, base::FeatureList::GetInstance()); + &mock_low_entropy_provider, &feature_list); } }
diff --git a/components/variations/service/safe_seed_manager.cc b/components/variations/service/safe_seed_manager.cc index 9f12bae..d8ad349 100644 --- a/components/variations/service/safe_seed_manager.cc +++ b/components/variations/service/safe_seed_manager.cc
@@ -18,24 +18,6 @@ namespace variations { -// As of the time of this writing, January 2018, users at the 99.5th percentile, -// across all platforms, tend to experience fewer than 3 consecutive crashes: -// [1], [2], [3], [4]. Note, however, that this is less true for the less-stable -// channels on some platforms. -// [1] All platforms, stable channel (consistently stable): -// https://uma.googleplex.com/timeline_v2?sid=90ac80f4573249fb341a8e49501bfcfd -// [2] Most platforms, all channels (consistently stable other than occasional -// spikes on Canary): -// https://uma.googleplex.com/timeline_v2?sid=7af5ba1969db76689a401f982a1db539 -// [3] A less stable platform, all channels: -// https://uma.googleplex.com/timeline_v2?sid=07dbc8e4fa9f08e332fb609309a21882 -// [4] Another less stable platform, all channels: -// https://uma.googleplex.com/timeline_v2?sid=a7b529ef5d52863fae2d216e963c4cbc -// Overall, the only {platform, channel} combinations that spike above 3 -// consecutive crashes are ones with very few users, plus Canary. It's probably -// not realistic to avoid false positives for these less-stable configurations. -constexpr int kCrashStreakThreshold = 3; - // Consecutive seed fetch failures are, unfortunately, a bit more common. As of // January 2018, users at the 99.5th percentile tend to see fewer than 4 // consecutive fetch failures on mobile platforms; and users at the 99th
diff --git a/components/variations/service/safe_seed_manager.h b/components/variations/service/safe_seed_manager.h index 38fe2b7..95173c17 100644 --- a/components/variations/service/safe_seed_manager.h +++ b/components/variations/service/safe_seed_manager.h
@@ -19,6 +19,24 @@ struct ClientFilterableState; class VariationsSeedStore; +// As of January 2018, users at the 99.5th percentile, across all platforms, +// tend to experience fewer than 3 consecutive crashes: [1], [2], [3], [4]. +// Note, however, that this is less true for the less-stable channels on some +// platforms. +// [1] All platforms, stable channel (consistently stable): +// https://uma.googleplex.com/timeline_v2?sid=90ac80f4573249fb341a8e49501bfcfd +// [2] Most platforms, all channels (consistently stable other than occasional +// spikes on Canary): +// https://uma.googleplex.com/timeline_v2?sid=7af5ba1969db76689a401f982a1db539 +// [3] A less stable platform, all channels: +// https://uma.googleplex.com/timeline_v2?sid=07dbc8e4fa9f08e332fb609309a21882 +// [4] Another less stable platform, all channels: +// https://uma.googleplex.com/timeline_v2?sid=a7b529ef5d52863fae2d216e963c4cbc +// Overall, the only {platform, channel} combinations that spike above 3 +// consecutive crashes are ones with very few users, plus Canary. It's probably +// not realistic to avoid false positives for these less-stable configurations. +constexpr int kCrashStreakThreshold = 3; + // The primary class that encapsulates state for managing the safe seed. class SafeSeedManager { public:
diff --git a/components/variations/service/variations_field_trial_creator.cc b/components/variations/service/variations_field_trial_creator.cc index b5bd47b2..e09c293 100644 --- a/components/variations/service/variations_field_trial_creator.cc +++ b/components/variations/service/variations_field_trial_creator.cc
@@ -146,6 +146,9 @@ } // namespace +const base::Feature kForceFieldTrialSetupCrashForTesting{ + "ForceFieldTrialSetupCrashForTesting", base::FEATURE_DISABLED_BY_DEFAULT}; + VariationsFieldTrialCreator::VariationsFieldTrialCreator( VariationsServiceClient* client, std::unique_ptr<VariationsSeedStore> seed_store, @@ -196,19 +199,6 @@ base::FieldTrial::EnableBenchmarking(); } -#if !defined(OS_ANDROID) - // TODO(crbug/1248239): Enable Extended Variations Safe Mode on Android. - if (extend_variations_safe_mode && - !metrics_state_manager->is_background_session()) { - // If the session is expected to be a background session, then do not extend - // Variations Safe Mode. Extending Safe Mode involves monitoring for crashes - // earlier on in startup; however, this monitoring is not desired in - // background sessions, whose terminations should never be considered - // crashes. - MaybeExtendVariationsSafeMode(metrics_state_manager); - } -#endif - if (command_line->HasSwitch(switches::kForceFieldTrialParams)) { bool result = AssociateParamsFromString( command_line->GetSwitchValueASCII(switches::kForceFieldTrialParams)); @@ -235,6 +225,19 @@ } } +#if !defined(OS_ANDROID) + // TODO(crbug/1248239): Enable Extended Variations Safe Mode on Android. + if (extend_variations_safe_mode && + !metrics_state_manager->is_background_session()) { + // If the session is expected to be a background session, then do not extend + // Variations Safe Mode. Extending Safe Mode involves monitoring for crashes + // earlier on in startup; however, this monitoring is not desired in + // background sessions, whose terminations should never be considered + // crashes. + MaybeExtendVariationsSafeMode(metrics_state_manager); + } +#endif + VariationsIdsProvider* http_header_provider = VariationsIdsProvider::GetInstance(); http_header_provider->SetLowEntropySourceValue(low_entropy_source_value); @@ -301,6 +304,14 @@ base::FeatureList::SetInstance(std::move(feature_list)); + // For testing Variations Safe Mode, maybe crash here. + if (base::FeatureList::IsEnabled(kForceFieldTrialSetupCrashForTesting)) { + // We log a recognizable token for the crash condition, to allow tests to + // recognize the crash location in the test output. See: + // TEST_P(FieldTrialTest, ExtendedSafeModeEndToEnd) + LOG(FATAL) << "crash_for_testing"; + } + // This must be called after |local_state_| is initialized. platform_field_trials->SetupFieldTrials();
diff --git a/components/variations/service/variations_field_trial_creator.h b/components/variations/service/variations_field_trial_creator.h index b6a56ad..570ffd2 100644 --- a/components/variations/service/variations_field_trial_creator.h +++ b/components/variations/service/variations_field_trial_creator.h
@@ -255,6 +255,10 @@ SEQUENCE_CHECKER(sequence_checker_); }; +// A testing feature that forces a crash during field trial creation +// on developer and test builds. +extern const base::Feature kForceFieldTrialSetupCrashForTesting; + } // namespace variations #endif // COMPONENTS_VARIATIONS_SERVICE_VARIATIONS_FIELD_TRIAL_CREATOR_H_
diff --git a/components/variations/service/variations_field_trial_creator_unittest.cc b/components/variations/service/variations_field_trial_creator_unittest.cc index a475e092..1930fca 100644 --- a/components/variations/service/variations_field_trial_creator_unittest.cc +++ b/components/variations/service/variations_field_trial_creator_unittest.cc
@@ -41,6 +41,7 @@ #include "components/variations/service/variations_service_client.h" #include "components/variations/variations_seed_store.h" #include "components/variations/variations_switches.h" +#include "components/variations/variations_test_utils.h" #include "components/version_info/channel.h" #include "components/version_info/version_info.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -60,7 +61,6 @@ using ::testing::Return; // Constants used to create the test seeds. -const char kTestSeedStudyName[] = "test"; const char kTestSeedExperimentName[] = "abc"; const char kTestSafeSeedExperimentName[] = "abc.safe"; const int kTestSeedExperimentProbability = 100; @@ -115,13 +115,6 @@ return seed; } -void DisableTestingConfig() { - // If the testing config is in use, the seed will not be used to set up field - // trials. Disable the testing config to exercise CreateTrialsFromSeed(). - base::CommandLine::ForCurrentProcess()->AppendSwitch( - switches::kDisableFieldTrialTestingConfig); -} - #if defined(OS_ANDROID) const char kTestSeedCountry[] = "in";
diff --git a/components/variations/variations_test_utils.cc b/components/variations/variations_test_utils.cc index f82a604..559f7835 100644 --- a/components/variations/variations_test_utils.cc +++ b/components/variations/variations_test_utils.cc
@@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/feature_list.h" #include "components/variations/proto/client_variations.pb.h" +#include "components/variations/service/variations_safe_mode_constants.h" #include "components/variations/variations_associated_data.h" #include "components/variations/variations_switches.h" #include "third_party/zlib/google/compression_utils.h" @@ -72,4 +73,18 @@ return trial; } +int SetUpExtendedSafeModeExperiment(const std::string& group_name) { + int default_group; + scoped_refptr<base::FieldTrial> trial( + base::FieldTrialList::FactoryGetFieldTrial( + kExtendedSafeModeTrial, 100, kDefaultGroup, + base::FieldTrial::ONE_TIME_RANDOMIZED, &default_group)); + + int active_group = default_group; + if (group_name != kDefaultGroup) + active_group = trial->AppendGroup(group_name, 100); + trial->SetForced(); + return active_group; +} + } // namespace variations
diff --git a/components/variations/variations_test_utils.h b/components/variations/variations_test_utils.h index 1310a18..76be121 100644 --- a/components/variations/variations_test_utils.h +++ b/components/variations/variations_test_utils.h
@@ -41,6 +41,10 @@ IDCollectionKey key, VariationID id); +// Sets up the extended safe mode experiment such that |group_name| is the +// active group. Returns the numeric value that denotes the active group. +int SetUpExtendedSafeModeExperiment(const std::string& group_name); + } // namespace variations #endif // COMPONENTS_VARIATIONS_VARIATIONS_TEST_UTILS_H_
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl_browsertest.cc b/content/browser/bluetooth/web_bluetooth_service_impl_browsertest.cc index 6daae68..a727866 100644 --- a/content/browser/bluetooth/web_bluetooth_service_impl_browsertest.cc +++ b/content/browser/bluetooth/web_bluetooth_service_impl_browsertest.cc
@@ -592,9 +592,9 @@ EXPECT_CALL(*adapter(), AddObserver(_)); - ASSERT_EQ(2u, GetWebContents()->GetAllFrames().size()); + RenderFrameHost* sub_frame = ChildFrameAt(GetWebContents(), 0); + ASSERT_TRUE(sub_frame); - RenderFrameHost* sub_frame = GetWebContents()->GetAllFrames().back(); constexpr char kErrorMessage[] = "NotFoundError: Web Bluetooth API globally disabled.";
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc index 83841b09..9528cdd7 100644 --- a/content/browser/download/download_browsertest.cc +++ b/content/browser/download/download_browsertest.cc
@@ -4273,7 +4273,7 @@ base::BindLambdaForTesting([&]() { DownloadInProgressObserver observer(DownloadManagerForShell(shell())); EXPECT_TRUE( - ExecJs(shell()->web_contents()->GetAllFrames()[1], + ExecJs(ChildFrameAt(shell()->web_contents(), 0), "var anchorElement = document.querySelector('a[download]'); " "anchorElement.click();")); download_item = observer.WaitAndGetInProgressDownload();
diff --git a/content/browser/download/mhtml_generation_browsertest.cc b/content/browser/download/mhtml_generation_browsertest.cc index 97e4aff..b585ef1 100644 --- a/content/browser/download/mhtml_generation_browsertest.cc +++ b/content/browser/download/mhtml_generation_browsertest.cc
@@ -410,7 +410,8 @@ const std::vector<std::string>& expected_substrings, const std::vector<std::string>& forbidden_substrings) { int actual_number_of_frames = - shell()->web_contents()->GetAllFrames().size(); + CollectAllRenderFrameHosts(shell()->web_contents()->GetPrimaryPage()) + .size(); EXPECT_EQ(expected_number_of_frames, actual_number_of_frames); for (const auto& expected_substring : expected_substrings) {
diff --git a/content/browser/loader/cross_site_document_blocking_browsertest.cc b/content/browser/loader/cross_site_document_blocking_browsertest.cc index 5be2ca34..a4a04287 100644 --- a/content/browser/loader/cross_site_document_blocking_browsertest.cc +++ b/content/browser/loader/cross_site_document_blocking_browsertest.cc
@@ -1227,7 +1227,7 @@ std::string fetch_script = base::StringPrintf(fetch_script_template, kPrefetchResourcePath); EXPECT_EQ("<p>contents of the response</p>", - EvalJs(shell()->web_contents()->GetAllFrames()[1], fetch_script, + EvalJs(ChildFrameAt(shell()->web_contents(), 0), fetch_script, EXECUTE_SCRIPT_USE_MANUAL_REPLY)); }
diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc index efb16ff..c2c388e9 100644 --- a/content/browser/prerender/prerender_browsertest.cc +++ b/content/browser/prerender/prerender_browsertest.cc
@@ -77,6 +77,7 @@ #include "net/test/embedded_test_server/http_response.h" #include "net/test/embedded_test_server/request_handler_util.h" #include "services/metrics/public/cpp/ukm_builders.h" +#include "services/network/public/cpp/web_sandbox_flags.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/features.h" @@ -4745,6 +4746,113 @@ PrerenderHost::FinalStatus::kMixedContent, 1); } +// Check that the Content-Security-Policy set via HTTP header applies after the +// activation. This test verifies that that the web sandbox flags value is none. +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, + ActivatePageWithCspHeaderFrameSrc) { + const GURL kInitialUrl = GetUrl("/empty.html"); + const GURL kPrerenderingUrl = + GetUrl("/set-header?Content-Security-Policy: frame-src 'none'"); + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + + int host_id = AddPrerender(kPrerenderingUrl); + RenderFrameHostImpl* prerendered_render_frame_host = + GetPrerenderedMainFrameHost(host_id); + + // Check that CSP was set on the prerendered page prior to activation. + { + const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp_pre = + prerendered_render_frame_host->policy_container_host() + ->policies() + .content_security_policies; + EXPECT_EQ(1u, root_csp_pre.size()); + EXPECT_EQ("frame-src 'none'", root_csp_pre[0]->header->header_value); + EXPECT_EQ(prerendered_render_frame_host->active_sandbox_flags(), + network::mojom::WebSandboxFlags::kNone); + } + + TestNavigationManager activation_manager(web_contents(), kPrerenderingUrl); + NavigatePrimaryPage(kPrerenderingUrl); + activation_manager.WaitForNavigationFinished(); + EXPECT_TRUE(activation_manager.was_prerendered_page_activation()); + EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl); + + // Check that CSP was set on the prerendered page after activation. + { + const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp_post = + current_frame_host() + ->policy_container_host() + ->policies() + .content_security_policies; + EXPECT_EQ(1u, root_csp_post.size()); + EXPECT_EQ("frame-src 'none'", root_csp_post[0]->header->header_value); + EXPECT_EQ(current_frame_host()->active_sandbox_flags(), + network::mojom::WebSandboxFlags::kNone); + EXPECT_EQ(static_cast<WebContentsImpl*>(web_contents()) + ->GetFrameTree() + ->root() + ->active_sandbox_flags(), + network::mojom::WebSandboxFlags::kNone); + } +} + +// Check that the Content-Security-Policy set via HTTP header applies after the +// activation. This test verifies that that the web sandbox flags value is set +// to allow scripts. +IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, + ActivatePageWithCspHeaderSandboxFlags) { + const GURL kInitialUrl = GetUrl("/empty.html"); + const GURL kPrerenderingUrl = + GetUrl("/set-header?Content-Security-Policy: sandbox allow-scripts"); + ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); + + int host_id = AddPrerender(kPrerenderingUrl); + RenderFrameHostImpl* prerendered_render_frame_host = + GetPrerenderedMainFrameHost(host_id); + + // Check that CSP was set on the prerendered page prior to activation. + { + const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp_pre = + prerendered_render_frame_host->policy_container_host() + ->policies() + .content_security_policies; + EXPECT_EQ(1u, root_csp_pre.size()); + EXPECT_EQ("sandbox allow-scripts", root_csp_pre[0]->header->header_value); + EXPECT_EQ(prerendered_render_frame_host->active_sandbox_flags(), + network::mojom::WebSandboxFlags::kAll & + ~network::mojom::WebSandboxFlags::kScripts & + ~network::mojom::WebSandboxFlags::kAutomaticFeatures); + } + + TestNavigationManager activation_manager(web_contents(), kPrerenderingUrl); + NavigatePrimaryPage(kPrerenderingUrl); + activation_manager.WaitForNavigationFinished(); + EXPECT_TRUE(activation_manager.was_prerendered_page_activation()); + EXPECT_EQ(web_contents()->GetLastCommittedURL(), kPrerenderingUrl); + + // Check that CSP was set on the prerendered page after activation. + { + const std::vector<network::mojom::ContentSecurityPolicyPtr>& root_csp_post = + current_frame_host() + ->policy_container_host() + ->policies() + .content_security_policies; + EXPECT_EQ(1u, root_csp_post.size()); + EXPECT_EQ("sandbox allow-scripts", root_csp_post[0]->header->header_value); + EXPECT_EQ(current_frame_host()->active_sandbox_flags(), + network::mojom::WebSandboxFlags::kAll & + ~network::mojom::WebSandboxFlags::kScripts & + ~network::mojom::WebSandboxFlags::kAutomaticFeatures); + EXPECT_EQ(static_cast<WebContentsImpl*>(web_contents()) + ->GetFrameTree() + ->root() + ->active_sandbox_flags(), + network::mojom::WebSandboxFlags::kAll & + ~network::mojom::WebSandboxFlags::kScripts & + ~network::mojom::WebSandboxFlags::kAutomaticFeatures); + } +} + class PrerenderPurposePrefetchBrowserTest : public PrerenderBrowserTest { public: PrerenderPurposePrefetchBrowserTest() = default;
diff --git a/content/browser/prerender/prerender_host_registry.cc b/content/browser/prerender/prerender_host_registry.cc index 5583236..352ecc57 100644 --- a/content/browser/prerender/prerender_host_registry.cc +++ b/content/browser/prerender/prerender_host_registry.cc
@@ -20,6 +20,7 @@ #include "content/browser/renderer_host/navigation_request.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/web_contents.h" #include "third_party/blink/public/common/features.h" namespace content { @@ -89,6 +90,17 @@ base::BindOnce(&PrerenderHostRegistry::NotifyTrigger, base::Unretained(this), attributes->url)); + // Don't prerender when the trigger is in the background. + auto* web_contents = + WebContents::FromRenderFrameHost(&initiator_render_frame_host); + DCHECK(web_contents); + if (web_contents->GetVisibility() == Visibility::HIDDEN) { + base::UmaHistogramEnumeration( + "Prerender.Experimental.PrerenderHostFinalStatus", + PrerenderHost::FinalStatus::kTriggerBackgrounded); + return RenderFrameHost::kNoFrameTreeNodeId; + } + // Don't prerender on low-end devices. // TODO(https://crbug.com/1176120): Fallback to NoStatePrefetch // since the memory requirements are different.
diff --git a/content/browser/prerender/prerender_host_registry_unittest.cc b/content/browser/prerender/prerender_host_registry_unittest.cc index 84016be..8487ac6 100644 --- a/content/browser/prerender/prerender_host_registry_unittest.cc +++ b/content/browser/prerender/prerender_host_registry_unittest.cc
@@ -683,6 +683,30 @@ EXPECT_NE(registry->FindHostByUrlForTesting(kPrerenderingUrl), nullptr); } +TEST_F(PrerenderHostRegistryTest, + DontStartPrerenderWhenTriggerIsAlreadyHidden) { + base::HistogramTester histogram_tester; + std::unique_ptr<TestWebContents> web_contents = + CreateWebContents(GURL("https://example.com/")); + // The visibility state to be HIDDEN will cause prerendering not started. + web_contents->WasHidden(); + + const GURL kPrerenderingUrl = GURL("https://example.com/empty.html"); + RenderFrameHostImpl* initiator_rfh = web_contents->GetMainFrame(); + PrerenderHostRegistry* registry = web_contents->GetPrerenderHostRegistry(); + auto attributes = blink::mojom::PrerenderAttributes::New(); + attributes->url = kPrerenderingUrl; + const int prerender_frame_tree_node_id = + registry->CreateAndStartHost(std::move(attributes), *initiator_rfh); + EXPECT_EQ(prerender_frame_tree_node_id, RenderFrameHost::kNoFrameTreeNodeId); + PrerenderHost* prerender_host = + registry->FindNonReservedHostById(prerender_frame_tree_node_id); + EXPECT_EQ(prerender_host, nullptr); + histogram_tester.ExpectUniqueSample( + "Prerender.Experimental.PrerenderHostFinalStatus", + PrerenderHost::FinalStatus::kTriggerBackgrounded, 1); +} + // ------------------------------------------------- // Activation navigation parameter matching unit tests. // These tests change a parameter to differentiate the activation request from
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc index bdae5c2..ec90b02 100644 --- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -13665,7 +13665,7 @@ shell()->web_contents()->GetController()); // Add 5 dynamic subframes to |frame|. - RenderFrameHost* frame = shell()->web_contents()->GetAllFrames()[1]; + RenderFrameHost* frame = ChildFrameAt(current_main_frame_host(), 0); std::string script = R"( for (var i = 0; i < 5; i++) { var iframe = document.createElement("iframe"); @@ -13707,7 +13707,7 @@ shell()->web_contents()->GetController()); // Add 5 dynamic subframes to |frame|. - RenderFrameHost* frame = shell()->web_contents()->GetAllFrames()[1]; + RenderFrameHost* frame = ChildFrameAt(current_main_frame_host(), 0); std::string script = R"( for (var i = 0; i < 5; i++) { var iframe = document.createElement("iframe");
diff --git a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc index ab18bf8..e2e32da5 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -2667,8 +2667,9 @@ EXPECT_TRUE(NavigateIframeToURL(web_contents(), "child0", blocked_url)); // Verify that the NavigationHandle / NavigationRequest didn't leak. - RenderFrameHostImpl* frame = static_cast<RenderFrameHostImpl*>( - shell()->web_contents()->GetAllFrames()[1]); + RenderFrameHostImpl* frame = + static_cast<RenderFrameHostImpl*>(ChildFrameAt(root_frame_host(), 0)); + EXPECT_FALSE(frame->HasPendingCommitNavigation()); // TODO(lukasza, clamy): https://crbug.com/784904: Verify that @@ -2870,9 +2871,9 @@ // Browser-side origin should match the renderer-side origin. // See also https://crbug.com/932067. - ASSERT_EQ(2u, web_contents()->GetAllFrames().size()); RenderFrameHostImpl* subframe = - web_contents()->GetMainFrame()->child_at(0)->current_frame_host(); + static_cast<RenderFrameHostImpl*>(ChildFrameAt(root_frame_host(), 0)); + ASSERT_TRUE(subframe); EXPECT_EQ(main_origin, subframe->GetLastCommittedOrigin()); EXPECT_EQ(blink::StorageKey(main_origin), subframe->storage_key()); } @@ -2900,8 +2901,8 @@ // Wait for a new subframe, but ignore the frame returned by // |subframe_observer| (it might be the speculative one, not the current one). subframe_observer.Wait(); - ASSERT_EQ(2u, web_contents()->GetAllFrames().size()); - RenderFrameHost* subframe = web_contents()->GetAllFrames()[1]; + RenderFrameHost* subframe = ChildFrameAt(root_frame_host(), 0); + ASSERT_TRUE(subframe); // The browser-side origin of the *sandboxed* subframe should be set to an // *opaque* origin (with the parent's origin as the precursor origin). @@ -2955,9 +2956,9 @@ // Browser-side origin should match the renderer-side origin. // See also https://crbug.com/932067. - ASSERT_EQ(2u, web_contents()->GetAllFrames().size()); RenderFrameHostImpl* subframe2 = - web_contents()->GetMainFrame()->child_at(0)->current_frame_host(); + static_cast<RenderFrameHostImpl*>(ChildFrameAt(root_frame_host(), 0)); + ASSERT_TRUE(subframe2); EXPECT_EQ(subframe, subframe2); // No swaps are expected. EXPECT_EQ(main_origin, subframe2->GetLastCommittedOrigin()); EXPECT_EQ(blink::StorageKey(main_origin), subframe2->storage_key()); @@ -4820,7 +4821,6 @@ DocumentUkmSourceIdObserver observer(web_contents); ASSERT_TRUE(NavigateToURL(shell(), main_frame_url)); - ASSERT_EQ(2u, web_contents->GetAllFrames().size()); RenderFrameHostImpl* main_frame_host = static_cast<RenderFrameHostImpl*>(web_contents->GetMainFrame()); @@ -4828,6 +4828,7 @@ ukm::SourceId main_frame_doc_ukm_source_id = observer.GetMainFrameDocumentUkmSourceId(); + ASSERT_EQ(1u, main_frame_host->child_count()); RenderFrameHostImpl* sub_frame_host = static_cast<RenderFrameHostImpl*>( main_frame_host->child_at(0)->current_frame_host()); ukm::SourceId subframe_doc_ukm_source_id =
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc index bdb57be8..256d93a 100644 --- a/content/browser/security_exploit_browsertest.cc +++ b/content/browser/security_exploit_browsertest.cc
@@ -970,7 +970,7 @@ // Sanity check of test setup: main frame and subframe should be isolated. WebContents* web_contents = shell()->web_contents(); RenderFrameHost* main_frame = web_contents->GetMainFrame(); - RenderFrameHost* subframe = web_contents->GetAllFrames()[1]; + RenderFrameHost* subframe = ChildFrameAt(main_frame, 0); EXPECT_NE(main_frame->GetProcess(), subframe->GetProcess()); // We need to get ahold of the RenderFrameProxyHost representing the main @@ -1019,8 +1019,8 @@ RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>( shell()->web_contents()->GetMainFrame()); RenderProcessHost* main_process = main_frame->GetProcess(); - EXPECT_EQ(2u, shell()->web_contents()->GetAllFrames().size()); - RenderFrameHost* subframe = shell()->web_contents()->GetAllFrames()[1]; + RenderFrameHost* subframe = ChildFrameAt(main_frame, 0); + ASSERT_TRUE(subframe); RenderProcessHost* subframe_process = subframe->GetProcess(); EXPECT_NE(main_process->GetID(), subframe_process->GetID());
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.cc b/content/browser/service_worker/service_worker_controllee_request_handler.cc index f2627bcb..3f9b97c 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.cc +++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -397,9 +397,6 @@ DCHECK_EQ(active_version, container_host_->controller()); DCHECK_NE(active_version->fetch_handler_existence(), ServiceWorkerVersion::FetchHandlerExistence::UNKNOWN); - ServiceWorkerMetrics::CountControlledPageLoad( - active_version->site_for_uma(), - destination_ == network::mojom::RequestDestination::kDocument); if (blink::IsRequestDestinationFrame(destination_)) container_host_->AddServiceWorkerToUpdate(active_version);
diff --git a/content/browser/service_worker/service_worker_metrics.cc b/content/browser/service_worker/service_worker_metrics.cc index bf06b97..3eaa314 100644 --- a/content/browser/service_worker/service_worker_metrics.cc +++ b/content/browser/service_worker/service_worker_metrics.cc
@@ -207,36 +207,6 @@ return "error"; } -ServiceWorkerMetrics::Site ServiceWorkerMetrics::SiteFromURL(const GURL& url) { - // TODO(falken): Plumb through ContentBrowserClient::GetMetricSuffixForURL or - // figure out a way to remove ServiceWorkerMetrics::Site entirely instead of - // hardcoding sites in //content. - - // This inaccurately matches google.example.com, see the TODO above. - static const char google_like_scope_prefix[] = "https://www.google."; - static const char ntp_scope_path[] = "/_/chrome/"; - if (base::StartsWith(url.spec(), google_like_scope_prefix, - base::CompareCase::INSENSITIVE_ASCII) && - base::StartsWith(url.path(), ntp_scope_path, - base::CompareCase::SENSITIVE)) { - return ServiceWorkerMetrics::Site::NEW_TAB_PAGE; - } - - const base::StringPiece host = url.host_piece(); - if (host == "plus.google.com") - return ServiceWorkerMetrics::Site::PLUS; - if (host == "inbox.google.com") - return ServiceWorkerMetrics::Site::INBOX; - if (host == "docs.google.com") - return ServiceWorkerMetrics::Site::DOCS; - if (host == "drive.google.com") { - // TODO(falken): This should not be DOCS but historically we logged them - // together. - return ServiceWorkerMetrics::Site::DOCS; - } - return ServiceWorkerMetrics::Site::OTHER; -} - void ServiceWorkerMetrics::CountReadResponseResult( ServiceWorkerMetrics::ReadResponseResult result) { UMA_HISTOGRAM_ENUMERATION("ServiceWorker.DiskCache.ReadResponseResult", @@ -249,15 +219,6 @@ result, NUM_WRITE_RESPONSE_RESULT_TYPES); } -void ServiceWorkerMetrics::CountControlledPageLoad(Site site, - bool is_main_frame_load) { - DCHECK_NE(site, Site::OTHER); - UMA_HISTOGRAM_ENUMERATION("ServiceWorker.PageLoad", site); - if (is_main_frame_load) { - UMA_HISTOGRAM_ENUMERATION("ServiceWorker.MainFramePageLoad", site); - } -} - void ServiceWorkerMetrics::RecordStartInstalledWorkerStatus( blink::ServiceWorkerStatusCode status, EventType purpose) { @@ -356,8 +317,7 @@ } break; case EventType::FETCH_WAITUNTIL: - UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.FetchEvent.WaitUntil.Time", - time); + // Do nothing: the histogram has been removed. break; case EventType::SYNC: UMA_HISTOGRAM_MEDIUM_TIMES("ServiceWorker.BackgroundSyncEvent.Time",
diff --git a/content/browser/service_worker/service_worker_metrics.h b/content/browser/service_worker/service_worker_metrics.h index 3cb4b08..450b5fd 100644 --- a/content/browser/service_worker/service_worker_metrics.h +++ b/content/browser/service_worker/service_worker_metrics.h
@@ -13,8 +13,6 @@ #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "ui/base/page_transition_types.h" -class GURL; - namespace content { class ServiceWorkerMetrics { @@ -94,19 +92,6 @@ kMaxValue = PUSH_SUBSCRIPTION_CHANGE, }; - // Used for UMA. Append only. - enum class Site { - OTHER, // Obsolete for UMA. Use WITH_FETCH_HANDLER or - // WITHOUT_FETCH_HANDLER. - NEW_TAB_PAGE, - WITH_FETCH_HANDLER, - WITHOUT_FETCH_HANDLER, - PLUS, - INBOX, - DOCS, - kMaxValue = DOCS, - }; - // Not used for UMA. enum class StartSituation { // Failed to allocate a process. @@ -169,18 +154,11 @@ // Converts a start situation to a string. Used for tracing. static const char* StartSituationToString(StartSituation start_situation); - // If the |url| is not a special site, returns Site::OTHER. - static Site SiteFromURL(const GURL& url); - // Counts the result of reading a service worker script from storage. static void CountReadResponseResult(ReadResponseResult result); // Counts the result of writing a service worker script to storage. static void CountWriteResponseResult(WriteResponseResult result); - // Counts the number of page loads controlled by a Service Worker. - static void CountControlledPageLoad(Site site, - bool is_main_frame_load); - // Records the result of trying to start an installed worker. static void RecordStartInstalledWorkerStatus( blink::ServiceWorkerStatusCode status,
diff --git a/content/browser/service_worker/service_worker_test_utils.h b/content/browser/service_worker/service_worker_test_utils.h index c82c44b..9b56f89 100644 --- a/content/browser/service_worker/service_worker_test_utils.h +++ b/content/browser/service_worker/service_worker_test_utils.h
@@ -41,26 +41,6 @@ class ServiceWorkerStorage; class ServiceWorkerVersion; -template <typename Arg> -void ReceiveResult(BrowserThread::ID run_quit_thread, - base::OnceClosure quit, - absl::optional<Arg>* out, - Arg actual) { - *out = actual; - if (!quit.is_null()) { - BrowserThread::GetTaskRunnerForThread(run_quit_thread) - ->PostTask(FROM_HERE, std::move(quit)); - } -} - -template <typename Arg> -base::OnceCallback<void(Arg)> CreateReceiver(BrowserThread::ID run_quit_thread, - base::OnceClosure quit, - absl::optional<Arg>* out) { - return base::BindOnce(&ReceiveResult<Arg>, run_quit_thread, std::move(quit), - out); -} - base::OnceCallback<void(blink::ServiceWorkerStatusCode)> ReceiveServiceWorkerStatus(absl::optional<blink::ServiceWorkerStatusCode>* out, base::OnceClosure quit_closure);
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index ca36bb2..ce1e7664 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -250,7 +250,6 @@ scope_(registration->scope()), script_type_(script_type), fetch_handler_existence_(FetchHandlerExistence::UNKNOWN), - site_for_uma_(ServiceWorkerMetrics::SiteFromURL(scope_)), registration_status_(registration->status()), context_(context), script_cache_map_(this, context), @@ -413,12 +412,6 @@ DCHECK_EQ(fetch_handler_existence_, FetchHandlerExistence::UNKNOWN); DCHECK_NE(existence, FetchHandlerExistence::UNKNOWN); fetch_handler_existence_ = existence; - if (site_for_uma_ != ServiceWorkerMetrics::Site::OTHER) - return; - if (existence == FetchHandlerExistence::EXISTS) - site_for_uma_ = ServiceWorkerMetrics::Site::WITH_FETCH_HANDLER; - else - site_for_uma_ = ServiceWorkerMetrics::Site::WITHOUT_FETCH_HANDLER; } void ServiceWorkerVersion::StartWorker(ServiceWorkerMetrics::EventType purpose, @@ -1721,13 +1714,14 @@ if (!request) return; // Copy error callback before calling FinishRequest. - StatusCallback callback = std::move(request->error_callback); + StatusCallback error_callback = std::move(request->error_callback); FinishRequest(request_id, status == blink::mojom::ServiceWorkerEventStatus::COMPLETED); - - std::move(callback).Run( - mojo::ConvertTo<blink::ServiceWorkerStatusCode>(status)); + // TODO(http://crbug.com/1251834): Why are we running the "error callback" + // even when there is no error? Clean this up. + std::move(error_callback) + .Run(mojo::ConvertTo<blink::ServiceWorkerStatusCode>(status)); } void ServiceWorkerVersion::CountFeature(blink::mojom::WebFeature feature) {
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index 33da2093..3295e88b 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -224,7 +224,6 @@ FetchHandlerExistence fetch_handler_existence() const { return fetch_handler_existence_; } - // This also updates |site_for_uma_| when it was Site::OTHER. void set_fetch_handler_existence(FetchHandlerExistence existence); base::TimeDelta TimeSinceNoControllees() const { @@ -252,8 +251,6 @@ void SetRegistrationStatus( ServiceWorkerRegistration::Status registration_status); - ServiceWorkerMetrics::Site site_for_uma() const { return site_for_uma_; } - // This sets the new status and also run status change callbacks // if there're any (see RegisterStatusChangeCallback). void SetStatus(Status status); @@ -308,10 +305,12 @@ // called. If FinishRequest is not called the request will eventually time // out and the worker will be forcibly terminated. // - // The |error_callback| is called if either ServiceWorkerVersion decides the + // `error_callback` is called if either ServiceWorkerVersion decides the // event is taking too long, or if for some reason the worker stops or is // killed before the request finishes. In this case, the caller should not - // call FinishRequest. + // call FinishRequest. EXCEPTION: If CreateSimpleEventCallback() is used, + // `error_callback` is always called, even in the case of success. + // TODO(http://crbug.com/1251834): Clean up this exception. int StartRequest(ServiceWorkerMetrics::EventType event_type, StatusCallback error_callback); @@ -930,7 +929,6 @@ // cached value because it must be looked up quickly and a live registration // doesn't necessarily exist whenever there is a live version. blink::mojom::NavigationPreloadState navigation_preload_state_; - ServiceWorkerMetrics::Site site_for_uma_; // A copy of ServiceWorkerRegistration::status(). Cached for the same reason // as `navigation_preload_state_`: A live registration doesn't necessarily
diff --git a/content/browser/service_worker/service_worker_version_browsertest.cc b/content/browser/service_worker/service_worker_version_browsertest.cc index 54f6aca..fd18436 100644 --- a/content/browser/service_worker/service_worker_version_browsertest.cc +++ b/content/browser/service_worker/service_worker_version_browsertest.cc
@@ -113,25 +113,6 @@ return base::BindOnce(&ReceivePrepareResult, is_prepared); } -void ReceiveFindRegistrationStatus( - BrowserThread::ID run_quit_thread, - base::OnceClosure quit, - blink::ServiceWorkerStatusCode* out_status, - blink::ServiceWorkerStatusCode status, - scoped_refptr<ServiceWorkerRegistration> registration) { - *out_status = status; - if (!quit.is_null()) - RunOrPostTaskOnThread(FROM_HERE, run_quit_thread, std::move(quit)); -} - -ServiceWorkerRegistry::FindRegistrationCallback CreateFindRegistrationReceiver( - BrowserThread::ID run_quit_thread, - base::OnceClosure quit, - blink::ServiceWorkerStatusCode* status) { - return base::BindOnce(&ReceiveFindRegistrationStatus, run_quit_thread, - std::move(quit), status); -} - void ExpectRegisterResultAndRun(blink::ServiceWorkerStatusCode expected, base::RepeatingClosure continuation, blink::ServiceWorkerStatusCode actual) { @@ -357,31 +338,55 @@ void TearDownOnMainThread() override { wrapper_.reset(); } - void InstallTestHelper(const std::string& worker_url, - blink::ServiceWorkerStatusCode expected_status, - blink::mojom::ScriptType script_type = - blink::mojom::ScriptType::kClassic) { + blink::ServiceWorkerStatusCode Install( + const std::string& worker_url, + blink::mojom::ScriptType script_type = + blink::mojom::ScriptType::kClassic) { SetUpRegistrationWithScriptType(worker_url, script_type); + blink::ServiceWorkerStatusCode status; - // Dispatch install on a worker. - absl::optional<blink::ServiceWorkerStatusCode> status; + // Start the worker. + base::RunLoop start_run_loop; + version_->RunAfterStartWorker( + ServiceWorkerMetrics::EventType::INSTALL, + base::BindLambdaForTesting( + [&](blink::ServiceWorkerStatusCode start_status) { + ASSERT_EQ(start_status, blink::ServiceWorkerStatusCode::kOk); + start_run_loop.Quit(); + })); + start_run_loop.Run(); + + // Dispatch install event. base::RunLoop install_run_loop; - Install(install_run_loop.QuitClosure(), &status); + DispatchInstallEvent(base::BindLambdaForTesting( + [&](blink::ServiceWorkerStatusCode install_status) { + status = install_status; + install_run_loop.Quit(); + })); install_run_loop.Run(); - ASSERT_EQ(expected_status, status.value()); // Stop the worker. base::RunLoop stop_run_loop; StopWorker(stop_run_loop.QuitClosure()); stop_run_loop.Run(); + + return status; } - void ActivateTestHelper(blink::ServiceWorkerStatusCode expected_status) { - absl::optional<blink::ServiceWorkerStatusCode> status; + blink::ServiceWorkerStatusCode Activate() { + blink::ServiceWorkerStatusCode status; base::RunLoop run_loop; - Activate(run_loop.QuitClosure(), &status); + version_->RunAfterStartWorker( + ServiceWorkerMetrics::EventType::ACTIVATE, + base::BindOnce(&ServiceWorkerVersionBrowserTest::DispatchActivateEvent, + base::Unretained(this), + base::BindLambdaForTesting( + [&](blink::ServiceWorkerStatusCode actual_status) { + status = actual_status; + run_loop.Quit(); + }))); run_loop.Run(); - ASSERT_EQ(expected_status, status.value()); + return status; } void FetchOnRegisteredWorker( @@ -465,13 +470,16 @@ registration_->ActivateWaitingVersionWhenReady(); } - void StartWorker(blink::ServiceWorkerStatusCode expected_status) { - ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); - absl::optional<blink::ServiceWorkerStatusCode> status; - base::RunLoop start_run_loop; - StartWorker(start_run_loop.QuitClosure(), &status); - start_run_loop.Run(); - ASSERT_EQ(expected_status, status.value()); + blink::ServiceWorkerStatusCode StartWorker() { + base::RunLoop run_loop; + blink::ServiceWorkerStatusCode status; + StartWorkerAsync(base::BindLambdaForTesting( + [&](blink::ServiceWorkerStatusCode actual_status) { + status = actual_status; + run_loop.Quit(); + })); + run_loop.Run(); + return status; } void StopWorker() { @@ -484,96 +492,108 @@ void StoreRegistration(int64_t version_id, blink::ServiceWorkerStatusCode expected_status) { ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); - absl::optional<blink::ServiceWorkerStatusCode> status; - base::RunLoop store_run_loop; + base::RunLoop run_loop; + blink::ServiceWorkerStatusCode status; ServiceWorkerVersion* version = wrapper()->context()->GetLiveVersion(version_id); wrapper()->context()->registry()->StoreRegistration( registration_.get(), version, - CreateReceiver(BrowserThread::UI, store_run_loop.QuitClosure(), - &status)); - store_run_loop.Run(); - ASSERT_EQ(expected_status, status.value()); + base::BindLambdaForTesting( + [&](blink::ServiceWorkerStatusCode actual_status) { + ASSERT_EQ(actual_status, expected_status); + status = actual_status; + run_loop.Quit(); + })); + run_loop.Run(); wrapper()->context()->registry()->NotifyDoneInstallingRegistration( - registration_.get(), version_.get(), *status); + registration_.get(), version_.get(), status); } void UpdateRegistration(int64_t registration_id, blink::ServiceWorkerStatusCode* out_status, bool* out_update_found) { - base::RunLoop update_run_loop; - Update(registration_id, - base::BindOnce(&self::ReceiveUpdateResult, base::Unretained(this), - update_run_loop.QuitClosure(), out_status, - out_update_found)); - update_run_loop.Run(); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + base::RunLoop run_loop; + scoped_refptr<ServiceWorkerRegistration> registration = + wrapper()->context()->GetLiveRegistration(registration_id); + ASSERT_TRUE(registration); + wrapper()->context()->UpdateServiceWorker( + registration.get(), false /* force_bypass_cache */, + false /* skip_script_comparison */, + blink::mojom::FetchClientSettingsObject::New(), + base::BindLambdaForTesting([&](blink::ServiceWorkerStatusCode status, + const std::string& message, + int64_t registration_id) { + ASSERT_EQ(wrapper()->context()->GetLiveRegistration(registration_id), + registration); + *out_status = status; + *out_update_found = !!registration->installing_version(); + run_loop.Quit(); + })); + + run_loop.Run(); } - void FindRegistrationForId(int64_t id, - const blink::StorageKey& key, - blink::ServiceWorkerStatusCode expected_status) { - ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); + blink::ServiceWorkerStatusCode FindRegistrationForId( + int64_t id, + const blink::StorageKey& key) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); blink::ServiceWorkerStatusCode status = blink::ServiceWorkerStatusCode::kErrorFailed; base::RunLoop run_loop; wrapper()->context()->registry()->FindRegistrationForId( id, key, - CreateFindRegistrationReceiver(BrowserThread::UI, - run_loop.QuitClosure(), &status)); + base::BindLambdaForTesting( + [&](blink::ServiceWorkerStatusCode actual_status, + scoped_refptr<ServiceWorkerRegistration> registration) { + status = actual_status; + run_loop.Quit(); + })); run_loop.Run(); - ASSERT_EQ(expected_status, status); + return status; } - void StartWorker(base::OnceClosure done, - absl::optional<blink::ServiceWorkerStatusCode>* result) { + void StartWorkerAsync( + base::OnceCallback<void(blink::ServiceWorkerStatusCode status)> + callback) { ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); version_->SetMainScriptResponse(CreateMainScriptResponse()); - version_->StartWorker( - ServiceWorkerMetrics::EventType::UNKNOWN, - CreateReceiver(BrowserThread::UI, std::move(done), result)); - } - - void Install(const base::RepeatingClosure& done, - absl::optional<blink::ServiceWorkerStatusCode>* result) { - ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); - version_->RunAfterStartWorker( - ServiceWorkerMetrics::EventType::INSTALL, - base::BindOnce(&self::DispatchInstallEvent, base::Unretained(this), - done, result)); + version_->StartWorker(ServiceWorkerMetrics::EventType::UNKNOWN, + std::move(callback)); } void DispatchInstallEvent( - base::OnceClosure done, - absl::optional<blink::ServiceWorkerStatusCode>* result, - blink::ServiceWorkerStatusCode start_worker_status) { + base::OnceCallback<void(blink::ServiceWorkerStatusCode status)> + callback) { ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); - ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, start_worker_status); + ASSERT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status()); version_->SetStatus(ServiceWorkerVersion::INSTALLING); - auto callback_pair = base::SplitOnceCallback(std::move(done)); + auto callback_pair = base::SplitOnceCallback(std::move(callback)); int request_id = version_->StartRequest( ServiceWorkerMetrics::EventType::INSTALL, - CreateReceiver(BrowserThread::UI, std::move(callback_pair.first), - result)); - version_->endpoint()->DispatchInstallEvent( - base::BindOnce(&self::ReceiveInstallEvent, base::Unretained(this), - std::move(callback_pair.second), result, request_id)); + base::BindLambdaForTesting( + [&](blink::ServiceWorkerStatusCode error_status) { + std::move(callback_pair.first).Run(error_status); + })); + version_->endpoint()->DispatchInstallEvent(base::BindOnce( + &ServiceWorkerVersionBrowserTest::ReceiveInstallEvent, + base::Unretained(this), std::move(callback_pair.second), request_id)); } - void ReceiveInstallEvent( - base::OnceClosure done, - absl::optional<blink::ServiceWorkerStatusCode>* out_result, - int request_id, - blink::mojom::ServiceWorkerEventStatus status, - uint32_t fetch_count) { + void ReceiveInstallEvent(ServiceWorkerVersion::StatusCallback callback, + int request_id, + blink::mojom::ServiceWorkerEventStatus status, + uint32_t fetch_count) { version_->FinishRequestWithFetchCount( request_id, status == blink::mojom::ServiceWorkerEventStatus::COMPLETED, fetch_count); - *out_result = mojo::ConvertTo<blink::ServiceWorkerStatusCode>(status); - if (!done.is_null()) - RunOrPostTaskOnThread(FROM_HERE, BrowserThread::UI, std::move(done)); + if (callback) { + std::move(callback).Run( + mojo::ConvertTo<blink::ServiceWorkerStatusCode>(status)); + } } void Store(base::OnceClosure done, @@ -582,57 +602,24 @@ ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); } - void Activate(base::OnceClosure done, - absl::optional<blink::ServiceWorkerStatusCode>* result) { - ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); - version_->RunAfterStartWorker( - ServiceWorkerMetrics::EventType::ACTIVATE, - base::BindOnce(&self::DispatchActivateEvent, base::Unretained(this), - std::move(done), result)); - } - void DispatchActivateEvent( - base::OnceClosure done, - absl::optional<blink::ServiceWorkerStatusCode>* result, + ServiceWorkerVersion::StatusCallback callback, blink::ServiceWorkerStatusCode start_worker_status) { ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, start_worker_status); version_->SetStatus(ServiceWorkerVersion::ACTIVATING); registration_->SetActiveVersion(version_.get()); + // Using CreateSimpleEventCallback() causes `callback` to be + // called when the event finishes successfully, even though + // it is called the "error callback" to StartRequest(). + // TODO(https://crbug.com/1251834): Clean up the callback handling for + // StartRequest(). int request_id = version_->StartRequest( - ServiceWorkerMetrics::EventType::INSTALL, - CreateReceiver(BrowserThread::UI, std::move(done), result)); + ServiceWorkerMetrics::EventType::ACTIVATE, std::move(callback)); version_->endpoint()->DispatchActivateEvent( version_->CreateSimpleEventCallback(request_id)); } - void Update(int registration_id, - ServiceWorkerContextCore::UpdateCallback callback) { - ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); - scoped_refptr<ServiceWorkerRegistration> registration = - wrapper()->context()->GetLiveRegistration(registration_id); - ASSERT_TRUE(registration); - wrapper()->context()->UpdateServiceWorker( - registration.get(), false /* force_bypass_cache */, - false /* skip_script_comparison */, - blink::mojom::FetchClientSettingsObject::New(), std::move(callback)); - } - - void ReceiveUpdateResult(const base::RepeatingClosure& done_on_ui, - blink::ServiceWorkerStatusCode* out_status, - bool* out_update_found, - blink::ServiceWorkerStatusCode status, - const std::string& status_message, - int64_t registration_id) { - scoped_refptr<ServiceWorkerRegistration> registration = - wrapper()->context()->GetLiveRegistration(registration_id); - DCHECK(registration); - - *out_status = status; - *out_update_found = !!registration->installing_version(); - RunOrPostTaskOnThread(FROM_HERE, BrowserThread::UI, done_on_ui); - } - void Fetch(base::OnceClosure done, const std::string& path, bool* prepare_result, @@ -662,14 +649,12 @@ } void SetLastUpdateCheck(int64_t registration_id, - base::Time last_update_time, - const base::RepeatingClosure& done_on_ui) { + base::Time last_update_time) { ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); scoped_refptr<ServiceWorkerRegistration> registration = wrapper()->context()->GetLiveRegistration(registration_id); ASSERT_TRUE(registration); registration->set_last_update_check(last_update_time); - RunOrPostTaskOnThread(FROM_HERE, BrowserThread::UI, done_on_ui); } // Contrary to the style guide, the output parameter of this function comes @@ -690,8 +675,8 @@ out_result->status = actual_status; out_result->result = actual_result; out_result->response = std::move(actual_response); - if (!quit.is_null()) - RunOrPostTaskOnThread(FROM_HERE, BrowserThread::UI, std::move(quit)); + if (quit) + std::move(quit).Run(); } ServiceWorkerFetchDispatcher::FetchCallback CreateResponseReceiver( @@ -793,9 +778,7 @@ void OnRunningStateChanged(ServiceWorkerVersion* version) override { if (version->running_status() == EmbeddedWorkerStatus::STOPPED) { - DCHECK(quit_closure_); - RunOrPostTaskOnThread(FROM_HERE, BrowserThread::UI, - std::move(quit_closure_)); + std::move(quit_closure_).Run(); } } @@ -808,11 +791,7 @@ SetUpRegistration("/service_worker/worker.js"); // Start a worker. - absl::optional<blink::ServiceWorkerStatusCode> status; - base::RunLoop start_run_loop; - StartWorker(start_run_loop.QuitClosure(), &status); - start_run_loop.Run(); - ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value()); + ASSERT_EQ(StartWorker(), blink::ServiceWorkerStatusCode::kOk); // Stop the worker. base::RunLoop stop_run_loop; @@ -826,12 +805,9 @@ DropCountsOnBlinkUseCounter) { StartServerAndNavigateToSetup(); SetUpRegistration("/service_worker/worker.js"); + // Start a worker. - absl::optional<blink::ServiceWorkerStatusCode> status; - base::RunLoop start_run_loop; - StartWorker(start_run_loop.QuitClosure(), &status); - start_run_loop.Run(); - ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value()); + ASSERT_EQ(StartWorker(), blink::ServiceWorkerStatusCode::kOk); // Expect no PageVisits count. EXPECT_EQ(nullptr, base::StatisticsRecorder::FindHistogram( @@ -851,7 +827,7 @@ SetUpRegistration("/service_worker/nonexistent.js"); // Start a worker for nonexistent URL. - StartWorker(blink::ServiceWorkerStatusCode::kErrorNetwork); + EXPECT_EQ(StartWorker(), blink::ServiceWorkerStatusCode::kErrorNetwork); } IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, ReadResourceFailure) { @@ -873,12 +849,12 @@ blink::ServiceWorkerStatusCode::kOk); // Start the worker. We'll fail to read the resource. - StartWorker(blink::ServiceWorkerStatusCode::kErrorDiskCache); + EXPECT_EQ(StartWorker(), blink::ServiceWorkerStatusCode::kErrorDiskCache); EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version_->status()); // The registration should be deleted from storage. - FindRegistrationForId(registration_->id(), registration_->key(), - blink::ServiceWorkerStatusCode::kErrorNotFound); + EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound, + FindRegistrationForId(registration_->id(), registration_->key())); EXPECT_TRUE(registration_->is_uninstalled()); } @@ -886,9 +862,9 @@ ReadResourceFailure_WaitingWorker) { StartServerAndNavigateToSetup(); // Create a registration and active version. - InstallTestHelper("/service_worker/worker.js", - blink::ServiceWorkerStatusCode::kOk); - ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(Install("/service_worker/worker.js"), + blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(Activate(), blink::ServiceWorkerStatusCode::kOk); ASSERT_TRUE(registration_->active_version()); // Give the version a controllee. @@ -914,34 +890,34 @@ // Start the broken worker. We'll fail to read from disk and the worker should // be doomed. StopWorker(); // in case it's already running - StartWorker(blink::ServiceWorkerStatusCode::kErrorDiskCache); + EXPECT_EQ(StartWorker(), blink::ServiceWorkerStatusCode::kErrorDiskCache); EXPECT_EQ(ServiceWorkerVersion::REDUNDANT, version_->status()); // The whole registration should be deleted from storage even though the // waiting version was not the broken one. - FindRegistrationForId(registration_->id(), registration_->key(), - blink::ServiceWorkerStatusCode::kErrorNotFound); + EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorNotFound, + FindRegistrationForId(registration_->id(), registration_->key())); EXPECT_TRUE(registration_->is_uninstalled()); } IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, Install) { StartServerAndNavigateToSetup(); - InstallTestHelper("/service_worker/worker.js", - blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Install("/service_worker/worker.js"), + blink::ServiceWorkerStatusCode::kOk); } IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, InstallWithWaitUntil_Fulfilled) { StartServerAndNavigateToSetup(); - InstallTestHelper("/service_worker/worker_install_fulfilled.js", - blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Install("/service_worker/worker_install_fulfilled.js"), + blink::ServiceWorkerStatusCode::kOk); } IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, InstallWithFetchHandler) { StartServerAndNavigateToSetup(); - InstallTestHelper("/service_worker/fetch_event.js", - blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(Install("/service_worker/fetch_event.js"), + blink::ServiceWorkerStatusCode::kOk); EXPECT_EQ(ServiceWorkerVersion::FetchHandlerExistence::EXISTS, version_->fetch_handler_existence()); } @@ -949,8 +925,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, InstallWithoutFetchHandler) { StartServerAndNavigateToSetup(); - InstallTestHelper("/service_worker/worker.js", - blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(Install("/service_worker/worker.js"), + blink::ServiceWorkerStatusCode::kOk); EXPECT_EQ(ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST, version_->fetch_handler_existence()); } @@ -960,8 +936,8 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchHandlerSetInInstallEvent) { StartServerAndNavigateToSetup(); - InstallTestHelper("/service_worker/fetch_event_set_in_install_event.js", - blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(Install("/service_worker/fetch_event_set_in_install_event.js"), + blink::ServiceWorkerStatusCode::kOk); EXPECT_EQ(ServiceWorkerVersion::FetchHandlerExistence::DOES_NOT_EXIST, version_->fetch_handler_existence()); } @@ -973,33 +949,32 @@ embedded_test_server()->RegisterRequestHandler( base::BindRepeating(&VerifyServiceWorkerHeaderInRequest)); StartServerAndNavigateToSetup(); - InstallTestHelper("/service_worker/generated_sw.js", - blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Install("/service_worker/generated_sw.js"), + blink::ServiceWorkerStatusCode::kOk); } IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, Activate_NoEventListener) { StartServerAndNavigateToSetup(); - InstallTestHelper("/service_worker/worker.js", - blink::ServiceWorkerStatusCode::kOk); - ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk); - ASSERT_EQ(ServiceWorkerVersion::ACTIVATING, version_->status()); + ASSERT_EQ(Install("/service_worker/worker.js"), + blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Activate(), blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(ServiceWorkerVersion::ACTIVATING, version_->status()); } IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, Activate_Rejected) { StartServerAndNavigateToSetup(); - InstallTestHelper("/service_worker/worker_activate_rejected.js", - blink::ServiceWorkerStatusCode::kOk); - ActivateTestHelper( - blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected); + ASSERT_EQ(Install("/service_worker/worker_activate_rejected.js"), + blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Activate(), + blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected); } IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, InstallWithWaitUntil_Rejected) { StartServerAndNavigateToSetup(); - InstallTestHelper( - "/service_worker/worker_install_rejected.js", - blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected); + EXPECT_EQ(Install("/service_worker/worker_install_rejected.js"), + blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected); } IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, @@ -1010,16 +985,22 @@ ConsoleListener console_listener; version_->embedded_worker()->AddObserver(&console_listener); - // Dispatch install on a worker. - absl::optional<blink::ServiceWorkerStatusCode> status; - base::RunLoop install_run_loop; - Install(install_run_loop.QuitClosure(), &status); - install_run_loop.Run(); - ASSERT_EQ(blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected, - status.value()); + // Start the worker. + ASSERT_EQ(StartWorker(), blink::ServiceWorkerStatusCode::kOk); + + // Dispatch install. + base::RunLoop run_loop; + DispatchInstallEvent( + base::BindLambdaForTesting([&](blink::ServiceWorkerStatusCode status) { + EXPECT_EQ(status, + blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected); + run_loop.Quit(); + })); const std::u16string expected = u"Rejecting oninstall event"; console_listener.WaitForConsoleMessages(1); + run_loop.Run(); + ASSERT_NE(std::u16string::npos, console_listener.messages()[0].find(expected)); version_->embedded_worker()->RemoveObserver(&console_listener); @@ -1031,9 +1012,9 @@ StartServerAndNavigateToSetup(); // Install a service worker. - InstallTestHelper("/service_worker/worker_with_one_import.js", - blink::ServiceWorkerStatusCode::kOk, - blink::mojom::ScriptType::kClassic); + EXPECT_EQ(Install("/service_worker/worker_with_one_import.js", + blink::mojom::ScriptType::kClassic), + blink::ServiceWorkerStatusCode::kOk); EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status()); // Emulate offline by stopping the test server. @@ -1041,7 +1022,7 @@ EXPECT_FALSE(embedded_test_server()->Started()); // Restart the worker while offline. - StartWorker(blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(StartWorker(), blink::ServiceWorkerStatusCode::kOk); } // Tests starting an installed module service worker while offline. @@ -1050,9 +1031,9 @@ StartServerAndNavigateToSetup(); // Install a service worker. - InstallTestHelper("/service_worker/static_import_worker.js", - blink::ServiceWorkerStatusCode::kOk, - blink::mojom::ScriptType::kModule); + ASSERT_EQ(Install("/service_worker/static_import_worker.js", + blink::mojom::ScriptType::kModule), + blink::ServiceWorkerStatusCode::kOk); EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status()); // Emulate offline by stopping the test server. @@ -1060,7 +1041,7 @@ EXPECT_FALSE(embedded_test_server()->Started()); // Restart the worker while offline. - StartWorker(blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(StartWorker(), blink::ServiceWorkerStatusCode::kOk); } IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, TimeoutStartingWorker) { @@ -1074,7 +1055,12 @@ WaitForLoaded wait_for_load(load_run_loop.QuitClosure()); version_->embedded_worker()->AddObserver(&wait_for_load); - StartWorker(start_run_loop.QuitClosure(), &status); + StartWorkerAsync(base::BindLambdaForTesting( + [&](blink::ServiceWorkerStatusCode actual_status) { + status = actual_status; + start_run_loop.Quit(); + })); + load_run_loop.Run(); version_->embedded_worker()->RemoveObserver(&wait_for_load); @@ -1096,15 +1082,16 @@ SetUpRegistration("/service_worker/while_true_in_install_worker.js"); // Start a worker. - absl::optional<blink::ServiceWorkerStatusCode> status; - base::RunLoop start_run_loop; - StartWorker(start_run_loop.QuitClosure(), &status); - start_run_loop.Run(); - ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, status.value()); + ASSERT_EQ(StartWorker(), blink::ServiceWorkerStatusCode::kOk); // Dispatch an event. base::RunLoop install_run_loop; - Install(install_run_loop.QuitClosure(), &status); + blink::ServiceWorkerStatusCode status; + DispatchInstallEvent(base::BindLambdaForTesting( + [&](blink::ServiceWorkerStatusCode actual_status) { + status = actual_status; + install_run_loop.Quit(); + })); // Simulate execution timeout. Use a delay to prevent killing the worker // before it's started execution. @@ -1115,16 +1102,16 @@ // Terminating a worker, even one in an infinite loop, is treated as if // waitUntil was rejected in the renderer code. EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorEventWaitUntilRejected, - status.value()); + status); } IN_PROC_BROWSER_TEST_F(ServiceWorkerVersionBrowserTest, FetchEvent_Response) { StartServerAndNavigateToSetup(); ServiceWorkerFetchDispatcher::FetchEventResult result; blink::mojom::FetchAPIResponsePtr response; - InstallTestHelper("/service_worker/fetch_event.js", - blink::ServiceWorkerStatusCode::kOk); - ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(Install("/service_worker/fetch_event.js"), + blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Activate(), blink::ServiceWorkerStatusCode::kOk); FetchOnRegisteredWorker("/service_worker/empty.html", &result, &response); ASSERT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse, @@ -1154,9 +1141,9 @@ ServiceWorkerFetchDispatcher::FetchEventResult result; blink::mojom::FetchAPIResponsePtr response1; blink::mojom::FetchAPIResponsePtr response2; - InstallTestHelper("/service_worker/fetch_event_respond_with_fetch.js", - blink::ServiceWorkerStatusCode::kOk); - ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(Install("/service_worker/fetch_event_respond_with_fetch.js"), + blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Activate(), blink::ServiceWorkerStatusCode::kOk); // The first fetch() response should come from network. FetchOnRegisteredWorker(kPath, &result, &response1); @@ -1184,9 +1171,9 @@ ServiceWorkerFetchDispatcher::FetchEventResult result; blink::mojom::FetchAPIResponsePtr response1; blink::mojom::FetchAPIResponsePtr response2; - InstallTestHelper("/service_worker/fetch_event_response_via_cache.js", - blink::ServiceWorkerStatusCode::kOk); - ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(Install("/service_worker/fetch_event_response_via_cache.js"), + blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Activate(), blink::ServiceWorkerStatusCode::kOk); // The first fetch() response should come from network. FetchOnRegisteredWorker(kPath, &result, &response1); @@ -1213,9 +1200,9 @@ StartServerAndNavigateToSetup(); ServiceWorkerFetchDispatcher::FetchEventResult result; blink::mojom::FetchAPIResponsePtr response; - InstallTestHelper("/service_worker/fetch_event_rejected.js", - blink::ServiceWorkerStatusCode::kOk); - ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(Install("/service_worker/fetch_event_rejected.js"), + blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Activate(), blink::ServiceWorkerStatusCode::kOk); ConsoleListener console_listener; version_->embedded_worker()->AddObserver(&console_listener); @@ -1294,10 +1281,7 @@ // Set the last update time far in the past. { last_update_time = base::Time::Now() - base::TimeDelta::FromHours(24); - base::RunLoop time_run_loop; - SetLastUpdateCheck(registration_id, last_update_time, - time_run_loop.QuitClosure()); - time_run_loop.Run(); + SetLastUpdateCheck(registration_id, last_update_time); } // Try to update again. The browser cache should be bypassed so the update @@ -1376,8 +1360,8 @@ ContentBrowserClient* old_client = SetBrowserClientForTesting(&content_browser_client); shell()->web_contents()->OnWebPreferencesChanged(); - InstallTestHelper("/service_worker/fetch_in_install.js", - blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Install("/service_worker/fetch_in_install.js"), + blink::ServiceWorkerStatusCode::kOk); SetBrowserClientForTesting(old_client); } @@ -1391,8 +1375,8 @@ ContentBrowserClient* old_client = SetBrowserClientForTesting(&content_browser_client); shell()->web_contents()->OnWebPreferencesChanged(); - InstallTestHelper("/service_worker/generated_sw.js", - blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Install("/service_worker/generated_sw.js"), + blink::ServiceWorkerStatusCode::kOk); SetBrowserClientForTesting(old_client); } @@ -1403,8 +1387,8 @@ MockContentBrowserClient content_browser_client; ContentBrowserClient* old_client = SetBrowserClientForTesting(&content_browser_client); - InstallTestHelper("/service_worker/fetch_in_install.js", - blink::ServiceWorkerStatusCode::kOk); + EXPECT_EQ(Install("/service_worker/fetch_in_install.js"), + blink::ServiceWorkerStatusCode::kOk); SetBrowserClientForTesting(old_client); } @@ -1412,7 +1396,7 @@ // Start a worker. StartServerAndNavigateToSetup(); SetUpRegistration("/service_worker/worker.js"); - StartWorker(blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(StartWorker(), blink::ServiceWorkerStatusCode::kOk); // Crash the renderer process. The version should stop. RenderProcessHost* process = @@ -1445,7 +1429,7 @@ // Once it's started, the worker script is read from the network and the COEP // value is set to the version. - StartWorker(blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(StartWorker(), blink::ServiceWorkerStatusCode::kOk); EXPECT_EQ(CrossOriginEmbedderPolicyRequireCorp(), version_->cross_origin_embedder_policy()); } @@ -1472,7 +1456,7 @@ cache_updated_closure_ = run_loop.QuitClosure(); // Start a worker. - StartWorker(status); + ASSERT_EQ(StartWorker(), status); // Wait for the metadata to be stored. This run loop should finish when // OnCachedMetadataUpdated() is called. @@ -1486,8 +1470,7 @@ size_t size) override { DCHECK(cache_updated_closure_); metadata_size_ = size; - RunOrPostTaskOnThread(FROM_HERE, BrowserThread::UI, - std::move(cache_updated_closure_)); + std::move(cache_updated_closure_).Run(); } private: @@ -1517,9 +1500,9 @@ std::string fetch_url, blink::mojom::FetchAPIResponsePtr* response_out) { StartServerAndNavigateToSetup(); - InstallTestHelper("/service_worker/cached_fetch_event.js", - blink::ServiceWorkerStatusCode::kOk); - ActivateTestHelper(blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(Install("/service_worker/cached_fetch_event.js"), + blink::ServiceWorkerStatusCode::kOk); + ASSERT_EQ(Activate(), blink::ServiceWorkerStatusCode::kOk); ServiceWorkerFetchDispatcher::FetchEventResult result; FetchOnRegisteredWorker(fetch_url, &result, response_out);
diff --git a/content/browser/site_per_process_unload_browsertest.cc b/content/browser/site_per_process_unload_browsertest.cc index c6cec02..7ea7a6d 100644 --- a/content/browser/site_per_process_unload_browsertest.cc +++ b/content/browser/site_per_process_unload_browsertest.cc
@@ -1502,7 +1502,8 @@ // Temporary extra expectations to investigate: // https://bugs.chromium.org/p/chromium/issues/detail?id=1215493 EXPECT_EQ(url, web_contents()->GetLastCommittedURL()); - EXPECT_EQ(2u, web_contents()->GetAllFrames().size()); + EXPECT_EQ( + 2u, CollectAllRenderFrameHosts(web_contents()->GetPrimaryPage()).size()); RenderFrameHostImpl* A4 = web_contents()->GetMainFrame(); RenderFrameHostImpl* B5 = A4->child_at(0)->current_frame_host(); @@ -1609,7 +1610,8 @@ // Temporary extra expectations to investigate: // https://bugs.chromium.org/p/chromium/issues/detail?id=1215493 EXPECT_EQ(url, web_contents()->GetLastCommittedURL()); - EXPECT_EQ(3u, web_contents()->GetAllFrames().size()); + EXPECT_EQ( + 3u, CollectAllRenderFrameHosts(web_contents()->GetPrimaryPage()).size()); RenderFrameHostImpl* A5 = web_contents()->GetMainFrame(); RenderFrameHostImpl* B6 = A5->child_at(0)->current_frame_host();
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index 035ffb5..e11bd3ef 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -3614,7 +3614,8 @@ // Start intercepting the DidOpenRequestedURL callback. MockDidOpenRequestedURLObserver mock_observer(shell()); WebContents* new_web_contents1 = nullptr; - RenderFrameHost* subframe = shell()->web_contents()->GetAllFrames()[1]; + RenderFrameHost* subframe = + ChildFrameAt(shell()->web_contents()->GetMainFrame(), 0); EXPECT_CALL(mock_observer, DidOpenRequestedURL( ::testing::_, // new_contents (captured via SaveArg below)
diff --git a/content/browser/webui/web_ui_url_loader_factory.cc b/content/browser/webui/web_ui_url_loader_factory.cc index 82f318c..3da1871 100644 --- a/content/browser/webui/web_ui_url_loader_factory.cc +++ b/content/browser/webui/web_ui_url_loader_factory.cc
@@ -5,11 +5,13 @@ #include "content/public/browser/web_ui_url_loader_factory.h" #include <utility> +#include <vector> #include "base/bind.h" #include "base/debug/crash_logging.h" #include "base/logging.h" #include "base/memory/ref_counted_memory.h" +#include "base/numerics/safe_conversions.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_piece.h" #include "base/task/thread_pool.h" @@ -30,9 +32,12 @@ #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "mojo/public/cpp/bindings/remote.h" +#include "net/http/http_byte_range.h" +#include "net/http/http_util.h" #include "services/network/public/cpp/parsed_headers.h" #include "services/network/public/cpp/self_deleting_url_loader_factory.h" #include "services/network/public/mojom/network_service.mojom.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/template_expressions.h" namespace content { @@ -58,6 +63,7 @@ bool replace_in_js, scoped_refptr<URLDataSourceImpl> data_source, mojo::PendingRemote<network::mojom::URLLoaderClient> client_remote, + absl::optional<net::HttpByteRange> requested_range, scoped_refptr<base::RefCountedMemory> bytes) { if (!bytes) { CallOnError(std::move(client_remote), net::ERR_FAILED); @@ -79,7 +85,28 @@ bytes = base::RefCountedString::TakeString(&temp_str); } - uint32_t output_size = bytes->size(); + // The use of MojoCreateDataPipeOptions below means we'll be using uint32_t + // for sizes / offsets. + if (!base::IsValueInRangeForNumericType<uint32_t>(bytes->size())) { + CallOnError(std::move(client_remote), net::ERR_INSUFFICIENT_RESOURCES); + return; + } + + uint32_t output_offset = 0; + uint32_t output_size = base::checked_cast<uint32_t>(bytes->size()); + if (requested_range) { + if (!requested_range->ComputeBounds(output_size)) { + CallOnError(std::move(client_remote), + net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); + return; + } + DCHECK(base::IsValueInRangeForNumericType<uint32_t>( + requested_range->first_byte_position())) + << "Expecting ComputeBounds() to enforce it"; + output_offset = requested_range->first_byte_position(); + output_size = requested_range->last_byte_position() - + requested_range->first_byte_position() + 1; + } MojoCreateDataPipeOptions options; options.struct_size = sizeof(MojoCreateDataPipeOptions); @@ -98,8 +125,9 @@ &buffer, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE); CHECK_EQ(result, MOJO_RESULT_OK); CHECK_GE(num_bytes, output_size); + CHECK_LE(output_offset + output_size, bytes->size()); - memcpy(buffer, bytes->front(), output_size); + memcpy(buffer, bytes->front() + output_offset, output_size); result = pipe_producer_handle->EndWriteData(output_size); CHECK_EQ(result, MOJO_RESULT_OK); @@ -127,6 +155,7 @@ bool replace_in_js, scoped_refptr<URLDataSourceImpl> source, mojo::PendingRemote<network::mojom::URLLoaderClient> client_remote, + absl::optional<net::HttpByteRange> requested_range, scoped_refptr<base::RefCountedMemory> bytes) { // Since the bytes are from the memory mapped resource file, copying the // data can lead to disk access. Needs to be posted to a SequencedTaskRunner @@ -134,9 +163,10 @@ base::ThreadPool::CreateSequencedTaskRunner( {base::TaskPriority::USER_BLOCKING, base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}) - ->PostTask(FROM_HERE, base::BindOnce(ReadData, std::move(headers), - replacements, replace_in_js, source, - std::move(client_remote), bytes)); + ->PostTask(FROM_HERE, + base::BindOnce(ReadData, std::move(headers), replacements, + replace_in_js, source, std::move(client_remote), + std::move(requested_range), bytes)); } void StartURLLoader( @@ -164,6 +194,23 @@ return; } + // Load everything by default, but respect the Range header if present. + absl::optional<net::HttpByteRange> range; + std::string range_header; + if (request.headers.GetHeader(net::HttpRequestHeaders::kRange, + &range_header)) { + std::vector<net::HttpByteRange> ranges; + // For simplicity, only allow a single range. This is expected to be + // sufficient for WebUI content. + if (!net::HttpUtil::ParseRangeHeader(range_header, &ranges) || + ranges.size() > 1u || !ranges[0].IsValid()) { + CallOnError(std::move(client_remote), + net::ERR_REQUEST_RANGE_NOT_SATISFIABLE); + return; + } + range = ranges[0]; + } + std::string path = URLDataSource::URLToRequestPath(request.url); std::string origin_header; request.headers.GetHeader(net::HttpRequestHeaders::kOrigin, &origin_header); @@ -199,7 +246,7 @@ // owned by |source| keep a reference to it in the callback. URLDataSource::GotDataCallback data_available_callback = base::BindOnce( DataAvailable, std::move(resource_response), replacements, replace_in_js, - base::RetainedRef(source), std::move(client_remote)); + base::RetainedRef(source), std::move(client_remote), std::move(range)); source->source()->StartDataRequest(request.url, std::move(wc_getter), std::move(data_available_callback));
diff --git a/content/browser/webui/web_ui_url_loader_factory_unittest.cc b/content/browser/webui/web_ui_url_loader_factory_unittest.cc new file mode 100644 index 0000000..5dcd2841 --- /dev/null +++ b/content/browser/webui/web_ui_url_loader_factory_unittest.cc
@@ -0,0 +1,228 @@ +// Copyright (c) 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 "content/public/browser/web_ui_url_loader_factory.h" + +#include "base/memory/ref_counted_memory.h" +#include "base/notreached.h" +#include "base/strings/strcat.h" +#include "base/strings/stringprintf.h" +#include "build/build_config.h" +#include "content/browser/webui/url_data_manager.h" +#include "content/public/browser/url_data_source.h" +#include "content/public/common/url_constants.h" +#include "content/public/test/test_renderer_host.h" +#include "mojo/public/c/system/data_pipe.h" +#include "mojo/public/c/system/types.h" +#include "net/traffic_annotation/network_traffic_annotation_test_helper.h" +#include "services/network/public/mojom/url_loader.mojom.h" +#include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "services/network/test/test_url_loader_client.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace content { + +namespace { + +const char* kTestWebUIScheme = kChromeUIScheme; +constexpr char kTestWebUIHost[] = "testhost"; +constexpr size_t kMaxTestResourceSize = 10; + +// A URLDataSource that always returns the byte sequence: +// {0, 1, 2, ..., resource_size - 1}. +class TestWebUIDataSource final : public URLDataSource { + public: + static std::vector<unsigned char> GetResource(size_t size) { + std::vector<unsigned char> resource(size); + for (size_t i = 0; i < resource.size(); ++i) + resource[i] = i; + return resource; + } + + explicit TestWebUIDataSource(size_t resource_size) + : resource_size_(resource_size) {} + + // URLDataSource implementation: + std::string GetSource() override { return kTestWebUIHost; } + + void StartDataRequest( + const GURL& /*url*/, + const content::WebContents::Getter& /*wc_getter*/, + content::URLDataSource::GotDataCallback callback) override { + std::vector<unsigned char> raw_resource = GetResource(resource_size_); + auto resource = base::RefCountedBytes::TakeVector(&raw_resource); + std::move(callback).Run(std::move(resource)); + } + + std::string GetMimeType(const std::string& path) override { + return "video/webm"; + } + + private: + const size_t resource_size_; +}; + +class OversizedWebUIDataSource final : public URLDataSource { + public: + explicit OversizedWebUIDataSource(size_t resource_size) + : resource_size_(resource_size) {} + + // URLDataSource implementation: + std::string GetSource() override { return kTestWebUIHost; } + + void StartDataRequest( + const GURL& /*url*/, + const content::WebContents::Getter& /*wc_getter*/, + content::URLDataSource::GotDataCallback callback) override { + auto resource = + base::MakeRefCounted<OversizedRefCountedMemory>(resource_size_); + std::move(callback).Run(std::move(resource)); + } + + std::string GetMimeType(const std::string& path) override { + return "video/webm"; + } + + private: + // An implementation of RefCountedMemory representing a very large "virtual" + // buffer that is never actually allocated. + class OversizedRefCountedMemory final : public base::RefCountedMemory { + public: + explicit OversizedRefCountedMemory(size_t size) : size_(size) {} + + OversizedRefCountedMemory(const OversizedRefCountedMemory&) = delete; + OversizedRefCountedMemory& operator=(const OversizedRefCountedMemory&) = + delete; + + // base::RefCountedMemory implementation: + const unsigned char* front() const override { + NOTREACHED(); + return nullptr; + } + size_t size() const override { return size_; } + + private: + ~OversizedRefCountedMemory() override = default; + + const size_t size_; + }; + + const size_t resource_size_; +}; + +} // namespace + +const struct RangeRequestTestData { + size_t resource_size = 0; + absl::optional<int> first_byte_position; + absl::optional<int> last_byte_position; + int expected_error_code = net::OK; + uint32_t expected_size = 0; +} kRangeRequestTestData[] = { + // No range. + {kMaxTestResourceSize, absl::nullopt, absl::nullopt, net::OK, + kMaxTestResourceSize}, + + // No range, 0-size resource. + {0, absl::nullopt, absl::nullopt, net::OK, 0}, + + {kMaxTestResourceSize, 3, absl::nullopt, net::OK, kMaxTestResourceSize - 3}, + + {kMaxTestResourceSize, 1, 1, net::OK, 1}, + + // Range too large by 1, truncated to resource size. + {kMaxTestResourceSize, 0, kMaxTestResourceSize, net::OK, + kMaxTestResourceSize}, + + // Range starts after the last resource byte. + {kMaxTestResourceSize, kMaxTestResourceSize, kMaxTestResourceSize + 5, + net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, 0}, + + // Invalid range. + {kMaxTestResourceSize, 2, 1, net::ERR_REQUEST_RANGE_NOT_SATISFIABLE, 0}, + +#if defined(ARCH_CPU_64_BITS) + // Resource too large. + {static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 1, + absl::nullopt, absl::nullopt, net::ERR_INSUFFICIENT_RESOURCES, 0}, +#endif // defined(ARCH_CPU_64_BITS) +}; + +class WebUIURLLoaderFactoryTest + : public RenderViewHostTestHarness, + public testing::WithParamInterface<RangeRequestTestData> { + public: + void SetUp() override { + RenderViewHostTestHarness::SetUp(); + + const auto resource_size = GetParam().resource_size; + std::unique_ptr<URLDataSource> data_source; + if (resource_size <= kMaxTestResourceSize) + data_source = std::make_unique<TestWebUIDataSource>(resource_size); + else + data_source = std::make_unique<OversizedWebUIDataSource>(resource_size); + URLDataManager::AddDataSource(browser_context(), std::move(data_source)); + } +}; + +INSTANTIATE_TEST_SUITE_P(, + WebUIURLLoaderFactoryTest, + testing::ValuesIn(kRangeRequestTestData)); + +TEST_P(WebUIURLLoaderFactoryTest, RangeRequest) { + mojo::Remote<network::mojom::URLLoaderFactory> loader_factory( + CreateWebUIURLLoaderFactory(main_rfh(), kTestWebUIScheme, + /*allowed_hosts=*/{})); + + network::ResourceRequest request; + request.url = GURL(base::StrCat({kTestWebUIScheme, "://", kTestWebUIHost})); + + if (GetParam().first_byte_position) { + const std::string range_value = + GetParam().last_byte_position + ? base::StringPrintf("bytes=%d-%d", *GetParam().first_byte_position, + *GetParam().last_byte_position) + : base::StringPrintf("bytes=%d-", *GetParam().first_byte_position); + request.headers.SetHeader(net::HttpRequestHeaders::kRange, range_value); + } + + mojo::PendingRemote<network::mojom::URLLoader> loader; + network::TestURLLoaderClient loader_client; + loader_factory->CreateLoaderAndStart( + loader.InitWithNewPipeAndPassReceiver(), /*request_id=*/0, + /*options=*/0, request, loader_client.CreateRemote(), + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS)); + loader_client.RunUntilComplete(); + + EXPECT_EQ(loader_client.completion_status().error_code, + GetParam().expected_error_code); + + if (loader_client.completion_status().error_code == net::OK) { + ASSERT_TRUE(loader_client.response_body().is_valid()); + uint32_t response_size; + ASSERT_EQ(loader_client.response_body().ReadData(nullptr, &response_size, + MOJO_READ_DATA_FLAG_QUERY), + MOJO_RESULT_OK); + ASSERT_EQ(response_size, GetParam().expected_size); + + if (response_size > 0u) { + std::vector<uint8_t> response(response_size); + ASSERT_EQ( + loader_client.response_body().ReadData( + response.data(), &response_size, MOJO_READ_DATA_FLAG_ALL_OR_NONE), + MOJO_RESULT_OK); + + std::vector<unsigned char> expected_resource = + TestWebUIDataSource::GetResource(GetParam().resource_size); + expected_resource.erase(expected_resource.begin(), + expected_resource.begin() + + GetParam().first_byte_position.value_or(0)); + expected_resource.resize(GetParam().expected_size); + EXPECT_EQ(response, expected_resource); + } + } +} + +} // namespace content
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index cc46a0b..98e7f8e8 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -1854,8 +1854,9 @@ return frame->GetLastCommittedURL() == url; } -RenderFrameHost* ChildFrameAt(RenderFrameHost* frame, size_t index) { - RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(frame); +RenderFrameHost* ChildFrameAt(const ToRenderFrameHost& adapter, size_t index) { + RenderFrameHostImpl* rfh = + static_cast<RenderFrameHostImpl*>(adapter.render_frame_host()); if (index >= rfh->frame_tree_node()->child_count()) return nullptr; return rfh->frame_tree_node()->child_at(index)->current_frame_host(); @@ -1869,6 +1870,10 @@ return visited_frames; } +std::vector<RenderFrameHost*> CollectAllRenderFrameHosts(Page& page) { + return CollectAllRenderFrameHosts(&page.GetMainDocument()); +} + std::vector<RenderFrameHost*> CollectAllRenderFrameHosts( WebContents* web_contents) { std::vector<RenderFrameHost*> visited_frames;
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 3fda448..16acff2c 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -876,14 +876,17 @@ bool FrameIsChildOfMainFrame(RenderFrameHost* frame); bool FrameHasSourceUrl(const GURL& url, RenderFrameHost* frame); -// Finds the child frame at the specified |index| for |frame| and returns its +// Finds the child frame at the specified |index| for |adapter| and returns its // RenderFrameHost. Returns nullptr if such child frame does not exist. -RenderFrameHost* ChildFrameAt(RenderFrameHost* frame, size_t index); +RenderFrameHost* ChildFrameAt(const ToRenderFrameHost& adapter, size_t index); // Returns the frames visited by |RenderFrameHost::ForEachRenderFrameHost| in // the same order. std::vector<RenderFrameHost*> CollectAllRenderFrameHosts( RenderFrameHost* starting_rfh); +// Returns the frames visited by |RenderFrameHost::ForEachRenderFrameHost| on +// |page|'s main document in the same order. +std::vector<RenderFrameHost*> CollectAllRenderFrameHosts(Page& page); // Returns the frames visited by |WebContents::ForEachRenderFrameHost| in // the same order. std::vector<RenderFrameHost*> CollectAllRenderFrameHosts(
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 642071f..29d33aa4 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -2228,6 +2228,7 @@ "../browser/webui/web_ui_main_frame_observer_unittest.cc", "../browser/webui/web_ui_message_handler_unittest.cc", "../browser/webui/web_ui_unittest.cc", + "../browser/webui/web_ui_url_loader_factory_unittest.cc", "../browser/worker_host/dedicated_worker_service_impl_unittest.cc", "../browser/worker_host/mock_shared_worker.cc", "../browser/worker_host/mock_shared_worker.h",
diff --git a/extensions/browser/content_script_matching_browsertest.cc b/extensions/browser/content_script_matching_browsertest.cc index 99c25bc..07b23ff 100644 --- a/extensions/browser/content_script_matching_browsertest.cc +++ b/extensions/browser/content_script_matching_browsertest.cc
@@ -207,37 +207,41 @@ } content::RenderFrameHost* tab1_fooFrame() { - DCHECK(tab1_); + EXPECT_TRUE(tab1_); return tab1_->GetMainFrame(); } content::RenderFrameHost* tab1_fooBlankFrame() { - DCHECK(tab1_); - DCHECK_LT(1u, tab1_->GetAllFrames().size()); - return tab1_->GetAllFrames()[1]; + EXPECT_TRUE(tab1_); + content::RenderFrameHost* child = ChildFrameAt(tab1_fooFrame(), 0); + EXPECT_TRUE(child); + return child; } content::RenderFrameHost* tab1_barFrame() { - DCHECK(tab1_); - DCHECK_LT(2u, tab1_->GetAllFrames().size()); - return tab1_->GetAllFrames()[2]; + EXPECT_TRUE(tab1_); + content::RenderFrameHost* child = ChildFrameAt(tab1_fooFrame(), 1); + EXPECT_TRUE(child); + return child; } content::RenderFrameHost* tab1_barBlankFrame() { - DCHECK(tab1_); - DCHECK_LT(3u, tab1_->GetAllFrames().size()); - return tab1_->GetAllFrames()[3]; + EXPECT_TRUE(tab1_); + content::RenderFrameHost* child = ChildFrameAt(tab1_barFrame(), 0); + EXPECT_TRUE(child); + return child; } content::RenderFrameHost* tab2_barBlankFrame1() { - DCHECK(tab2_); + EXPECT_TRUE(tab2_); return tab2_->GetMainFrame(); } content::RenderFrameHost* tab2_barBlankFrame2() { - DCHECK(tab2_); - DCHECK_LT(1u, tab1_->GetAllFrames().size()); - return tab2_->GetAllFrames()[1]; + EXPECT_TRUE(tab2_); + content::RenderFrameHost* child = ChildFrameAt(tab2_barBlankFrame1(), 0); + EXPECT_TRUE(child); + return child; } // Populated by SetUpFrameTree (during test setup / in SetUpOnMainThread).
diff --git a/fuchsia/engine/browser/accessibility_bridge_browsertest.cc b/fuchsia/engine/browser/accessibility_bridge_browsertest.cc index 77d6b894..e3236fd 100644 --- a/fuchsia/engine/browser/accessibility_bridge_browsertest.cc +++ b/fuchsia/engine/browser/accessibility_bridge_browsertest.cc
@@ -1076,7 +1076,10 @@ kPage1Title); // Two frames should be present. - int num_frames = frame_impl_->web_contents_for_test()->GetAllFrames().size(); + int num_frames = CollectAllRenderFrameHosts( + frame_impl_->web_contents_for_test()->GetPrimaryPage()) + .size(); + EXPECT_EQ(num_frames, 2); // Check that the iframe node has been loaded. @@ -1122,7 +1125,10 @@ // We've navigated to a different page that has no iframes. Only one frame // should be present. - num_frames = frame_impl_->web_contents_for_test()->GetAllFrames().size(); + num_frames = CollectAllRenderFrameHosts( + frame_impl_->web_contents_for_test()->GetPrimaryPage()) + .size(); + EXPECT_EQ(num_frames, 1); }
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 6b85b9f..eb95508a 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -2149,6 +2149,9 @@ <message name="IDS_IOS_SETTINGS_TOOLBAR_DELETE" desc="Label of the button displayed on the bottom toolbar of the settings' collections when they are in edit mode. Pressing this button deletes the currently selected items."> Delete </message> + <message name="IDS_IOS_SETTINGS_TOOLBAR_ADD" desc="Label of the button displayed on the bottom toolbar of the settings' collections. Pressing this button opens the Add view. For example: Clicking this button in the Password settings would open the add password view."> + Add + </message> <message name="IDS_IOS_SETTINGS_SWIPE_DOWN_MESSAGE" desc="Message displayed whenever a user tries to dismiss a Settings screen which is being edited, or information is being added to it."> Are you sure you want to discard your changes? </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SETTINGS_TOOLBAR_ADD.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SETTINGS_TOOLBAR_ADD.png.sha1 new file mode 100644 index 0000000..21b80c5 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_SETTINGS_TOOLBAR_ADD.png.sha1
@@ -0,0 +1 @@ +fea94b381934ce85880d0ad87dfdc8dab6d8eea3 \ No newline at end of file
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_my.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_my.xtb index 438b065c..ad83c19 100644 --- a/ios/chrome/app/strings/resources/ios_chromium_strings_my.xtb +++ b/ios/chrome/app/strings/resources/ios_chromium_strings_my.xtb
@@ -56,7 +56,7 @@ <translation id="5573014823074921752">Chromium အကြံပြုချက်။ နောက်ထပ် တဘ်ရွေးချယ်စရာများအတွက် ဖန်သားပြင်၏ အောက်ခြေ သို့မဟုတ် ထိပ်ဘက်ရှိ ကိရိယာဘားအတွင်း 'တဘ်ကို ပြရန်' ခလုတ်ကို တို့၍ဖိထားပါ။</translation> <translation id="5700709190537129682">Chromium က သင့်စကားဝှက်များကို စစ်ဆေး၍မရပါ</translation> <translation id="5777187867430702742">Chromium စာမျက်နှာ</translation> -<translation id="5862307444128926510">Chromium မှ ကြိုဆိုပါ၏</translation> +<translation id="5862307444128926510">Chromium က ကြိုဆိုပါ၏</translation> <translation id="5945387852661427312">သင်သည် <ph name="DOMAIN" /> က စီမံခန့်ခွဲထားသည့် အကောင့်ဖြင့် လက်မှတ်ထိုးဝင်နေပြီး သင့် Chromium ဒေတာကို ထိန်းချုပ်ခွင့်ပေးထားပါသည်။ သင့်ဒေတာများသည် ဤအကောင့်နှင့် အပြီးအပိုင် ချိတ်ဆက်ထားပါမည်။ Chromium မှ ထွက်လိုက်ခြင်းဖြင့် ဤစက်ပစ္စည်းပေါ်ရှိ ဒေတာများကို ဖျက်လိုက်မည် ဖြစ်သော်လည်း ၎င်းတို့သည် သင့် Google အကောင့်တွင် ကျန်ရှိနေဦးမည် ဖြစ်သည်။</translation> <translation id="602807004951640891">Chromium အသုံးပြုခြင်းဖြင့် သင်သည် <ph name="BEGIN_LINK_TOS" />ဝန်ဆောင်မှု စည်းကမ်းများ<ph name="END_LINK_TOS" /> ကို သဘောတူရာ ရောက်ပါသည်။</translation> <translation id="6119647025869519954">Chromium ကို မူရင်းသတ်မှတ်ရန်-
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_my.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_my.xtb index 317c8d5..f8515bf 100644 --- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_my.xtb +++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_my.xtb
@@ -85,7 +85,7 @@ <translation id="7400722733683201933">Google Chrome အကြောင်း</translation> <translation id="7501046334262221972">Chrome ကို မူရင်းဘရောင်ဇာ သတ်မှတ်ရန် ‘ဆက်တင်များ’ ဖွင့်ပါ။ ‘မူရင်း ဘရောင်ဇာအက်ပ်’ ကိုတို့ပြီး Chrome ကိုရွေးပါ။</translation> <translation id="756809126120519699">Chrome ဒေတာကို ရှင်းလင်းလိုက်ပါပြီ</translation> -<translation id="7626032353295482388">Chrome မှ ကြိုဆိုပါသည်</translation> +<translation id="7626032353295482388">Chrome က ကြိုဆိုပါသည်</translation> <translation id="7662994914830945754">Chrome အသုံးပြုသည့် နေရာမှန်သမျှမှ သင့်တဘ်များကိုကြည့်ရန် လက်မှတ်ထိုးဝင်ပြီး စင့်ခ်လုပ်ခြင်းကိုဖွင့်ပါ</translation> <translation id="766361182512894255">ဒေတာပေါက်ကြားမှုတစ်ခုတွင် သင့်စကားဝှက် ဖော်ထုတ်ခံခဲ့ရသည်။ စကားဝှက်ကို ယခုပြောင်းရန် Chrome က အကြံပြုပါသည်။</translation> <translation id="7693590760643069321">ယခုအချိန်တွင် မက်ဆေ့ဂျ်များ၊ စာရွက်စာတမ်းများနှင့် အခြားအက်ပ်များတွင် အချိန်မရွေး လင့်ခ်များကို တို့ရုံမျှဖြင့် Chrome ကို သင်အသုံးပြုနိုင်သည်။</translation>
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 1b62bb73..9c4d303 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -485,12 +485,11 @@ flags_ui::kOsIos, FEATURE_VALUE_TYPE( autofill::features::kAutofillSaveCardDismissOnNavigation)}, - {"desktop-version-default", flag_descriptions::kDefaultToDesktopOnIPadName, - flag_descriptions::kDefaultToDesktopOnIPadDescription, flags_ui::kOsIos, + {"default-user-agent", + flag_descriptions::kUseDefaultUserAgentInWebClientName, + flag_descriptions::kUseDefaultUserAgentInWebClientDescription, + flags_ui::kOsIos, FEATURE_VALUE_TYPE(web::features::kUseDefaultUserAgentInWebClient)}, - {"mobile-google-srp", flag_descriptions::kMobileGoogleSRPName, - flag_descriptions::kMobileGoogleSRPDescription, flags_ui::kOsIos, - FEATURE_VALUE_TYPE(web::kMobileGoogleSRP)}, {"url-blocklist-ios", flag_descriptions::kURLBlocklistIOSName, flag_descriptions::kURLBlocklistIOSDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kURLBlocklistIOS)}, @@ -575,10 +574,6 @@ flag_descriptions::kEditPasswordsInSettingsName, flag_descriptions::kEditPasswordsInSettingsDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(password_manager::features::kEditPasswordsInSettings)}, - {"enable-incognito-authentication-ios", - flag_descriptions::kIncognitoAuthenticationName, - flag_descriptions::kIncognitoAuthenticationDescription, flags_ui::kOsIos, - FEATURE_VALUE_TYPE(kIncognitoAuthentication)}, {"web-view-native-context-menu", flag_descriptions::kWebViewNativeContextMenuName, flag_descriptions::kWebViewNativeContextMenuDescription, flags_ui::kOsIos,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 67343d347..026f660 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -108,10 +108,11 @@ const char kDefaultPromoTailoredDescription[] = "When enabled the selected tailored fullscreen promo can be triggered."; -const char kDefaultToDesktopOnIPadName[] = "Request desktop version by default"; -const char kDefaultToDesktopOnIPadDescription[] = - "By default, on iPad, the desktop version of the web sites will be " - "requested"; +const char kUseDefaultUserAgentInWebClientName[] = + "[Refactoring] Let the client choose default mode"; +const char kUseDefaultUserAgentInWebClientDescription[] = + "When enabled, the web client will choose the default mode. It is a " + "refactoring, no visible impact."; const char kDefaultBrowserFullscreenPromoExperimentName[] = "Default Browser Fullscreen modal experiment"; @@ -242,12 +243,6 @@ "When enabled, the web view's insets are updated for scoll events. If " "disabled, the the web view's frame are updated."; -const char kIncognitoAuthenticationName[] = - "Device Authentication for Incognito"; -extern const char kIncognitoAuthenticationDescription[] = - "When enabled, a setting appears to enable biometric authentication for " - "accessing incognito."; - const char kIncognitoBrandConsistencyForIOSName[] = "Enable Incognito brand consistency in iOS."; const char kIncognitoBrandConsistencyForIOSDescription[] = @@ -326,11 +321,6 @@ const char kMICEWebSignInName[] = "MICE Web Sign-in"; const char kMICEWebSignInDescription[] = "Enables MICE web sign-in."; -const char kMobileGoogleSRPName[] = "Mobile version of Google SRP by default"; -const char kMobileGoogleSRPDescription[] = - "Request the Mobile version of Google SRP by default when the desktop mode " - "is requested by default."; - const char kModernTabStripName[] = "Modern TabStrip"; const char kModernTabStripDescription[] = "When enabled, the newly implemented tabstrip can be tested.";
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index e1fc882..7d7ae4d2 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -101,10 +101,10 @@ extern const char kDefaultPromoNonModalName[]; extern const char kDefaultPromoNonModalDescription[]; -// Title and description for the flag to request the desktop version of web site -// by default on iPad -extern const char kDefaultToDesktopOnIPadName[]; -extern const char kDefaultToDesktopOnIPadDescription[]; +// Title and description for the flag to have the web client choosing the +// default user agent. +extern const char kUseDefaultUserAgentInWebClientName[]; +extern const char kUseDefaultUserAgentInWebClientDescription[]; // Title and description for the flag to use default WebKit context menu in web // content. @@ -216,11 +216,6 @@ extern const char kFullscreenSmoothScrollingName[]; extern const char kFullscreenSmoothScrollingDescription[]; -// Title and dscription for the flag to allow biometric authentication for -// accessing incognito. -extern const char kIncognitoAuthenticationName[]; -extern const char kIncognitoAuthenticationDescription[]; - // Title and description for the flag to enable dark mode colors while in // Incognito mode. extern const char kIncognitoBrandConsistencyForIOSName[]; @@ -278,11 +273,6 @@ extern const char kMICEWebSignInName[]; extern const char kMICEWebSignInDescription[]; -// Title and description for the flag where the Google SRP is requested in -// mobile mode by default. -extern const char kMobileGoogleSRPName[]; -extern const char kMobileGoogleSRPDescription[]; - // TODO(crbug.com/1128242): Remove this flag after the refactoring work is // finished. // Title and description for the flag used to test the newly
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 6a20b61..c8f3411 100644 --- a/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm +++ b/ios/chrome/browser/ui/bookmarks/bookmark_home_view_controller.mm
@@ -708,7 +708,7 @@ - (void)openAllURLs:(std::vector<GURL>)urls inIncognito:(BOOL)inIncognito newTab:(BOOL)newTab { - if (base::FeatureList::IsEnabled(kIncognitoAuthentication) && inIncognito) { + if (inIncognito) { IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent agentFromScene:SceneStateBrowserAgent::FromBrowser(self.browser) ->GetSceneState()];
diff --git a/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm b/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm index ebc5f18..561ba9e0 100644 --- a/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm +++ b/ios/chrome/browser/ui/context_menu/context_menu_configuration_provider.mm
@@ -147,8 +147,6 @@ if (!isLink && !isImage) return nil; - base::RecordAction( - base::UserMetricsAction("MobileWebContextMenuLinkImpression")); DCHECK(self.browser->GetBrowserState()); __weak __typeof(self) weakSelf = self; @@ -167,6 +165,8 @@ scenario:menuScenario]; if (isLink) { + base::RecordAction( + base::UserMetricsAction("MobileWebContextMenuLinkImpression")); if (web::UrlHasWebScheme(link)) { // Open in New Tab. UrlLoadParams loadParams = UrlLoadParams::InNewTab(link); @@ -232,6 +232,8 @@ } if (isImage) { + base::RecordAction( + base::UserMetricsAction("MobileWebContextMenuImageImpression")); // Save Image. UIAction* saveImage = [actionFactory actionSaveImageWithBlock:^{ if (!weakSelf || !weakBaseViewController) @@ -510,25 +512,23 @@ UrlLoadingBrowserAgent::FromBrowser(self.browser)->Load(params); }; - if (base::FeatureList::IsEnabled(kIncognitoAuthentication)) { - IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent - agentFromScene:SceneStateBrowserAgent::FromBrowser(self.browser) - ->GetSceneState()]; - // Wrap the action inside of an auth check block. - ProceduralBlock wrappedAction = action; - action = ^{ - if (reauthAgent.authenticationRequired) { - [reauthAgent authenticateIncognitoContentWithCompletionBlock:^( - BOOL success) { - if (success) { - wrappedAction(); - } - }]; - } else { - wrappedAction(); - } - }; - } + IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent + agentFromScene:SceneStateBrowserAgent::FromBrowser(self.browser) + ->GetSceneState()]; + // Wrap the action inside of an auth check block. + ProceduralBlock wrappedAction = action; + action = ^{ + if (reauthAgent.authenticationRequired) { + [reauthAgent authenticateIncognitoContentWithCompletionBlock:^( + BOOL success) { + if (success) { + wrappedAction(); + } + }]; + } else { + wrappedAction(); + } + }; [self.legacyContextMenuCoordinator addItemWithTitle:title
diff --git a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm index d1c92de..b3085e60 100644 --- a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm +++ b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.mm
@@ -99,19 +99,20 @@ base::SysNSStringToUTF16(biometricAuthenticationTypeString())); __weak IncognitoReauthSceneAgent* weakSelf = self; - [self.reauthModule - attemptReauthWithLocalizedReason:authReason - canReusePreviousAuth:false - handler:^(ReauthenticationResult result) { - BOOL success = - (result == - ReauthenticationResult::kSuccess); - weakSelf.authenticatedSinceLastForeground = - success; - if (completion) { - completion(success); - } - }]; + void (^completionHandler)(ReauthenticationResult) = + ^(ReauthenticationResult result) { + BOOL success = (result == ReauthenticationResult::kSuccess); + base::UmaHistogramBoolean( + "IOS.Incognito.BiometricReauthAttemptSuccessful", success); + + weakSelf.authenticatedSinceLastForeground = success; + if (completion) { + completion(success); + } + }; + [self.reauthModule attemptReauthWithLocalizedReason:authReason + canReusePreviousAuth:false + handler:completionHandler]; } - (void)addObserver:(id<IncognitoReauthObserver>)observer { @@ -188,9 +189,6 @@ - (void)logEnabledHistogramOnce { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - if (!base::FeatureList::IsEnabled(kIncognitoAuthentication)) { - return; - } DCHECK(self.localState) << "Local state is not yet available when trying to log " "IOS.Incognito.BiometricAuthEnabled. This code is called too " @@ -198,7 +196,8 @@ BOOL settingEnabled = self.localState && self.localState->GetBoolean(prefs::kIncognitoAuthenticationSetting); - UMA_HISTOGRAM_BOOLEAN("IOS.Incognito.BiometricAuthEnabled", settingEnabled); + base::UmaHistogramBoolean("IOS.Incognito.BiometricAuthEnabled", + settingEnabled); }); } @@ -216,8 +215,7 @@ // Convenience method to check the pref associated with the reauth setting and // the feature flag. - (BOOL)featureEnabled { - return base::FeatureList::IsEnabled(kIncognitoAuthentication) && - self.localState && + return self.localState && self.localState->GetBoolean(prefs::kIncognitoAuthenticationSetting); }
diff --git a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent_unittest.mm b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent_unittest.mm index 6e24a6a..f6f167d 100644 --- a/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent_unittest.mm +++ b/ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent_unittest.mm
@@ -73,10 +73,7 @@ return web_state_list; } - void SetUpTestObjects(int tab_count, bool enable_flag, bool enable_pref) { - // Mock the feature flag. - feature_list_.InitWithFeatureState(kIncognitoAuthentication, enable_flag); - + void SetUpTestObjects(int tab_count, bool enable_pref) { // Stub all calls to be able to mock the following: // 1. sceneState.interfaceProvider.incognitoInterface // .browser->GetWebStateList()->count() @@ -122,7 +119,7 @@ // Test that when the feature pref is disabled, auth isn't required. TEST_F(IncognitoReauthSceneAgentTest, PrefDisabled) { - SetUpTestObjects(/*tab_count=*/1, /*enable_flag=*/true, + SetUpTestObjects(/*tab_count=*/1, /*enable_pref=*/false); // Go foreground. @@ -131,21 +128,10 @@ EXPECT_FALSE(agent_.authenticationRequired); } -// Test that when the feature flag is disabled, auth isn't required. -TEST_F(IncognitoReauthSceneAgentTest, FlagDisabled) { - SetUpTestObjects(/*tab_count=*/1, /*enable_flag=*/false, - /*enable_pref=*/true); - - // Go foreground. - scene_state_.activationLevel = SceneActivationLevelForegroundActive; - - EXPECT_FALSE(agent_.authenticationRequired); -} - // Test that when the feature is enabled, we're foregrounded with some incognito // content already present, auth is required TEST_F(IncognitoReauthSceneAgentTest, NeedsAuth) { - SetUpTestObjects(/*tab_count=*/1, /*enable_flag=*/true, /*enable_pref=*/true); + SetUpTestObjects(/*tab_count=*/1, /*enable_pref=*/true); // Go foreground. scene_state_.activationLevel = SceneActivationLevelForegroundActive; @@ -156,7 +142,7 @@ // Test that when auth is required and is successfully performed, it's not // required anymore. TEST_F(IncognitoReauthSceneAgentTest, SuccessfulAuth) { - SetUpTestObjects(/*tab_count=*/1, /*enable_flag=*/true, /*enable_pref=*/true); + SetUpTestObjects(/*tab_count=*/1, /*enable_pref=*/true); // Go foreground. scene_state_.activationLevel = SceneActivationLevelForegroundActive; @@ -176,7 +162,7 @@ // Tests that authentication is still required if authentication fails. TEST_F(IncognitoReauthSceneAgentTest, FailedSkippedAuth) { - SetUpTestObjects(/*tab_count=*/1, /*enable_flag=*/true, /*enable_pref=*/true); + SetUpTestObjects(/*tab_count=*/1, /*enable_pref=*/true); // Go foreground. scene_state_.activationLevel = SceneActivationLevelForegroundActive; @@ -198,7 +184,7 @@ // Test that when the feature is enabled, auth isn't required if we foreground // without any incognito tabs. TEST_F(IncognitoReauthSceneAgentTest, AuthNotRequiredWhenNoIncognitoTabs) { - SetUpTestObjects(/*tab_count=*/0, /*enable_flag=*/true, /*enable_pref=*/true); + SetUpTestObjects(/*tab_count=*/0, /*enable_pref=*/true); // Go foreground. scene_state_.activationLevel = SceneActivationLevelForegroundActive; @@ -210,7 +196,7 @@ // content already present, auth is required TEST_F(IncognitoReauthSceneAgentTest, AuthNotRequiredWhenNoIncognitoTabsOnForeground) { - SetUpTestObjects(/*tab_count=*/0, /*enable_flag=*/true, /*enable_pref=*/true); + SetUpTestObjects(/*tab_count=*/0, /*enable_pref=*/true); // Go foreground. scene_state_.activationLevel = SceneActivationLevelForegroundActive;
diff --git a/ios/chrome/browser/ui/main/scene_controller.mm b/ios/chrome/browser/ui/main/scene_controller.mm index 345ca06..79e93952 100644 --- a/ios/chrome/browser/ui/main/scene_controller.mm +++ b/ios/chrome/browser/ui/main/scene_controller.mm
@@ -1459,8 +1459,7 @@ } - (void)openURLInNewTab:(OpenNewTabCommand*)command { - if (base::FeatureList::IsEnabled(kIncognitoAuthentication) && - command.inIncognito) { + if (command.inIncognito) { IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent agentFromScene:self.sceneState]; if (reauthAgent.authenticationRequired) { @@ -2152,8 +2151,7 @@ }; // Wrap the post-dismiss-modals action with the incognito auth check. - if (base::FeatureList::IsEnabled(kIncognitoAuthentication) && - targetMode == ApplicationModeForTabOpening::INCOGNITO) { + if (targetMode == ApplicationModeForTabOpening::INCOGNITO) { IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent agentFromScene:self.sceneState]; if (reauthAgent.authenticationRequired) {
diff --git a/ios/chrome/browser/ui/menu/BUILD.gn b/ios/chrome/browser/ui/menu/BUILD.gn index 7321934..fe06823 100644 --- a/ios/chrome/browser/ui/menu/BUILD.gn +++ b/ios/chrome/browser/ui/menu/BUILD.gn
@@ -94,6 +94,7 @@ "//ios/chrome/browser/main:test_support", "//ios/chrome/browser/sessions:test_support", "//ios/chrome/browser/ui/commands", + "//ios/chrome/browser/ui/main:scene_state_header", "//ios/chrome/browser/url_loading", "//ios/chrome/browser/window_activities", "//ios/web/public/test",
diff --git a/ios/chrome/browser/ui/menu/action_factory.mm b/ios/chrome/browser/ui/menu/action_factory.mm index 5b267b7..67bfd19 100644 --- a/ios/chrome/browser/ui/menu/action_factory.mm +++ b/ios/chrome/browser/ui/menu/action_factory.mm
@@ -54,7 +54,7 @@ return [self actionWithTitle:l10n_util::GetNSString(IDS_IOS_COPY_LINK_ACTION_TITLE) image:[UIImage imageNamed:@"copy_link_url"] - type:MenuActionType::Copy + type:MenuActionType::CopyURL block:^{ StoreURLInPasteboard(URL); }]; @@ -196,7 +196,7 @@ UIAction* action = [self actionWithTitle:l10n_util::GetNSString(title) image:[UIImage imageNamed:@"download"] - type:MenuActionType::Save + type:MenuActionType::SaveImage block:block]; return action; } @@ -205,7 +205,7 @@ UIAction* action = [self actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_COPYIMAGE) image:[UIImage imageNamed:@"copy"] - type:MenuActionType::Copy + type:MenuActionType::CopyImage block:block]; return action; }
diff --git a/ios/chrome/browser/ui/menu/action_factory_unittest.mm b/ios/chrome/browser/ui/menu/action_factory_unittest.mm index 31a173ef..4d69166 100644 --- a/ios/chrome/browser/ui/menu/action_factory_unittest.mm +++ b/ios/chrome/browser/ui/menu/action_factory_unittest.mm
@@ -54,7 +54,7 @@ UIAction* action = [factory actionWithTitle:test_title_ image:mockImage - type:MenuActionType::Copy + type:MenuActionType::CopyURL block:^{ }];
diff --git a/ios/chrome/browser/ui/menu/browser_action_factory.mm b/ios/chrome/browser/ui/menu/browser_action_factory.mm index 7934f72cf..b20af5d 100644 --- a/ios/chrome/browser/ui/menu/browser_action_factory.mm +++ b/ios/chrome/browser/ui/menu/browser_action_factory.mm
@@ -70,20 +70,18 @@ - (UIAction*)actionToOpenInNewIncognitoTabWithBlock:(ProceduralBlock)block { // Wrap the block with the incognito auth check, if necessary. - if (base::FeatureList::IsEnabled(kIncognitoAuthentication)) { - IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent - agentFromScene:SceneStateBrowserAgent::FromBrowser(self.browser) - ->GetSceneState()]; - if (reauthAgent.authenticationRequired) { - block = ^{ - [reauthAgent - authenticateIncognitoContentWithCompletionBlock:^(BOOL success) { - if (success && block != nullptr) { - block(); - } - }]; - }; - } + IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent + agentFromScene:SceneStateBrowserAgent::FromBrowser(self.browser) + ->GetSceneState()]; + if (reauthAgent.authenticationRequired) { + block = ^{ + [reauthAgent + authenticateIncognitoContentWithCompletionBlock:^(BOOL success) { + if (success && block != nullptr) { + block(); + } + }]; + }; } return [self actionWithTitle:l10n_util::GetNSString( @@ -128,7 +126,7 @@ UIAction* action = [self actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_OPENIMAGE) image:[UIImage imageNamed:@"open"] - type:MenuActionType::OpenInCurrentTab + type:MenuActionType::OpenImageInCurrentTab block:^{ loadingAgent->Load(UrlLoadParams::InCurrentTab(URL)); if (completion) { @@ -147,7 +145,7 @@ [self actionWithTitle:l10n_util::GetNSString( IDS_IOS_CONTENT_CONTEXT_OPENIMAGENEWTAB) image:[UIImage imageNamed:@"open_image_in_new_tab"] - type:MenuActionType::OpenInNewTab + type:MenuActionType::OpenImageInNewTab block:^{ loadingAgent->Load(params); if (completion) {
diff --git a/ios/chrome/browser/ui/menu/browser_action_factory_unittest.mm b/ios/chrome/browser/ui/menu/browser_action_factory_unittest.mm index f7d213a..a8eb599 100644 --- a/ios/chrome/browser/ui/menu/browser_action_factory_unittest.mm +++ b/ios/chrome/browser/ui/menu/browser_action_factory_unittest.mm
@@ -10,6 +10,8 @@ #import "ios/chrome/browser/sessions/test_session_service.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h" +#import "ios/chrome/browser/ui/main/scene_state.h" +#import "ios/chrome/browser/ui/main/scene_state_browser_agent.h" #import "ios/chrome/browser/ui/menu/menu_action_type.h" #import "ios/chrome/browser/ui/menu/menu_histograms.h" #import "ios/chrome/browser/url_loading/url_loading_params.h" @@ -38,9 +40,12 @@ protected: BrowserActionFactoryTest() : test_title_(@"SomeTitle"), - test_browser_(std::make_unique<TestBrowser>()) {} + test_browser_(std::make_unique<TestBrowser>()), + scene_state_([[SceneState alloc] initWithAppState:nil]) {} void SetUp() override { + SceneStateBrowserAgent::CreateForBrowser(test_browser_.get(), scene_state_); + mock_application_commands_handler_ = OCMStrictProtocolMock(@protocol(ApplicationCommands)); [test_browser_->GetCommandDispatcher() @@ -66,6 +71,7 @@ std::unique_ptr<TestBrowser> test_browser_; id mock_application_commands_handler_; id mock_application_settings_commands_handler_; + SceneState* scene_state_; }; // Tests that the Open in New Tab actions have the right titles and images.
diff --git a/ios/chrome/browser/ui/menu/menu_action_type.h b/ios/chrome/browser/ui/menu/menu_action_type.h index ae3cf3c..e0fe559 100644 --- a/ios/chrome/browser/ui/menu/menu_action_type.h +++ b/ios/chrome/browser/ui/menu/menu_action_type.h
@@ -13,7 +13,7 @@ OpenInNewIncognitoTab = 1, OpenInNewWindow = 2, OpenAllInNewTabs = 3, - Copy = 4, + CopyURL = 4, Edit = 5, Move = 6, Share = 7, @@ -28,12 +28,14 @@ AddToBookmarks = 16, CloseTab = 17, EditBookmark = 18, - Save = 19, - OpenInCurrentTab = 20, + SaveImage = 19, + OpenImageInCurrentTab = 20, SearchImage = 21, CloseAllTabs = 22, SelectTabs = 23, - kMaxValue = SelectTabs + OpenImageInNewTab = 24, + CopyImage = 25, + kMaxValue = CopyImage }; #endif // IOS_CHROME_BROWSER_UI_MENU_MENU_ACTION_TYPE_H_
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm index e86c617..cc1f009 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_coordinator.mm
@@ -389,7 +389,7 @@ incognito:(BOOL)incognito { // Only open a new incognito tab when incognito is authenticated. Prompt for // auth otherwise. - if (base::FeatureList::IsEnabled(kIncognitoAuthentication) && incognito) { + if (incognito) { IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent agentFromScene:SceneStateBrowserAgent::FromBrowser(self.browser) ->GetSceneState()];
diff --git a/ios/chrome/browser/ui/settings/autofill/BUILD.gn b/ios/chrome/browser/ui/settings/autofill/BUILD.gn index 88f45c7e..a1d9b5a 100644 --- a/ios/chrome/browser/ui/settings/autofill/BUILD.gn +++ b/ios/chrome/browser/ui/settings/autofill/BUILD.gn
@@ -30,6 +30,7 @@ "//components/autofill/core/browser", "//components/autofill/core/common", "//components/autofill/ios/browser", + "//components/password_manager/core/common", "//components/prefs", "//components/strings", "//ios/chrome/app/strings",
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm b/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm index 52ef186..fa70e08 100644 --- a/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.mm
@@ -12,6 +12,7 @@ #include "components/autofill/core/common/autofill_prefs.h" #import "components/autofill/ios/browser/credit_card_util.h" #import "components/autofill/ios/browser/personal_data_manager_observer_bridge.h" +#import "components/password_manager/core/common/password_manager_features.h" #include "components/prefs/pref_service.h" #include "components/strings/grit/components_strings.h" #include "ios/chrome/browser/application_context.h" @@ -99,7 +100,12 @@ self = [super initWithStyle:ChromeTableViewStyle()]; if (self) { self.title = l10n_util::GetNSString(IDS_AUTOFILL_PAYMENT_METHODS); - self.shouldHideDoneButton = YES; + if (base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)) { + self.shouldDisableDoneButtonOnEdit = YES; + } else { + self.shouldHideDoneButton = YES; + } _browser = browser; _personalDataManager = autofill::PersonalDataManagerFactory::GetForBrowserState( @@ -122,10 +128,15 @@ self.tableView.accessibilityIdentifier = kAutofillCreditCardTableViewId; self.navigationController.toolbar.accessibilityIdentifier = kAutofillPaymentMethodsToolbarId; - - self.addPaymentMethodButton.enabled = [self isAutofillCreditCardEnabled]; - [self setToolbarItems:@[ [self flexibleSpace], self.addPaymentMethodButton ] - animated:YES]; + if (base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)) { + self.shouldShowAddButtonInToolbar = YES; + self.addButtonInToolbar.enabled = [self isAutofillCreditCardEnabled]; + } else { + self.addPaymentMethodButton.enabled = [self isAutofillCreditCardEnabled]; + [self setToolbarItems:@[ [self flexibleSpace], self.addPaymentMethodButton ] + animated:YES]; + } [self updateUIForEditState]; [self loadModel]; } @@ -134,10 +145,16 @@ [super setEditing:editing animated:animated]; if (editing) { self.deleteButton.enabled = NO; - [self showDeleteButton]; + if (!base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)) { + [self showDeleteButton]; + } [self setSwitchItemEnabled:NO itemType:ItemTypeAutofillCardSwitch]; } else { - [self hideDeleteButton]; + if (!base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)) { + [self hideDeleteButton]; + } [self setSwitchItemEnabled:YES itemType:ItemTypeAutofillCardSwitch]; } [self updateUIForEditState]; @@ -148,16 +165,6 @@ self.navigationController.toolbarHidden = NO; } -- (BOOL)shouldHideToolbar { - // There is a bug from apple that this method might be called in this view - // controller even if it is not the top view controller. - if (self.navigationController.topViewController == self) { - return NO; - } - - return [super shouldHideToolbar]; -} - #pragma mark - ChromeTableViewController - (void)loadModel { @@ -274,11 +281,15 @@ #pragma mark - SettingsRootTableViewController - (BOOL)shouldShowEditButton { + if (base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)) { + // The edit button is put in the toolbar instead of the navigation bar. + return NO; + } return YES; } - (BOOL)editButtonEnabled { - DCHECK([self shouldShowEditButton]); return [self localCreditCardsExist]; } @@ -287,6 +298,37 @@ [self deleteItemAtIndexPaths:indexPaths]; } +- (BOOL)shouldHideToolbar { + // There is a bug from apple that this method might be called in this view + // controller even if it is not the top view controller. + if (self.navigationController.topViewController == self) { + return NO; + } + + return [super shouldHideToolbar]; +} + +- (BOOL)shouldShowEditDoneButton { + if (base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)) { + // The "Done" button in the navigation bar closes the sheet. + return NO; + } + return YES; +} + +- (void)updateUIForEditState { + [super updateUIForEditState]; + if (base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)) { + [self updatedToolbarForEditState]; + } +} + +- (void)addButtonCallback { + [self handleAddPayment]; +} + #pragma mark - Actions // Called when the user clicks on the information button of the managed @@ -348,7 +390,12 @@ - (void)autofillCardSwitchChanged:(UISwitch*)switchView { [self setSwitchItemOn:[switchView isOn] itemType:ItemTypeAutofillCardSwitch]; [self setAutofillCreditCardEnabled:[switchView isOn]]; - self.addPaymentMethodButton.enabled = [self isAutofillCreditCardEnabled]; + if (base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)) { + self.addButtonInToolbar.enabled = [self isAutofillCreditCardEnabled]; + } else { + self.addPaymentMethodButton.enabled = [self isAutofillCreditCardEnabled]; + } } #pragma mark - Switch Helpers @@ -502,7 +549,7 @@ // Opens new view controller |AutofillAddCreditCardViewController| for fillig // credit card details. -- (void)handleAddPayment:(id)sender { +- (void)handleAddPayment { base::RecordAction( base::UserMetricsAction("MobileAddCreditCard.AddPaymentMethodButton")); @@ -541,13 +588,15 @@ } - (UIBarButtonItem*)addPaymentMethodButton { + DCHECK(!base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)); if (!_addPaymentMethodButton) { _addPaymentMethodButton = [[UIBarButtonItem alloc] initWithTitle:l10n_util::GetNSString( IDS_IOS_MANUAL_FALLBACK_ADD_PAYMENT_METHOD) style:UIBarButtonItemStylePlain target:self - action:@selector(handleAddPayment:)]; + action:@selector(handleAddPayment)]; _addPaymentMethodButton.accessibilityIdentifier = kSettingsAddPaymentMethodButtonId; } @@ -558,6 +607,8 @@ // Create a flexible space item to be used in the toolbar. - (UIBarButtonItem*)flexibleSpace { + DCHECK(!base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)); return [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil @@ -566,6 +617,8 @@ // Adds delete button to the bottom toolbar. - (void)showDeleteButton { + DCHECK(!base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)); if ([self isAutofillCreditCardEnabled]) { [self setToolbarItems:@[ self.deleteButton, [self flexibleSpace], self.addPaymentMethodButton @@ -579,6 +632,8 @@ // Removes delete button from the bottom toolbar. - (void)hideDeleteButton { + DCHECK(!base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)); NSArray* customToolbarItems = @[ [self flexibleSpace], self.addPaymentMethodButton ]; [self setToolbarItems:customToolbarItems animated:YES];
diff --git a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm index b8d7f2be..2201a150 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_settings_egtest.mm
@@ -261,7 +261,7 @@ // Returns matcher for the "Add Password" button located at the bottom of the // screen. id<GREYMatcher> AddPasswordButton() { - return grey_accessibilityID(kPasswordsAddPasswordButtonId); + return grey_accessibilityID(kSettingsToolbarAddButtonId); } // Returns matcher for the "Save" button in the "Add Password" view.
diff --git a/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h b/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h index 9aefc4df..76f6b19 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h +++ b/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h
@@ -12,7 +12,6 @@ extern NSString* const kPasswordsExportConfirmViewId; extern NSString* const kPasswordsSearchBarId; extern NSString* const kPasswordsScrimViewId; -extern NSString* const kPasswordsAddPasswordButtonId; // The accessibility identifier of the password details table view. extern NSString* const kPasswordDetailsTableViewId;
diff --git a/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.mm b/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.mm index 7e46711..443d8f80 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_table_view_constants.mm
@@ -12,7 +12,6 @@ NSString* const kPasswordsExportConfirmViewId = @"PasswordsExportConfirmViewId"; NSString* const kPasswordsSearchBarId = @"PasswordsSearchBar"; NSString* const kPasswordsScrimViewId = @"PasswordsScrimViewId"; -NSString* const kPasswordsAddPasswordButtonId = @"PasswordsAddPasswordButtonId"; NSString* const kPasswordDetailsTableViewId = @"PasswordDetailsTableViewId"; NSString* const kPasswordDetailsDeletionAlertViewId =
diff --git a/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm index fa885da..f2b60897 100644 --- a/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/passwords_table_view_controller.mm
@@ -249,9 +249,6 @@ // Number of compromised passwords. @property(assign) NSInteger compromisedPasswordsCount; -// Button to add new password profile in the toolbar. -@property(nonatomic, strong) UIBarButtonItem* addPasswordButton; - // Stores the most recently created or updated password form. @property(nonatomic, assign) absl::optional<password_manager::PasswordForm> mostRecentlyUpdatedPassword; @@ -358,6 +355,17 @@ action:@selector(dismissSearchController:) forControlEvents:UIControlEventTouchUpInside]; + if (base::FeatureList::IsEnabled( + password_manager::features::kSupportForAddPasswordsInSettings)) { + // If the settings are managed by enterprise policy and the password manager + // is not enabled, there won't be any add functionality. + if (!(_browserState->GetPrefs()->IsManagedPreference( + password_manager::prefs::kCredentialsEnableService) && + ![_passwordManagerEnabled value])) { + self.shouldShowAddButtonInToolbar = YES; + } + } + [self loadModel]; if (!_didReceiveSavedForms) { @@ -537,11 +545,7 @@ - (BOOL)shouldHideToolbar { if (base::FeatureList::IsEnabled( password_manager::features::kSupportForAddPasswordsInSettings)) { - // There is a bug from apple that this method might be called in this view - // controller even if it is not the top view controller. - if (self.navigationController.topViewController == self) { return NO; - } } return [super shouldHideToolbar]; @@ -560,10 +564,15 @@ [super updateUIForEditState]; if (base::FeatureList::IsEnabled( password_manager::features::kSupportForAddPasswordsInSettings)) { - [self setToolbarItemsWithEditing:self.tableView.editing]; + self.addButtonInToolbar.enabled = [_passwordManagerEnabled value]; + [self updatedToolbarForEditState]; } } +- (void)addButtonCallback { + [self.handler showAddPasswordSheet]; +} + #pragma mark - SettingsControllerProtocol - (void)reportDismissalUserAction { @@ -737,7 +746,7 @@ if (base::FeatureList::IsEnabled( password_manager::features::kSupportForAddPasswordsInSettings)) { // Disable the "Add" button if the password manager is not enabled. - self.addPasswordButton.enabled = [_passwordManagerEnabled value]; + self.addButtonInToolbar.enabled = [_passwordManagerEnabled value]; } } @@ -782,13 +791,6 @@ [self presentViewController:errorInfoPopover animated:YES completion:nil]; } -- (void)handleAddPassword:(id)sender { - [self.handler showAddPasswordSheet]; -} - -- (void)editOrDoneButtonPressed { - [self setEditing:!self.tableView.editing animated:YES]; -} #pragma mark - PasswordsConsumer @@ -1013,41 +1015,6 @@ [self searchForTerm:searchText]; } -#pragma mark - Toolbar Buttons - -// Returns "Add Password" button, to be added to the toolbar. -- (UIBarButtonItem*)addPasswordButton { - if (!_addPasswordButton) { - // TODO(crbug.com/1226006): Use i18n string for the add password button. - _addPasswordButton = - [[UIBarButtonItem alloc] initWithTitle:@"Add" - style:UIBarButtonItemStylePlain - target:self - action:@selector(handleAddPassword:)]; - _addPasswordButton.accessibilityIdentifier = kPasswordsAddPasswordButtonId; - } - _addPasswordButton.enabled = [_passwordManagerEnabled value]; - return _addPasswordButton; -} - -// Creates and returns "Edit" or "Done" button based on |editing|, to be added -// to the toolbar. -- (UIBarButtonItem*)editOrDoneButtonWithEditing:(BOOL)editing { - // TODO(crbug.com/1226006): Create separate accessibility identifiers for the - // toolbar "Edit" and "Done" buttons. - NSString* title = - l10n_util::GetNSString(editing ? IDS_IOS_NAVIGATION_BAR_DONE_BUTTON - : IDS_IOS_NAVIGATION_BAR_EDIT_BUTTON); - UIBarButtonItem* button = [[UIBarButtonItem alloc] - initWithTitle:title - style:(editing ? UIBarButtonItemStyleDone - : UIBarButtonItemStylePlain) - target:self - action:@selector(editOrDoneButtonPressed)]; - button.enabled = editing || [self editButtonEnabled]; - return button; -} - #pragma mark - Private methods // Shows loading spinner background view. @@ -1490,37 +1457,6 @@ password_manager::PasswordCheckReferrer::kPasswordSettings); } -// Sets toolbar items based on |editing|. -- (void)setToolbarItemsWithEditing:(BOOL)editing { - UIBarButtonItem* flexibleSpace = [[UIBarButtonItem alloc] - initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace - target:nil - action:nil]; - - if (_browserState->GetPrefs()->IsManagedPreference( - password_manager::prefs::kCredentialsEnableService) && - ![_passwordManagerEnabled value]) { - // Add functionality is not available. - if (!editing) { - [self setToolbarItems:@[ - flexibleSpace, [self editOrDoneButtonWithEditing:editing], flexibleSpace - ] - animated:YES]; - return; - } - } - - UIBarButtonItem* toolbarLeftButton = - editing ? self.deleteButton : self.addPasswordButton; - [self setToolbarItems:@[ - toolbarLeftButton, flexibleSpace, [self editOrDoneButtonWithEditing:editing] - ] - animated:YES]; - if (editing) { - self.deleteButton.enabled = NO; - } -} - // Scrolls the password lists such that most recently updated // SavedFormContentItem is in the middle of the screen. - (void)scrollToLastUpdatedItem {
diff --git a/ios/chrome/browser/ui/settings/privacy/privacy_coordinator.mm b/ios/chrome/browser/ui/settings/privacy/privacy_coordinator.mm index 3c53280a..348a397 100644 --- a/ios/chrome/browser/ui/settings/privacy/privacy_coordinator.mm +++ b/ios/chrome/browser/ui/settings/privacy/privacy_coordinator.mm
@@ -52,10 +52,7 @@ self.handler = HandlerForProtocol(self.browser->GetCommandDispatcher(), ApplicationCommands); - ReauthenticationModule* module = nil; - if (base::FeatureList::IsEnabled(kIncognitoAuthentication)) { - module = [[ReauthenticationModule alloc] init]; - } + ReauthenticationModule* module = [[ReauthenticationModule alloc] init]; self.viewController = [[PrivacyTableViewController alloc] initWithBrowser:self.browser reauthenticationModule:module];
diff --git a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm index ed500ee..ca6a866 100644 --- a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.mm
@@ -127,12 +127,10 @@ _prefObserverBridge->ObserveChangesForPreference( prefs::kIosHandoffToOtherDevices, &_prefChangeRegistrar); - if (base::FeatureList::IsEnabled(kIncognitoAuthentication)) { - _incognitoReauthPref = [[PrefBackedBoolean alloc] - initWithPrefService:GetApplicationContext()->GetLocalState() - prefName:prefs::kIncognitoAuthenticationSetting]; - [_incognitoReauthPref setObserver:self]; - } + _incognitoReauthPref = [[PrefBackedBoolean alloc] + initWithPrefService:GetApplicationContext()->GetLocalState() + prefName:prefs::kIncognitoAuthenticationSetting]; + [_incognitoReauthPref setObserver:self]; } return self; } @@ -161,9 +159,7 @@ TableViewModel* model = self.tableViewModel; [model addSectionWithIdentifier:SectionIdentifierPrivacyContent]; [model addSectionWithIdentifier:SectionIdentifierWebServices]; - if (base::FeatureList::IsEnabled(kIncognitoAuthentication)) { - [model addSectionWithIdentifier:SectionIdentifierIncognitoAuth]; - } + [model addSectionWithIdentifier:SectionIdentifierIncognitoAuth]; // Clear Browsing item. [model addItem:[self clearBrowsingDetailItem] @@ -178,8 +174,7 @@ // Do not show the incognito authentication setting when Incognito mode is // disabled. - if (base::FeatureList::IsEnabled(kIncognitoAuthentication) && - !IsIncognitoModeDisabled(_browserState->GetPrefs())) { + if (!IsIncognitoModeDisabled(_browserState->GetPrefs())) { // Incognito authentication item. [model addItem:self.incognitoReauthItem toSectionWithIdentifier:SectionIdentifierIncognitoAuth]; @@ -257,8 +252,6 @@ } - (SettingsSwitchItem*)incognitoReauthItem { - DCHECK(base::FeatureList::IsEnabled(kIncognitoAuthentication)); - if (_incognitoReauthItem) { return _incognitoReauthItem; } @@ -421,9 +414,6 @@ // Whether the explanatory footer for the incognito reauth setting should be // shown. It's shown when the setting cannot be enabled due to the device state. - (BOOL)shouldShowReauthFooter { - if (!base::FeatureList::IsEnabled(kIncognitoAuthentication)) { - return NO; - } return ![self deviceSupportsAuthentication]; }
diff --git a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller_unittest.mm index 5761ae0..263bf1d 100644 --- a/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller_unittest.mm
@@ -107,7 +107,7 @@ TEST_F(PrivacyTableViewControllerTest, TestModel) { CreateController(); CheckController(); - EXPECT_EQ(2, NumberOfSections()); + EXPECT_EQ(3, NumberOfSections()); // Sections[0]. EXPECT_EQ(1, NumberOfItemsInSection(0)); @@ -124,6 +124,11 @@ l10n_util::GetNSString(IDS_IOS_OPTIONS_ENABLE_HANDOFF_TO_OTHER_DEVICES), handoffSubtitle, 1, 0); + // Sections[2]. + EXPECT_EQ(1, NumberOfItemsInSection(2)); + CheckSwitchCellStateAndText( + NO, l10n_util::GetNSString(IDS_IOS_INCOGNITO_REAUTH_SETTING_NAME), 2, 0); + CheckSectionFooter( l10n_util::GetNSString(IDS_IOS_PRIVACY_GOOGLE_SERVICES_FOOTER), /* section= */ 0); @@ -137,7 +142,7 @@ CreateController(); CheckController(); - EXPECT_EQ(2, NumberOfSections()); + EXPECT_EQ(3, NumberOfSections()); CheckSectionFooter( l10n_util::GetNSString(IDS_IOS_PRIVACY_GOOGLE_SERVICES_FOOTER), @@ -154,7 +159,7 @@ CreateController(); CheckController(); - EXPECT_EQ(2, NumberOfSections()); + EXPECT_EQ(3, NumberOfSections()); CheckSectionFooter( l10n_util::GetNSString(IDS_IOS_PRIVACY_SYNC_AND_GOOGLE_SERVICES_FOOTER),
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_constants.h b/ios/chrome/browser/ui/settings/settings_root_table_constants.h index bc32847e..359bb58 100644 --- a/ios/chrome/browser/ui/settings/settings_root_table_constants.h +++ b/ios/chrome/browser/ui/settings/settings_root_table_constants.h
@@ -7,6 +7,7 @@ #import <Foundation/Foundation.h> +extern NSString* const kSettingsToolbarAddButtonId; extern NSString* const kSettingsToolbarDeleteButtonId; #endif // IOS_CHROME_BROWSER_UI_SETTINGS_SETTINGS_ROOT_TABLE_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_constants.mm b/ios/chrome/browser/ui/settings/settings_root_table_constants.mm index 87efa33..87765d1 100644 --- a/ios/chrome/browser/ui/settings/settings_root_table_constants.mm +++ b/ios/chrome/browser/ui/settings/settings_root_table_constants.mm
@@ -8,5 +8,7 @@ #error "This file requires ARC support." #endif +NSString* const kSettingsToolbarAddButtonId = @"SettingsToolbarAddButtonId"; + NSString* const kSettingsToolbarDeleteButtonId = @"SettingsToolbarDeleteButtonId";
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h index 414ab56..9c2818c 100644 --- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h +++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.h
@@ -22,6 +22,9 @@ // Delete button for the toolbar. @property(nonatomic, strong, readonly) UIBarButtonItem* deleteButton; +// Add button for the toolbar. +@property(nonatomic, strong, readonly) UIBarButtonItem* addButtonInToolbar; + // Whether this table view controller should hide the "Done" button (the right // navigation bar button). Default is NO. @property(nonatomic, assign) BOOL shouldHideDoneButton; @@ -30,6 +33,10 @@ // navigation bar button) on edit. Default is NO. @property(nonatomic, assign) BOOL shouldDisableDoneButtonOnEdit; +// Whether this table view controller should show the "Add" button in the +// toolbar(bottom left). Default is NO. +@property(nonatomic, assign) BOOL shouldShowAddButtonInToolbar; + // Updates the edit or done button to reflect editing state. If the // tableView is not in edit mode (and thus showing the 'Done' button) it is // using shouldHideDoneButton to know if it should display the edit button. @@ -37,6 +44,12 @@ // setEditing:animated: method instead of being manually triggered. - (void)updateUIForEditState; +// Updates the edit or done button to reflect editing state in the toolbar. +// Shows Add button in the left end if |shouldShowAddButtonInToolbar| is YES. In +// edit state, the left end shows the Delete button and the right end shows +// Done. +- (void)updatedToolbarForEditState; + // Reloads the table view model with |loadModel| and then reloads the // table view data. - (void)reloadData; @@ -91,6 +104,10 @@ // * Removes the transparent veil. - (void)allowUserInteraction; +// Called when the add button in the toolbar is pressed. Subclasses should +// override this method. +- (void)addButtonCallback; + @end #endif // IOS_CHROME_BROWSER_UI_SETTINGS_SETTINGS_ROOT_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm index e0b1fa6e..c413764 100644 --- a/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/settings_root_table_view_controller.mm
@@ -48,6 +48,9 @@ // Delete button for the toolbar. @property(nonatomic, strong) UIBarButtonItem* deleteButton; +// Add button for the toolbar. +@property(nonatomic, strong) UIBarButtonItem* addButtonInToolbar; + // Item displayed before the user interactions are prevented. This is used to // store the item while the interaction is prevented. @property(nonatomic, strong) UIBarButtonItem* savedBarButtonItem; @@ -78,9 +81,11 @@ // Update edit button. if ([self shouldShowEditDoneButton] && self.tableView.editing) { - self.navigationItem.rightBarButtonItem = [self createEditModeDoneButton]; + self.navigationItem.rightBarButtonItem = + [self createEditModeDoneButtonForToolbar:NO]; } else if (self.shouldShowEditButton) { - self.navigationItem.rightBarButtonItem = [self createEditButton]; + self.navigationItem.rightBarButtonItem = + [self createEditButtonForToolbar:NO]; } else { self.navigationItem.rightBarButtonItem = [self doneButtonIfNeeded]; } @@ -93,6 +98,40 @@ } } +- (void)updatedToolbarForEditState { + if (self.shouldHideToolbar) { + return; + } + UIBarButtonItem* flexibleSpace = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace + target:nil + action:nil]; + + UIBarButtonItem* toolbarLeftButton = nil; + if (self.tableView.editing) { + toolbarLeftButton = self.deleteButton; + } else if (self.shouldShowAddButtonInToolbar) { + toolbarLeftButton = self.addButtonInToolbar; + } + + UIBarButtonItem* editOrDoneButton = + self.tableView.editing ? [self createEditModeDoneButtonForToolbar:YES] + : [self createEditButtonForToolbar:YES]; + + if (toolbarLeftButton) { + [self + setToolbarItems:@[ toolbarLeftButton, flexibleSpace, editOrDoneButton ] + animated:YES]; + } else { + [self setToolbarItems:@[ flexibleSpace, editOrDoneButton, flexibleSpace ] + animated:YES]; + } + + if (self.tableView.editing) { + self.deleteButton.enabled = NO; + } +} + - (void)reloadData { [self loadModel]; [self.tableView reloadData]; @@ -113,6 +152,18 @@ return _deleteButton; } +- (UIBarButtonItem*)addButtonInToolbar { + if (!_addButtonInToolbar) { + _addButtonInToolbar = [[UIBarButtonItem alloc] + initWithTitle:l10n_util::GetNSString(IDS_IOS_SETTINGS_TOOLBAR_ADD) + style:UIBarButtonItemStylePlain + target:self + action:@selector(addButtonCallback)]; + _addButtonInToolbar.accessibilityIdentifier = kSettingsToolbarAddButtonId; + } + return _addButtonInToolbar; +} + #pragma mark - UIViewController - (void)viewDidLoad { @@ -237,25 +288,25 @@ return doneButton; } -- (UIBarButtonItem*)createEditButton { +- (UIBarButtonItem*)createEditButtonForToolbar:(BOOL)toolbar { // Create a custom Edit bar button item, as Material Navigation Bar does not // handle a system UIBarButtonSystemItemEdit item. UIBarButtonItem* button = [[UIBarButtonItem alloc] initWithTitle:l10n_util::GetNSString(IDS_IOS_NAVIGATION_BAR_EDIT_BUTTON) - style:UIBarButtonItemStyleDone - target:self + style:(toolbar ? UIBarButtonItemStylePlain + : UIBarButtonItemStyleDone)target:self action:@selector(editButtonPressed)]; [button setEnabled:[self editButtonEnabled]]; return button; } -- (UIBarButtonItem*)createEditModeDoneButton { +- (UIBarButtonItem*)createEditModeDoneButtonForToolbar:(BOOL)toolbar { // Create a custom Done bar button item, as Material Navigation Bar does not // handle a system UIBarButtonSystemItemDone item. return [[UIBarButtonItem alloc] initWithTitle:l10n_util::GetNSString(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON) - style:UIBarButtonItemStyleDone - target:self + style:(toolbar ? UIBarButtonItemStylePlain + : UIBarButtonItemStyleDone)target:self action:@selector(editButtonPressed)]; } @@ -389,6 +440,11 @@ self.savedBarButtonItemPosition = kUndefinedBarButtonItemPosition; } +- (void)addButtonCallback { + // Subclasses should implement. + NOTREACHED(); +} + #pragma mark - UIAdaptivePresentationControllerDelegate - (BOOL)presentationControllerShouldDismiss:
diff --git a/ios/chrome/browser/ui/table_view/cells/table_view_disclosure_header_footer_item.mm b/ios/chrome/browser/ui/table_view/cells/table_view_disclosure_header_footer_item.mm index 7f65d966..97b79f2 100644 --- a/ios/chrome/browser/ui/table_view/cells/table_view_disclosure_header_footer_item.mm +++ b/ios/chrome/browser/ui/table_view/cells/table_view_disclosure_header_footer_item.mm
@@ -84,7 +84,6 @@ _subtitleLabel = [[UILabel alloc] init]; _subtitleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]; - _subtitleLabel.textColor = [UIColor colorNamed:kTextSecondaryColor]; [_subtitleLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical]; @@ -186,8 +185,11 @@ #pragma mark - properties - (void)setDisabled:(BOOL)disabled { - _titleLabel.textColor = disabled ? [UIColor colorNamed:kTextSecondaryColor] + _titleLabel.textColor = disabled ? [UIColor colorNamed:kTextQuaternaryColor] : [UIColor colorNamed:kTextPrimaryColor]; + _subtitleLabel.textColor = disabled + ? [UIColor colorNamed:kTextQuaternaryColor] + : [UIColor colorNamed:kTextSecondaryColor]; _disclosureImageView.image = disabled ? nil : [UIImage imageNamed:@"table_view_cell_chevron"]; _disabled = disabled;
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc index e5fbf5f1..487bea6 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.cc +++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -30,9 +30,6 @@ const base::Feature kModernTabStrip{"ModernTabStrip", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kIncognitoAuthentication{ - "enable-incognito-authentication-ios", base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kIncognitoBrandConsistencyForIOS{ "IncognitoBrandConsistencyForIOS", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/ui_feature_flags.h b/ios/chrome/browser/ui/ui_feature_flags.h index a2ecf8b..3fc0df6 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.h +++ b/ios/chrome/browser/ui/ui_feature_flags.h
@@ -36,9 +36,6 @@ // finished. Flag to modernize the tabstrip without disturbing the existing one. extern const base::Feature kModernTabStrip; -// Adds a setting to enable biometric authentication for incognito tabs. -extern const base::Feature kIncognitoAuthentication; - // Enables the usage of dark mode color while in Incognito mode. extern const base::Feature kIncognitoBrandConsistencyForIOS;
diff --git a/ios/chrome/browser/url_loading/BUILD.gn b/ios/chrome/browser/url_loading/BUILD.gn index e2259c83..3cf4eb3 100644 --- a/ios/chrome/browser/url_loading/BUILD.gn +++ b/ios/chrome/browser/url_loading/BUILD.gn
@@ -90,6 +90,7 @@ "//ios/chrome/browser/main:test_support", "//ios/chrome/browser/ntp", "//ios/chrome/browser/search_engines", + "//ios/chrome/browser/ui/main:scene_state_header", "//ios/chrome/browser/web", "//ios/chrome/browser/web:web_internal", "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/browser/url_loading/url_loading_browser_agent.mm b/ios/chrome/browser/url_loading/url_loading_browser_agent.mm index 2c8b50d..6cd37e9 100644 --- a/ios/chrome/browser/url_loading/url_loading_browser_agent.mm +++ b/ios/chrome/browser/url_loading/url_loading_browser_agent.mm
@@ -310,8 +310,7 @@ DCHECK(delegate_); DCHECK(browser_); - if (base::FeatureList::IsEnabled(kIncognitoAuthentication) && - params.in_incognito) { + if (params.in_incognito) { IncognitoReauthSceneAgent* reauthAgent = [IncognitoReauthSceneAgent agentFromScene:SceneStateBrowserAgent::FromBrowser(browser_) ->GetSceneState()];
diff --git a/ios/chrome/browser/url_loading/url_loading_browser_agent_unittest.mm b/ios/chrome/browser/url_loading/url_loading_browser_agent_unittest.mm index 18c9be6a..b89357b 100644 --- a/ios/chrome/browser/url_loading/url_loading_browser_agent_unittest.mm +++ b/ios/chrome/browser/url_loading/url_loading_browser_agent_unittest.mm
@@ -14,6 +14,8 @@ #include "ios/chrome/browser/main/test_browser.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h" #import "ios/chrome/browser/ntp/new_tab_page_tab_helper_delegate.h" +#import "ios/chrome/browser/ui/main/scene_state.h" +#import "ios/chrome/browser/ui/main/scene_state_browser_agent.h" #import "ios/chrome/browser/url_loading/scene_url_loading_service.h" #import "ios/chrome/browser/url_loading/test_scene_url_loading_service.h" #import "ios/chrome/browser/url_loading/url_loading_notifier_browser_agent.h" @@ -60,9 +62,12 @@ chrome_browser_state_->GetOffTheRecordChromeBrowserState()), url_loading_delegate_([[URLLoadingTestDelegate alloc] init]), scene_loader_(std::make_unique<TestSceneUrlLoadingService>()), - otr_browser_(std::make_unique<TestBrowser>(otr_browser_state_)) { + otr_browser_(std::make_unique<TestBrowser>(otr_browser_state_)), + scene_state_([[SceneState alloc] initWithAppState:nil]) { // Configure app service. scene_loader_->current_browser_ = browser_.get(); + SceneStateBrowserAgent::CreateForBrowser(browser_.get(), scene_state_); + SceneStateBrowserAgent::CreateForBrowser(otr_browser_.get(), scene_state_); // Disable web usage on both browsers WebUsageEnablerBrowserAgent::CreateForBrowser(browser_.get()); @@ -123,6 +128,7 @@ UrlLoadingBrowserAgent* loader_; std::unique_ptr<Browser> otr_browser_; UrlLoadingBrowserAgent* otr_loader_; + SceneState* scene_state_; }; TEST_F(URLLoadingBrowserAgentTest, TestSwitchToTab) {
diff --git a/ios/chrome/browser/web/chrome_web_client.h b/ios/chrome/browser/web/chrome_web_client.h index 0ea7cc19..7b307c8 100644 --- a/ios/chrome/browser/web/chrome_web_client.h +++ b/ios/chrome/browser/web/chrome_web_client.h
@@ -52,7 +52,6 @@ UIView* GetWindowedContainer() override; bool EnableLongPressAndForceTouchHandling() const override; bool EnableLongPressUIContextMenu() const override; - bool ForceMobileVersionByDefault(const GURL& url) override; web::UserAgentType GetDefaultUserAgent(id<UITraitEnvironment> web_view, const GURL& url) override; bool RestoreSessionFromCache(web::WebState* web_state) const override;
diff --git a/ios/chrome/browser/web/chrome_web_client.mm b/ios/chrome/browser/web/chrome_web_client.mm index 32659e4a..e1ec1f2 100644 --- a/ios/chrome/browser/web/chrome_web_client.mm +++ b/ios/chrome/browser/web/chrome_web_client.mm
@@ -403,26 +403,11 @@ return web::features::UseWebViewNativeContextMenuSystem(); } -bool ChromeWebClient::ForceMobileVersionByDefault(const GURL& url) { - DCHECK(web::features::UseWebClientDefaultUserAgent()); - if (base::FeatureList::IsEnabled(web::kMobileGoogleSRP)) { - return google_util::IsGoogleSearchUrl(url); - } - return false; -} - web::UserAgentType ChromeWebClient::GetDefaultUserAgent( id<UITraitEnvironment> web_view, const GURL& url) { DCHECK(web::features::UseWebClientDefaultUserAgent()); - if (ForceMobileVersionByDefault(url)) - return web::UserAgentType::MOBILE; - BOOL isRegularRegular = web_view.traitCollection.horizontalSizeClass == - UIUserInterfaceSizeClassRegular && - web_view.traitCollection.verticalSizeClass == - UIUserInterfaceSizeClassRegular; - return isRegularRegular ? web::UserAgentType::DESKTOP - : web::UserAgentType::MOBILE; + return web::UserAgentType::MOBILE; } bool ChromeWebClient::RestoreSessionFromCache(web::WebState* web_state) const {
diff --git a/ios/chrome/browser/web/chrome_web_client_unittest.mm b/ios/chrome/browser/web/chrome_web_client_unittest.mm index 7c4aca6..922a8e4 100644 --- a/ios/chrome/browser/web/chrome_web_client_unittest.mm +++ b/ios/chrome/browser/web/chrome_web_client_unittest.mm
@@ -493,15 +493,9 @@ // Tests the default user agent for different views. TEST_F(ChromeWebClientTest, DefaultUserAgent) { - if (@available(iOS 13, *)) { - } else { - // The feature is only available on iOS 13. - return; - } base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitWithFeatures( - {web::features::kUseDefaultUserAgentInWebClient, web::kMobileGoogleSRP}, - {}); + {web::features::kUseDefaultUserAgentInWebClient}, {}); ChromeWebClient web_client; const GURL google_url = GURL("https://www.google.com/search?q=test"); @@ -544,7 +538,7 @@ id mock_regular_regular_view = OCMClassMock([UIView class]); OCMStub([mock_regular_regular_view traitCollection]) .andReturn(regular_regular); - EXPECT_EQ(web::UserAgentType::DESKTOP, + EXPECT_EQ(web::UserAgentType::MOBILE, web_client.GetDefaultUserAgent(mock_regular_regular_view, non_google_url));
diff --git a/ios/chrome/browser/web/features.cc b/ios/chrome/browser/web/features.cc index 4eb1874..bb69302 100644 --- a/ios/chrome/browser/web/features.cc +++ b/ios/chrome/browser/web/features.cc
@@ -15,9 +15,6 @@ const base::Feature kWebPageAlternativeTextZoom{ "WebPageAlternativeTextZoom", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kMobileGoogleSRP{"MobileGoogleSRP", - base::FEATURE_DISABLED_BY_DEFAULT}; - const base::Feature kRestoreSessionFromCache{"RestoreSessionFromCache", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/web/features.h b/ios/chrome/browser/web/features.h index 4b49a65..cc9832dd 100644 --- a/ios/chrome/browser/web/features.h +++ b/ios/chrome/browser/web/features.h
@@ -20,10 +20,6 @@ // Used to enable a different method of zooming web pages. extern const base::Feature kWebPageAlternativeTextZoom; -// Feature flag to keep the mobile version for Google SRP. Should be used when -// the desktop version is requested by default. -extern const base::Feature kMobileGoogleSRP; - // Feature flag for to use native session restoration. extern const base::Feature kRestoreSessionFromCache;
diff --git a/ios/web/common/features.mm b/ios/web/common/features.mm index e5c9269..44c8cd4 100644 --- a/ios/web/common/features.mm +++ b/ios/web/common/features.mm
@@ -56,10 +56,7 @@ "DisableNonHTMLScreenshotOnIOS15", base::FEATURE_ENABLED_BY_DEFAULT}; bool UseWebClientDefaultUserAgent() { - if (@available(iOS 13, *)) { - return base::FeatureList::IsEnabled(kUseDefaultUserAgentInWebClient); - } - return false; + return base::FeatureList::IsEnabled(kUseDefaultUserAgentInWebClient); } bool UseWebViewNativeContextMenuWeb() {
diff --git a/ios/web/common/user_agent_unittest.mm b/ios/web/common/user_agent_unittest.mm index cbc710bf..80123d2 100644 --- a/ios/web/common/user_agent_unittest.mm +++ b/ios/web/common/user_agent_unittest.mm
@@ -59,14 +59,10 @@ GetUserAgentTypeWithDescription(kNoneDescription)); EXPECT_EQ(UserAgentType::NONE, GetUserAgentTypeWithDescription(kInvalidDescription)); - - // The kUseDefaultUserAgentInWebClient feature is only available on iOS 13+. - if (@available(iOS 13, *)) { - EXPECT_EQ(kAutomaticDescription, - GetUserAgentTypeDescription(UserAgentType::AUTOMATIC)); - EXPECT_EQ(UserAgentType::AUTOMATIC, - GetUserAgentTypeWithDescription(kAutomaticDescription)); - } + EXPECT_EQ(kAutomaticDescription, + GetUserAgentTypeDescription(UserAgentType::AUTOMATIC)); + EXPECT_EQ(UserAgentType::AUTOMATIC, + GetUserAgentTypeWithDescription(kAutomaticDescription)); } // Tests the mobile user agent returned for a specific product.
diff --git a/ios/web/navigation/crw_session_storage_unittest.mm b/ios/web/navigation/crw_session_storage_unittest.mm index 0d6d13f6..eda5eb9 100644 --- a/ios/web/navigation/crw_session_storage_unittest.mm +++ b/ios/web/navigation/crw_session_storage_unittest.mm
@@ -111,11 +111,6 @@ // Tests that unarchiving CRWSessionStorage data results in an equivalent // storage when the user agent is automatic. TEST_F(CRWNSessionStorageTest, EncodeDecodeAutomatic) { - // The kUseDefaultUserAgentInWebClient feature is only available on iOS 13+. - if (!base::ios::IsRunningOnIOS13OrLater()) { - return; - } - base::test::ScopedFeatureList feature; feature.InitAndEnableFeature(web::features::kUseDefaultUserAgentInWebClient); session_storage_.userAgentType = web::UserAgentType::AUTOMATIC;
diff --git a/ios/web/public/web_client.h b/ios/web/public/web_client.h index b6545328..6c2fd88e 100644 --- a/ios/web/public/web_client.h +++ b/ios/web/public/web_client.h
@@ -177,13 +177,6 @@ // Enables the logic to handle long press context menu with UIContextMenu. virtual bool EnableLongPressUIContextMenu() const; - // This method is used when the user didn't express any preference for the - // version of |url|. Returning true allows to make sure that for |url|, the - // mobile version will be used, unless the user explicitly requested the - // desktop version. This method can be overriden to avoid having specific URL - // being requested in desktop mode when the default mode is desktop. - virtual bool ForceMobileVersionByDefault(const GURL& url); - // Returns the UserAgentType that should be used by default for the web // content, based on the size class of |web_view| and the |url|. virtual UserAgentType GetDefaultUserAgent(id<UITraitEnvironment> web_view,
diff --git a/ios/web/web_client.mm b/ios/web/web_client.mm index ad9e40b..1dabedb 100644 --- a/ios/web/web_client.mm +++ b/ios/web/web_client.mm
@@ -110,10 +110,6 @@ return false; } -bool WebClient::ForceMobileVersionByDefault(const GURL&) { - return false; -} - bool WebClient::RestoreSessionFromCache(web::WebState* web_state) const { return false; }
diff --git a/media/capture/video/linux/fake_v4l2_impl.cc b/media/capture/video/linux/fake_v4l2_impl.cc index 0a3c15f..f2936a91 100644 --- a/media/capture/video/linux/fake_v4l2_impl.cc +++ b/media/capture/video/linux/fake_v4l2_impl.cc
@@ -26,6 +26,8 @@ static const uint32_t kMaxBufferCount = 5; static const int kDefaultWidth = 640; static const int kDefaultHeight = 480; +static const unsigned int kMaxWidth = 3840; +static const unsigned int kMaxHeight = 2160; // 20 fps. static const int kDefaultFrameInternvalNumerator = 50; @@ -159,8 +161,11 @@ } int s_fmt(v4l2_format* format) { - if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + format->fmt.pix.width > kMaxWidth || + format->fmt.pix.height > kMaxHeight) { return EINVAL; + } v4l2_pix_format& pix_format = format->fmt.pix; // We only support YUV420 output for now. Tell this to the client by // overwriting whatever format it requested.
diff --git a/net/cookies/site_for_cookies.cc b/net/cookies/site_for_cookies.cc index b9330de5..5907339ec 100644 --- a/net/cookies/site_for_cookies.cc +++ b/net/cookies/site_for_cookies.cc
@@ -207,8 +207,21 @@ } bool operator<(const SiteForCookies& lhs, const SiteForCookies& rhs) { - return std::tie(lhs.site_, lhs.schemefully_same_) < - std::tie(rhs.site_, rhs.schemefully_same_); + // Similar to IsEquivalent(), if they're both null then they're equivalent + // and therefore `lhs` is not < `rhs`. + if (lhs.IsNull() && rhs.IsNull()) + return false; + + // If only `lhs` is null then it's always < `rhs`. + if (lhs.IsNull()) + return true; + + // If only `rhs` is null then `lhs` is not < `rhs`. + if (rhs.IsNull()) + return false; + + // Otherwise neither are null and we need to compare the `site_`s. + return lhs.site_ < rhs.site_; } } // namespace net
diff --git a/net/cookies/site_for_cookies_unittest.cc b/net/cookies/site_for_cookies_unittest.cc index c4d720f..bf20aef 100644 --- a/net/cookies/site_for_cookies_unittest.cc +++ b/net/cookies/site_for_cookies_unittest.cc
@@ -610,10 +610,22 @@ SiteForCookies third = SiteForCookies::FromUrl(GURL("https://examplelongerstill.com")); + SiteForCookies null1 = SiteForCookies(); + SiteForCookies null2 = + SiteForCookies::FromUrl(GURL("https://examplelongerstillstill.com")); + null2.SetSchemefullySameForTesting(false); + EXPECT_LT(first, second); EXPECT_LT(second, third); EXPECT_LT(first, third); + EXPECT_LT(null1, first); + EXPECT_LT(null2, first); + EXPECT_FALSE(second < first); + EXPECT_FALSE(first < null1); + EXPECT_FALSE(first < null2); + EXPECT_FALSE(null1 < null2); + EXPECT_FALSE(null2 < null1); } } // namespace net
diff --git a/net/proxy_resolution/configured_proxy_resolution_service.cc b/net/proxy_resolution/configured_proxy_resolution_service.cc index b256b3e..7eeec29 100644 --- a/net/proxy_resolution/configured_proxy_resolution_service.cc +++ b/net/proxy_resolution/configured_proxy_resolution_service.cc
@@ -49,9 +49,7 @@ #elif defined(OS_MAC) #include "net/proxy_resolution/proxy_config_service_mac.h" #include "net/proxy_resolution/proxy_resolver_mac.h" -// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch -// of lacros-chrome is complete. -#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) +#elif defined(OS_LINUX) #include "net/proxy_resolution/proxy_config_service_linux.h" #elif defined(OS_ANDROID) #include "net/proxy_resolution/proxy_config_service_android.h" @@ -64,10 +62,7 @@ namespace { -// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch -// of lacros-chrome is complete. -#if defined(OS_WIN) || defined(OS_APPLE) || \ - (defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) +#if defined(OS_WIN) || defined(OS_APPLE) || defined(OS_LINUX) constexpr net::NetworkTrafficAnnotationTag kSystemProxyConfigTrafficAnnotation = net::DefineNetworkTrafficAnnotation("proxy_config_system", R"( semantics { @@ -1417,7 +1412,7 @@ << "profile_io_data.cc::CreateProxyConfigService and this should " << "be used only for examples."; return std::make_unique<UnsetProxyConfigService>(); -#elif defined(OS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) +#elif defined(OS_LINUX) std::unique_ptr<ProxyConfigServiceLinux> linux_config_service( new ProxyConfigServiceLinux());
diff --git a/services/network/cors/preflight_controller.cc b/services/network/cors/preflight_controller.cc index 23aff43..6433e5e7 100644 --- a/services/network/cors/preflight_controller.cc +++ b/services/network/cors/preflight_controller.cc
@@ -368,9 +368,6 @@ network::URLLoaderCompletionStatus(net::ERR_INVALID_REDIRECT)); } - // Preflight should not allow any redirect. - FinalizeLoader(); - std::move(completion_callback_) .Run(net::ERR_FAILED, CorsErrorStatus(mojom::CorsError::kPreflightDisallowedRedirect), @@ -392,8 +389,6 @@ *devtools_request_id_, network::URLLoaderCompletionStatus(net::OK)); } - FinalizeLoader(); - absl::optional<CorsErrorStatus> detected_error_status; bool has_authorization_covered_by_wildcard = false; std::unique_ptr<PreflightResult> result = CreatePreflightResult( @@ -421,34 +416,26 @@ std::move(completion_callback_) .Run(detected_error_status ? net::ERR_FAILED : net::OK, detected_error_status, has_authorization_covered_by_wildcard); - - RemoveFromController(); - // |this| is deleted here. } void HandleResponseBody(std::unique_ptr<std::string> response_body) { - // Reached only when the request fails without receiving headers, e.g. - // unknown hosts, unreachable remote, reset by peer, and so on. - // See https://crbug.com/826868 for related discussion. - DCHECK(!response_body); const int error = loader_->NetError(); - DCHECK_NE(error, net::OK); - if (devtools_observer_) { - DCHECK(devtools_request_id_); - devtools_observer_->OnCorsPreflightRequestCompleted( - *devtools_request_id_, network::URLLoaderCompletionStatus(error)); + if (!completion_callback_.is_null()) { + // As HandleResponseHeader() isn't called due to a request failure, such + // as unknown hosts. unreachable remote, reset by peer, and so on, we + // still hold `completion_callback_` to invoke. + if (devtools_observer_) { + DCHECK(devtools_request_id_); + devtools_observer_->OnCorsPreflightRequestCompleted( + *devtools_request_id_, network::URLLoaderCompletionStatus(error)); + } + std::move(completion_callback_).Run(error, absl::nullopt, false); } - FinalizeLoader(); - std::move(completion_callback_).Run(error, absl::nullopt, false); + RemoveFromController(); // |this| is deleted here. } - void FinalizeLoader() { - DCHECK(loader_); - loader_.reset(); - } - // Removes |this| instance from |controller_|. Once the method returns, |this| // is already removed. void RemoveFromController() { controller_->RemoveLoader(this); }
diff --git a/testing/buildbot/filters/fuchsia.components_unittests.filter b/testing/buildbot/filters/fuchsia.components_unittests.filter index 742a68c..0559240 100644 --- a/testing/buildbot/filters/fuchsia.components_unittests.filter +++ b/testing/buildbot/filters/fuchsia.components_unittests.filter
@@ -513,7 +513,7 @@ -URLBlocklistPolicyHandlerTest.ApplyPolicySettings_CheckPolicySettingsMaxFiltersLimitExceeded* -URLBlocklistPolicyHandlerTest.CheckPolicySettings_DisabledSchemesWrong* -URLBlocklistPolicyHandlerTest.CheckPolicySettings_URLBlocklistWrong* --UserAgentUtilsTest.UserAgentStringOrdering +-All/UserAgentUtilsTest.UserAgentStringOrdering/* -Voice* -WebAppOriginAssociationFetcher* -Zero*
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 3580dde..e2a791a5 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1419,6 +1419,7 @@ "unload_support": "opt_in_header_required" }, "enable_features": [ + "BFCachePerformanceManagerPolicy", "BackForwardCache", "LoadingTasksUnfreezable" ] @@ -4624,21 +4625,6 @@ ] } ], - "IncognitoBiometricReauth": [ - { - "platforms": [ - "ios" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "enable-incognito-authentication-ios" - ] - } - ] - } - ], "IncognitoBrandConsistencyForDesktop": [ { "platforms": [
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium index 0c6a6a8..4c4ca86 100644 --- a/third_party/abseil-cpp/README.chromium +++ b/third_party/abseil-cpp/README.chromium
@@ -4,7 +4,7 @@ License: Apache 2.0 License File: LICENSE Version: 0 -Revision: b2dc72c17ac663885b62334d334da9f8970543b5 +Revision: de71511109d967000e68baedb75de104adb2b778 Security Critical: yes Description:
diff --git a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc index ca03d9b..4b13370 100644 --- a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +++ b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc
@@ -68,6 +68,7 @@ hashes_bitwise_or.store(0, std::memory_order_relaxed); hashes_bitwise_and.store(~size_t{}, std::memory_order_relaxed); hashes_bitwise_xor.store(0, std::memory_order_relaxed); + max_reserve.store(0, std::memory_order_relaxed); create_time = absl::Now(); // The inliner makes hardcoded skip_count difficult (especially when combined
diff --git a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h index d86207f..812118e 100644 --- a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +++ b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h
@@ -80,6 +80,7 @@ std::atomic<size_t> hashes_bitwise_or; std::atomic<size_t> hashes_bitwise_and; std::atomic<size_t> hashes_bitwise_xor; + std::atomic<size_t> max_reserve; // All of the fields below are set by `PrepareForSampling`, they must not be // mutated in `Record*` functions. They are logically `const` in that sense. @@ -107,6 +108,18 @@ std::memory_order_relaxed); } +inline void RecordReservationSlow(HashtablezInfo* info, + size_t target_capacity) { + info->max_reserve.store( + (std::max)(info->max_reserve.load(std::memory_order_relaxed), + target_capacity), + std::memory_order_relaxed); +} + +inline void RecordClearedReservationSlow(HashtablezInfo* info) { + info->max_reserve.store(0, std::memory_order_relaxed); +} + inline void RecordStorageChangedSlow(HashtablezInfo* info, size_t size, size_t capacity) { info->size.store(size, std::memory_order_relaxed); @@ -170,6 +183,16 @@ RecordRehashSlow(info_, total_probe_length); } + inline void RecordReservation(size_t target_capacity) { + if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; + RecordReservationSlow(info_, target_capacity); + } + + inline void RecordClearedReservation() { + if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; + RecordClearedReservationSlow(info_); + } + inline void RecordInsert(size_t hash, size_t distance_from_desired) { if (ABSL_PREDICT_TRUE(info_ == nullptr)) return; RecordInsertSlow(info_, hash, distance_from_desired); @@ -199,6 +222,8 @@ inline void RecordStorageChanged(size_t /*size*/, size_t /*capacity*/) {} inline void RecordRehash(size_t /*total_probe_length*/) {} + inline void RecordReservation(size_t /*target_capacity*/) {} + inline void RecordClearedReservation() {} inline void RecordInsert(size_t /*hash*/, size_t /*distance_from_desired*/) {} inline void RecordErase() {}
diff --git a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc index 53fcfe6f..f053c19 100644 --- a/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc +++ b/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler_test.cc
@@ -91,6 +91,7 @@ EXPECT_EQ(info.hashes_bitwise_or.load(), 0); EXPECT_EQ(info.hashes_bitwise_and.load(), ~size_t{}); EXPECT_EQ(info.hashes_bitwise_xor.load(), 0); + EXPECT_EQ(info.max_reserve.load(), 0); EXPECT_GE(info.create_time, test_start); info.capacity.store(1, std::memory_order_relaxed); @@ -101,6 +102,7 @@ info.hashes_bitwise_or.store(1, std::memory_order_relaxed); info.hashes_bitwise_and.store(1, std::memory_order_relaxed); info.hashes_bitwise_xor.store(1, std::memory_order_relaxed); + info.max_reserve.store(1, std::memory_order_relaxed); info.create_time = test_start - absl::Hours(20); info.PrepareForSampling(); @@ -113,6 +115,7 @@ EXPECT_EQ(info.hashes_bitwise_or.load(), 0); EXPECT_EQ(info.hashes_bitwise_and.load(), ~size_t{}); EXPECT_EQ(info.hashes_bitwise_xor.load(), 0); + EXPECT_EQ(info.max_reserve.load(), 0); EXPECT_GE(info.create_time, test_start); } @@ -187,6 +190,22 @@ EXPECT_EQ(info.num_rehashes.load(), 1); } +TEST(HashtablezInfoTest, RecordReservation) { + HashtablezInfo info; + absl::MutexLock l(&info.init_mu); + info.PrepareForSampling(); + RecordReservationSlow(&info, 3); + EXPECT_EQ(info.max_reserve.load(), 3); + + RecordReservationSlow(&info, 2); + // High watermark does not change + EXPECT_EQ(info.max_reserve.load(), 3); + + RecordReservationSlow(&info, 10); + // High watermark does change + EXPECT_EQ(info.max_reserve.load(), 10); +} + #if defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE) TEST(HashtablezSamplerTest, SmallSampleParameter) { SetHashtablezEnabled(true);
diff --git a/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h b/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h index f4919ce..212052e 100644 --- a/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +++ b/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h
@@ -1069,6 +1069,8 @@ // past that we simply deallocate the array. if (capacity_ > 127) { destroy_slots(); + + infoz().RecordClearedReservation(); } else if (capacity_) { for (size_t i = 0; i != capacity_; ++i) { if (IsFull(ctrl_[i])) { @@ -1382,14 +1384,20 @@ if (n == 0 && size_ == 0) { destroy_slots(); infoz().RecordStorageChanged(0, 0); + infoz().RecordClearedReservation(); return; } + // bitor is a faster way of doing `max` here. We will round up to the next // power-of-2-minus-1, so bitor is good enough. auto m = NormalizeCapacity(n | GrowthToLowerboundCapacity(size())); // n == 0 unconditionally rehashes as per the standard. if (n == 0 || m > capacity_) { resize(m); + + // This is after resize, to ensure that we have completed the allocation + // and have potentially sampled the hashtable. + infoz().RecordReservation(n); } } @@ -1397,6 +1405,10 @@ if (n > size() + growth_left()) { size_t m = GrowthToLowerboundCapacity(n); resize(NormalizeCapacity(m)); + + // This is after resize, to ensure that we have completed the allocation + // and have potentially sampled the hashtable. + infoz().RecordReservation(n); } } @@ -1638,6 +1650,7 @@ PolicyTraits::destroy(&alloc_ref(), slots_ + i); } } + // Unpoison before returning the memory to the allocator. SanitizerUnpoisonMemoryRegion(slots_, sizeof(slot_type) * capacity_); Deallocate<alignof(slot_type)>(
diff --git a/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc b/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc index 4012a3a..b46c492 100644 --- a/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc +++ b/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc
@@ -2049,15 +2049,31 @@ std::vector<IntTable> tables; for (int i = 0; i < 1000000; ++i) { tables.emplace_back(); + + const bool do_reserve = (i % 10 > 5); + const bool do_rehash = !do_reserve && (i % 10 > 0); + + if (do_reserve) { + // Don't reserve on all tables. + tables.back().reserve(10 * (i % 10)); + } + tables.back().insert(1); tables.back().insert(i % 5); + + if (do_rehash) { + // Rehash some other tables. + tables.back().rehash(10 * (i % 10)); + } } size_t end_size = 0; std::unordered_map<size_t, int> observed_checksums; + std::unordered_map<ssize_t, int> reservations; end_size += sampler.Iterate([&](const HashtablezInfo& info) { if (preexisting_info.count(&info) == 0) { observed_checksums[info.hashes_bitwise_xor.load( std::memory_order_relaxed)]++; + reservations[info.max_reserve.load(std::memory_order_relaxed)]++; } ++end_size; }); @@ -2068,6 +2084,15 @@ for (const auto& [_, count] : observed_checksums) { EXPECT_NEAR((100 * count) / static_cast<double>(tables.size()), 0.2, 0.05); } + + EXPECT_EQ(reservations.size(), 10); + for (const auto& [reservation, count] : reservations) { + EXPECT_GE(reservation, 0); + EXPECT_LT(reservation, 100); + + EXPECT_NEAR((100 * count) / static_cast<double>(tables.size()), 0.1, 0.05) + << reservation; + } } #endif // ABSL_INTERNAL_HASHTABLEZ_SAMPLE
diff --git a/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h b/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h index a257ea5..5e04a9c 100644 --- a/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h +++ b/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h
@@ -41,7 +41,6 @@ // samples maintained by the SampleRecorder. Type T defines the sampled data. template <typename T> struct Sample { - public: // Guards the ability to restore the sample to a pristine state. This // prevents races with sampling and resurrecting an object. absl::Mutex init_mu;
diff --git a/third_party/abseil-cpp/absl/strings/cord.cc b/third_party/abseil-cpp/absl/strings/cord.cc index 115705a20..29af978 100644 --- a/third_party/abseil-cpp/absl/strings/cord.cc +++ b/third_party/abseil-cpp/absl/strings/cord.cc
@@ -708,8 +708,8 @@ if (btree_enabled()) { // TODO(b/192061034): keep legacy 10% growth rate: consider other rates. rep = ForceBtree(rep); - const size_t alloc_hint = (std::min)(kMaxFlatLength, rep->length / 10); - rep = CordRepBtree::Append(rep->btree(), src, alloc_hint); + const size_t min_growth = std::max<size_t>(rep->length / 10, src.size()); + rep = CordRepBtree::Append(rep->btree(), src, min_growth - src.size()); } else { // Use new block(s) for any remaining bytes that were not handled above. // Alloc extra memory only if the right child of the root of the new tree
diff --git a/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc b/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc index 8fe589fa..6d53ab61 100644 --- a/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc +++ b/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc
@@ -96,7 +96,8 @@ maybe_dump_data(rep); DumpAll(substring->child, include_contents, stream, depth + 1); } else if (rep->tag >= FLAT) { - stream << "Flat, len = " << rep->length; + stream << "Flat, len = " << rep->length + << ", cap = " << rep->flat()->Capacity(); maybe_dump_data(rep); } else if (rep->tag == EXTERNAL) { stream << "Extn, len = " << rep->length;
diff --git a/third_party/abseil-cpp/absl/time/time.h b/third_party/abseil-cpp/absl/time/time.h index e9cbce84..5abd815a 100644 --- a/third_party/abseil-cpp/absl/time/time.h +++ b/third_party/abseil-cpp/absl/time/time.h
@@ -480,8 +480,9 @@ // ToInt64Hours() // // Helper functions that convert a Duration to an integral count of the -// indicated unit. These functions are shorthand for the `IDivDuration()` -// function above; see its documentation for details about overflow, etc. +// indicated unit. These return the same results as the `IDivDuration()` +// function, though they usually do so more efficiently; see the +// documentation of `IDivDuration()` for details about overflow, etc. // // Example: //
diff --git a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py index 8adc528..9a33c6a 100644 --- a/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py +++ b/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py
@@ -63,9 +63,29 @@ """ assert isinstance(cg_context, CodeGenContext) - name = (cg_context.member_like.code_generator_info.property_implemented_as - or cg_context.member_like.identifier - or cg_context.property_.identifier) + name = cg_context.member_like.code_generator_info.property_implemented_as + if name: + pass + elif cg_context.constructor: + if cg_context.is_named_constructor: + name = "CreateForJSConstructor" + else: + name = "Create" + else: + name = (cg_context.member_like.identifier + or cg_context.property_.identifier) + if name: + pass + elif cg_context.indexed_property_getter: + name = "AnonymousIndexedGetter" + elif cg_context.indexed_property_setter: + name = "AnonymousIndexedSetter" + elif cg_context.named_property_getter: + name = "AnonymousNamedGetter" + elif cg_context.named_property_setter: + name = "AnonymousNamedSetter" + elif cg_context.named_property_deleter: + name = "AnonymousNamedDeleter" if cg_context.attribute_get: # modules/webaudio/biquad_filter_node.idl has readonly attribute "Q" @@ -82,17 +102,6 @@ tokens.insert(0, "set") name = "".join(tokens) - if cg_context.indexed_property_getter and not name: - name = "AnonymousIndexedGetter" - if cg_context.indexed_property_setter and not name: - name = "AnonymousIndexedSetter" - if cg_context.named_property_getter and not name: - name = "AnonymousNamedGetter" - if cg_context.named_property_setter and not name: - name = "AnonymousNamedSetter" - if cg_context.named_property_deleter and not name: - name = "AnonymousNamedDeleter" - return name @@ -709,11 +718,6 @@ arguments.append("${exception_state}") func_name = backward_compatible_api_func(cg_context) - if cg_context.constructor: - if cg_context.is_named_constructor: - func_name = "CreateForJSConstructor" - else: - func_name = "Create" if "Reflect" in ext_attrs: # [Reflect] func_name = _make_reflect_accessor_func_name(cg_context)
diff --git a/third_party/blink/renderer/core/css/media_query_evaluator.cc b/third_party/blink/renderer/core/css/media_query_evaluator.cc index 3692ee3..497e8835 100644 --- a/third_party/blink/renderer/core/css/media_query_evaluator.cc +++ b/third_party/blink/renderer/core/css/media_query_evaluator.cc
@@ -62,10 +62,8 @@ using mojom::blink::HoverType; using mojom::blink::PointerType; -enum MediaFeaturePrefix { kMinPrefix, kMaxPrefix, kNoPrefix }; - using EvalFunc = bool (*)(const MediaQueryExpValue&, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues&); using FunctionMap = HashMap<StringImpl*, EvalFunc>; static FunctionMap* g_function_map; @@ -175,27 +173,37 @@ } template <typename T> -bool CompareValue(T a, T b, MediaFeaturePrefix op) { +bool CompareValue(T a, T b, MediaQueryOperator op) { switch (op) { - case kMinPrefix: + case MediaQueryOperator::kGe: return a >= b; - case kMaxPrefix: + case MediaQueryOperator::kLe: return a <= b; - case kNoPrefix: + case MediaQueryOperator::kEq: + case MediaQueryOperator::kNone: return a == b; + case MediaQueryOperator::kLt: + return a < b; + case MediaQueryOperator::kGt: + return a > b; } return false; } -bool CompareDoubleValue(double a, double b, MediaFeaturePrefix op) { +bool CompareDoubleValue(double a, double b, MediaQueryOperator op) { const double precision = LayoutUnit::Epsilon(); switch (op) { - case kMinPrefix: + case MediaQueryOperator::kGe: return a >= (b - precision); - case kMaxPrefix: + case MediaQueryOperator::kLe: return a <= (b + precision); - case kNoPrefix: + case MediaQueryOperator::kEq: + case MediaQueryOperator::kNone: return std::abs(a - b) <= precision; + case MediaQueryOperator::kLt: + return a < b; + case MediaQueryOperator::kGt: + return a > b; } return false; } @@ -203,7 +211,7 @@ static bool CompareAspectRatioValue(const MediaQueryExpValue& value, int width, int height, - MediaFeaturePrefix op) { + MediaQueryOperator op) { if (value.IsRatio()) { return CompareValue(static_cast<double>(width) * value.Denominator(), static_cast<double>(height) * value.Numerator(), op); @@ -221,7 +229,7 @@ } static bool ColorMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { float number; int bits_per_component = media_values.ColorBitsPerComponent(); @@ -233,7 +241,7 @@ } static bool ColorIndexMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues&) { // FIXME: We currently assume that we do not support indexed displays, as it // is unknown how to retrieve the information if the display mode is indexed. @@ -249,7 +257,7 @@ } static bool MonochromeMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { float number; int bits_per_component = media_values.MonochromeBitsPerComponent(); @@ -261,7 +269,7 @@ } static bool DisplayModeMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { // isValid() is false if there is no parameter. Without parameter we should // return true to indicate that displayModeMediaFeature is enabled in the @@ -289,7 +297,7 @@ } static bool OrientationMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { int width = media_values.ViewportWidth(); int height = media_values.ViewportHeight(); @@ -305,7 +313,7 @@ } static bool AspectRatioMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { if (value.IsValid()) return CompareAspectRatioValue(value, media_values.ViewportWidth(), @@ -317,7 +325,7 @@ } static bool DeviceAspectRatioMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { if (value.IsValid()) return CompareAspectRatioValue(value, media_values.DeviceWidth(), @@ -329,7 +337,7 @@ } static bool DynamicRangeMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { if (!value.IsId()) return false; @@ -350,7 +358,7 @@ } static bool VideoDynamicRangeMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { // For now, Chrome makes no distinction between video-dynamic-range and // dynamic-range @@ -358,7 +366,7 @@ } static bool EvalResolution(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { // According to MQ4, only 'screen', 'print' and 'speech' may match. // FIXME: What should speech match? @@ -412,7 +420,7 @@ } static bool DevicePixelRatioMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { UseCounter::Count(media_values.GetDocument(), WebFeature::kPrefixedDevicePixelRatioMediaFeature); @@ -423,14 +431,14 @@ } static bool ResolutionMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { return (!value.IsValid() || CSSPrimitiveValue::IsResolution(value.Unit())) && EvalResolution(value, op, media_values); } static bool GridMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues&) { // if output device is bitmap, grid: 0 == true // assume we have bitmap device @@ -457,7 +465,7 @@ } static bool ComputeLengthAndCompare(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values, double compare_to_value) { double length; @@ -466,7 +474,7 @@ } static bool DeviceHeightMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { if (value.IsValid()) return ComputeLengthAndCompare(value, op, media_values, @@ -478,7 +486,7 @@ } static bool DeviceWidthMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { if (value.IsValid()) return ComputeLengthAndCompare(value, op, media_values, @@ -490,7 +498,7 @@ } static bool HeightMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { double height = media_values.ViewportHeight(); if (value.IsValid()) @@ -500,7 +508,7 @@ } static bool WidthMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { double width = media_values.ViewportWidth(); if (value.IsValid()) @@ -513,149 +521,165 @@ // media feature expression used. static bool MinColorMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return ColorMediaFeatureEval(value, kMinPrefix, media_values); + return ColorMediaFeatureEval(value, MediaQueryOperator::kGe, media_values); } static bool MaxColorMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return ColorMediaFeatureEval(value, kMaxPrefix, media_values); + return ColorMediaFeatureEval(value, MediaQueryOperator::kLe, media_values); } static bool MinColorIndexMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return ColorIndexMediaFeatureEval(value, kMinPrefix, media_values); + return ColorIndexMediaFeatureEval(value, MediaQueryOperator::kGe, + media_values); } static bool MaxColorIndexMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return ColorIndexMediaFeatureEval(value, kMaxPrefix, media_values); + return ColorIndexMediaFeatureEval(value, MediaQueryOperator::kLe, + media_values); } static bool MinMonochromeMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return MonochromeMediaFeatureEval(value, kMinPrefix, media_values); + return MonochromeMediaFeatureEval(value, MediaQueryOperator::kGe, + media_values); } static bool MaxMonochromeMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return MonochromeMediaFeatureEval(value, kMaxPrefix, media_values); + return MonochromeMediaFeatureEval(value, MediaQueryOperator::kLe, + media_values); } static bool MinAspectRatioMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return AspectRatioMediaFeatureEval(value, kMinPrefix, media_values); + return AspectRatioMediaFeatureEval(value, MediaQueryOperator::kGe, + media_values); } static bool MaxAspectRatioMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return AspectRatioMediaFeatureEval(value, kMaxPrefix, media_values); + return AspectRatioMediaFeatureEval(value, MediaQueryOperator::kLe, + media_values); } static bool MinDeviceAspectRatioMediaFeatureEval( const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return DeviceAspectRatioMediaFeatureEval(value, kMinPrefix, media_values); + return DeviceAspectRatioMediaFeatureEval(value, MediaQueryOperator::kGe, + media_values); } static bool MaxDeviceAspectRatioMediaFeatureEval( const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return DeviceAspectRatioMediaFeatureEval(value, kMaxPrefix, media_values); + return DeviceAspectRatioMediaFeatureEval(value, MediaQueryOperator::kLe, + media_values); } static bool MinDevicePixelRatioMediaFeatureEval( const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { UseCounter::Count(media_values.GetDocument(), WebFeature::kPrefixedMinDevicePixelRatioMediaFeature); - return DevicePixelRatioMediaFeatureEval(value, kMinPrefix, media_values); + return DevicePixelRatioMediaFeatureEval(value, MediaQueryOperator::kGe, + media_values); } static bool MaxDevicePixelRatioMediaFeatureEval( const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { UseCounter::Count(media_values.GetDocument(), WebFeature::kPrefixedMaxDevicePixelRatioMediaFeature); - return DevicePixelRatioMediaFeatureEval(value, kMaxPrefix, media_values); + return DevicePixelRatioMediaFeatureEval(value, MediaQueryOperator::kLe, + media_values); } static bool MinHeightMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return HeightMediaFeatureEval(value, kMinPrefix, media_values); + return HeightMediaFeatureEval(value, MediaQueryOperator::kGe, media_values); } static bool MaxHeightMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return HeightMediaFeatureEval(value, kMaxPrefix, media_values); + return HeightMediaFeatureEval(value, MediaQueryOperator::kLe, media_values); } static bool MinWidthMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return WidthMediaFeatureEval(value, kMinPrefix, media_values); + return WidthMediaFeatureEval(value, MediaQueryOperator::kGe, media_values); } static bool MaxWidthMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return WidthMediaFeatureEval(value, kMaxPrefix, media_values); + return WidthMediaFeatureEval(value, MediaQueryOperator::kLe, media_values); } static bool MinDeviceHeightMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return DeviceHeightMediaFeatureEval(value, kMinPrefix, media_values); + return DeviceHeightMediaFeatureEval(value, MediaQueryOperator::kGe, + media_values); } static bool MaxDeviceHeightMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return DeviceHeightMediaFeatureEval(value, kMaxPrefix, media_values); + return DeviceHeightMediaFeatureEval(value, MediaQueryOperator::kLe, + media_values); } static bool MinDeviceWidthMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return DeviceWidthMediaFeatureEval(value, kMinPrefix, media_values); + return DeviceWidthMediaFeatureEval(value, MediaQueryOperator::kGe, + media_values); } static bool MaxDeviceWidthMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return DeviceWidthMediaFeatureEval(value, kMaxPrefix, media_values); + return DeviceWidthMediaFeatureEval(value, MediaQueryOperator::kLe, + media_values); } static bool MinResolutionMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return ResolutionMediaFeatureEval(value, kMinPrefix, media_values); + return ResolutionMediaFeatureEval(value, MediaQueryOperator::kGe, + media_values); } static bool MaxResolutionMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { - return ResolutionMediaFeatureEval(value, kMaxPrefix, media_values); + return ResolutionMediaFeatureEval(value, MediaQueryOperator::kLe, + media_values); } static bool Transform3dMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { UseCounter::Count(media_values.GetDocument(), WebFeature::kPrefixedTransform3dMediaFeature); @@ -677,7 +701,7 @@ } static bool ImmersiveMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { bool return_value_if_no_parameter; int is_immersive_numeric_value; @@ -697,7 +721,7 @@ } static bool HoverMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { HoverType hover = media_values.PrimaryHoverType(); @@ -713,7 +737,7 @@ } static bool AnyHoverMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { int available_hover_types = media_values.AvailableHoverTypes(); @@ -736,7 +760,7 @@ } static bool OriginTrialTestMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { // The test feature only supports a 'no-value' parsing. So if we've gotten // to this point it will always match. @@ -745,7 +769,7 @@ } static bool PointerMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { PointerType pointer = media_values.PrimaryPointerType(); @@ -765,7 +789,7 @@ static bool PrefersReducedMotionMediaFeatureEval( const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { // If the value is not valid, this was passed without an argument. In that // case, it implicitly resolves to 'reduce'. @@ -781,7 +805,7 @@ static bool PrefersReducedDataMediaFeatureEval( const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { if (!value.IsValid()) return media_values.PrefersReducedData(); @@ -794,7 +818,7 @@ } static bool AnyPointerMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { int available_pointers = media_values.AvailablePointerTypes(); @@ -821,7 +845,7 @@ } static bool ScanMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { // Scan only applies to 'tv' media. if (!EqualIgnoringASCIICase(media_values.MediaType(), media_type_names::kTv)) @@ -840,7 +864,7 @@ } static bool ColorGamutMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { // isValid() is false if there is no parameter. Without parameter we should // return true to indicate that colorGamutMediaFeature is enabled in the @@ -883,7 +907,7 @@ static bool PrefersColorSchemeMediaFeatureEval( const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { UseCounter::Count(media_values.GetDocument(), WebFeature::kPrefersColorSchemeMediaFeature); @@ -903,7 +927,7 @@ } static bool PrefersContrastMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { UseCounter::Count(media_values.GetDocument(), WebFeature::kPrefersContrastMediaFeature); @@ -934,7 +958,7 @@ } static bool ForcedColorsMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { UseCounter::Count(media_values.GetDocument(), WebFeature::kForcedColorsMediaFeature); @@ -956,7 +980,7 @@ static bool NavigationControlsMediaFeatureEval( const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { NavigationControls navigation_controls = media_values.GetNavigationControls(); @@ -975,7 +999,7 @@ static bool HorizontalViewportSegmentsMediaFeatureEval( const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { int horizontal_viewport_segments = media_values.GetHorizontalViewportSegments(); @@ -990,7 +1014,7 @@ static bool VerticalViewportSegmentsMediaFeatureEval( const MediaQueryExpValue& value, - MediaFeaturePrefix op, + MediaQueryOperator op, const MediaValues& media_values) { int vertical_viewport_segments = media_values.GetVerticalViewportSegments(); if (!value.IsValid()) @@ -1002,7 +1026,7 @@ } static bool DevicePostureMediaFeatureEval(const MediaQueryExpValue& value, - MediaFeaturePrefix, + MediaQueryOperator, const MediaValues& media_values) { // isValid() is false if there is no parameter. Without parameter we should // return true to indicate that device posture is enabled in the @@ -1026,6 +1050,25 @@ } } +static MediaQueryOperator ReverseOperator(MediaQueryOperator op) { + switch (op) { + case MediaQueryOperator::kNone: + case MediaQueryOperator::kEq: + return op; + case MediaQueryOperator::kLt: + return MediaQueryOperator::kGt; + case MediaQueryOperator::kLe: + return MediaQueryOperator::kGe; + case MediaQueryOperator::kGt: + return MediaQueryOperator::kLt; + case MediaQueryOperator::kGe: + return MediaQueryOperator::kLe; + } + + NOTREACHED(); + return MediaQueryOperator::kNone; +} + void MediaQueryEvaluator::Init() { // Create the table. g_function_map = new FunctionMap; @@ -1050,10 +1093,26 @@ // Call the media feature evaluation function. Assume no prefix and let // trampoline functions override the prefix if prefix is used. EvalFunc func = g_function_map->at(expr.MediaFeature().Impl()); - if (func) - return func(expr.ExpValue(), kNoPrefix, *media_values_); - return false; + if (!func) + return false; + + const auto& bounds = expr.Bounds(); + + bool result = true; + + if (!bounds.IsRange() || bounds.right.IsValid()) { + DCHECK((bounds.right.op == MediaQueryOperator::kNone) || bounds.IsRange()); + result &= func(bounds.right.value, bounds.right.op, *media_values_); + } + + if (bounds.left.IsValid()) { + DCHECK(bounds.IsRange()); + auto op = ReverseOperator(bounds.left.op); + result &= func(bounds.left.value, op, *media_values_); + } + + return result; } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/media_query_evaluator_test.cc b/third_party/blink/renderer/core/css/media_query_evaluator_test.cc index dbc7bab9..79976d6 100644 --- a/third_party/blink/renderer/core/css/media_query_evaluator_test.cc +++ b/third_party/blink/renderer/core/css/media_query_evaluator_test.cc
@@ -22,6 +22,18 @@ namespace blink { +namespace { + +MediaQueryExpValue PxValue(double value) { + return MediaQueryExpValue(value, CSSPrimitiveValue::UnitType::kPixels); +} + +MediaQueryExpValue RatioValue(unsigned numerator, unsigned denominator) { + return MediaQueryExpValue(numerator, denominator); +} + +} // namespace + struct MediaQueryEvaluatorTestCase { const char* input; const bool output; @@ -709,4 +721,164 @@ } } +TEST(MediaQueryEvaluatorTest, RangedValues) { + MediaValuesCached::MediaValuesCachedData data; + data.viewport_width = 500; + data.viewport_height = 250; + + auto* media_values = MakeGarbageCollected<MediaValuesCached>(data); + MediaQueryEvaluator media_query_evaluator(*media_values); + + // (width < 600px) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(600), MediaQueryOperator::kLt))))); + + // (width < 501px) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(501), MediaQueryOperator::kLt))))); + + // (width < 500px) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(500), MediaQueryOperator::kLt))))); + + // (width > 500px) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(500), MediaQueryOperator::kGt))))); + + // (width < 501px) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(501), MediaQueryOperator::kLt))))); + + // (width <= 500px) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(500), MediaQueryOperator::kLe))))); + + // (400px < width) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(400), MediaQueryOperator::kLt), + MediaQueryExpComparison())))); + + // (600px < width) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(600), MediaQueryOperator::kLt), + MediaQueryExpComparison())))); + + // (400px > width) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(400), MediaQueryOperator::kGt), + MediaQueryExpComparison())))); + + // (600px > width) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(600), MediaQueryOperator::kGt), + MediaQueryExpComparison())))); + + // (400px <= width) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(400), MediaQueryOperator::kLe), + MediaQueryExpComparison())))); + + // (600px <= width) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(600), MediaQueryOperator::kLe), + MediaQueryExpComparison())))); + + // (400px >= width) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(400), MediaQueryOperator::kGe), + MediaQueryExpComparison())))); + + // (600px >= width) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(600), MediaQueryOperator::kGe), + MediaQueryExpComparison())))); + + // (width = 500px) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(500), MediaQueryOperator::kEq))))); + + // (width = 400px) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(400), MediaQueryOperator::kEq))))); + + // (500px = width) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(500), MediaQueryOperator::kEq), + MediaQueryExpComparison())))); + + // (400px = width) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", MediaQueryExpBounds(MediaQueryExpComparison( + PxValue(400), MediaQueryOperator::kEq), + MediaQueryExpComparison())))); + + // (400px < width < 600px) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", + MediaQueryExpBounds( + MediaQueryExpComparison(PxValue(400), MediaQueryOperator::kLt), + MediaQueryExpComparison(PxValue(600), MediaQueryOperator::kLt))))); + + // (550px < width < 600px) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", + MediaQueryExpBounds( + MediaQueryExpComparison(PxValue(550), MediaQueryOperator::kLt), + MediaQueryExpComparison(PxValue(600), MediaQueryOperator::kLt))))); + + // (400px < width < 450px) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "width", + MediaQueryExpBounds( + MediaQueryExpComparison(PxValue(400), MediaQueryOperator::kLt), + MediaQueryExpComparison(PxValue(450), MediaQueryOperator::kLt))))); + + // (aspect-ratio = 2/1) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "aspect-ratio", MediaQueryExpBounds(MediaQueryExpComparison( + RatioValue(2, 1), MediaQueryOperator::kEq))))); + + // (aspect-ratio = 3/1) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "aspect-ratio", MediaQueryExpBounds(MediaQueryExpComparison( + RatioValue(3, 1), MediaQueryOperator::kEq))))); + + // (aspect-ratio < 1/1) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "aspect-ratio", MediaQueryExpBounds(MediaQueryExpComparison( + RatioValue(1, 1), MediaQueryOperator::kLt))))); + + // (aspect-ratio < 3/1) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "aspect-ratio", MediaQueryExpBounds(MediaQueryExpComparison( + RatioValue(3, 1), MediaQueryOperator::kLt))))); + + // (aspect-ratio > 1/1) + EXPECT_TRUE(media_query_evaluator.Eval(MediaQueryExp::Create( + "aspect-ratio", MediaQueryExpBounds(MediaQueryExpComparison( + RatioValue(1, 1), MediaQueryOperator::kGt))))); + + // (aspect-ratio > 3/1) + EXPECT_FALSE(media_query_evaluator.Eval(MediaQueryExp::Create( + "aspect-ratio", MediaQueryExpBounds(MediaQueryExpComparison( + RatioValue(3, 1), MediaQueryOperator::kGt))))); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/media_query_exp.cc b/third_party/blink/renderer/core/css/media_query_exp.cc index 085ae071..5d5816a 100644 --- a/third_party/blink/renderer/core/css/media_query_exp.cc +++ b/third_party/blink/renderer/core/css/media_query_exp.cc
@@ -321,11 +321,16 @@ } MediaQueryExp::MediaQueryExp(const MediaQueryExp& other) - : media_feature_(other.MediaFeature()), exp_value_(other.ExpValue()) {} + : media_feature_(other.MediaFeature()), bounds_(other.bounds_) {} MediaQueryExp::MediaQueryExp(const String& media_feature, - const MediaQueryExpValue& exp_value) - : media_feature_(media_feature), exp_value_(exp_value) {} + const MediaQueryExpValue& value) + : MediaQueryExp(media_feature, + MediaQueryExpBounds(MediaQueryExpComparison(value))) {} + +MediaQueryExp::MediaQueryExp(const String& media_feature, + const MediaQueryExpBounds& bounds) + : media_feature_(media_feature), bounds_(bounds) {} MediaQueryExp MediaQueryExp::Create(const String& media_feature, CSSParserTokenRange& range, @@ -434,21 +439,71 @@ return Invalid(); } +namespace { + +const char* MediaQueryOperatorToString(MediaQueryOperator op) { + switch (op) { + case MediaQueryOperator::kNone: + return ""; + case MediaQueryOperator::kEq: + return "="; + case MediaQueryOperator::kLt: + return "<"; + case MediaQueryOperator::kLe: + return "<="; + case MediaQueryOperator::kGt: + return ">"; + case MediaQueryOperator::kGe: + return ">="; + } + + NOTREACHED(); + return ""; +} + +} // namespace + +MediaQueryExp MediaQueryExp::Create(const String& media_feature, + const MediaQueryExpBounds& bounds) { + return MediaQueryExp(media_feature, bounds); +} + MediaQueryExp::~MediaQueryExp() = default; bool MediaQueryExp::operator==(const MediaQueryExp& other) const { - return (other.media_feature_ == media_feature_) && - (exp_value_ == other.exp_value_); + return (other.media_feature_ == media_feature_) && (bounds_ == other.bounds_); } String MediaQueryExp::Serialize() const { + String name = media_feature_.LowerASCII(); + StringBuilder result; result.Append('('); - result.Append(media_feature_.LowerASCII()); - if (exp_value_.IsValid()) { - result.Append(": "); - result.Append(exp_value_.CssText()); + + // <mf-boolean> e.g. (color) + // <mf-plain> e.g. (width: 100px) + if (!bounds_.IsRange()) { + result.Append(name); + if (ExpValue().IsValid()) { + result.Append(": "); + result.Append(ExpValue().CssText()); + } + } else { + if (bounds_.left.IsValid()) { + result.Append(bounds_.left.value.CssText()); + result.Append(" "); + result.Append(MediaQueryOperatorToString(bounds_.left.op)); + result.Append(" "); + } + result.Append(name); + if (bounds_.right.IsValid()) { + result.Append(" "); + result.Append(MediaQueryOperatorToString(bounds_.right.op)); + result.Append(" "); + result.Append(bounds_.right.value.CssText()); + } } + result.Append(')'); return result.ToString(); @@ -480,4 +535,57 @@ return output.ToString(); } +String MediaQueryExpNode::Serialize() const { + StringBuilder builder; + SerializeTo(builder); + return builder.ToString(); +} + +void MediaQueryFeatureExpNode::SerializeTo(StringBuilder& builder) const { + builder.Append(exp_.Serialize()); +} + +std::unique_ptr<MediaQueryExpNode> MediaQueryFeatureExpNode::Copy() const { + return std::make_unique<MediaQueryFeatureExpNode>(exp_); +} + +void MediaQueryNestedExpNode::SerializeTo(StringBuilder& builder) const { + builder.Append("("); + child_->SerializeTo(builder); + builder.Append(")"); +} + +std::unique_ptr<MediaQueryExpNode> MediaQueryNestedExpNode::Copy() const { + return std::make_unique<MediaQueryNestedExpNode>(child_->Copy()); +} + +void MediaQueryNotExpNode::SerializeTo(StringBuilder& builder) const { + builder.Append("not "); + operand_->SerializeTo(builder); +} + +std::unique_ptr<MediaQueryExpNode> MediaQueryNotExpNode::Copy() const { + return std::make_unique<MediaQueryNestedExpNode>(operand_->Copy()); +} + +void MediaQueryAndExpNode::SerializeTo(StringBuilder& builder) const { + Left().SerializeTo(builder); + builder.Append(" and "); + Right().SerializeTo(builder); +} + +std::unique_ptr<MediaQueryExpNode> MediaQueryAndExpNode::Copy() const { + return std::make_unique<MediaQueryAndExpNode>(Left().Copy(), Right().Copy()); +} + +void MediaQueryOrExpNode::SerializeTo(StringBuilder& builder) const { + Left().SerializeTo(builder); + builder.Append(" or "); + Right().SerializeTo(builder); +} + +std::unique_ptr<MediaQueryExpNode> MediaQueryOrExpNode::Copy() const { + return std::make_unique<MediaQueryOrExpNode>(Left().Copy(), Right().Copy()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/media_query_exp.h b/third_party/blink/renderer/core/css/media_query_exp.h index 8302d07d..d943e20 100644 --- a/third_party/blink/renderer/core/css/media_query_exp.h +++ b/third_party/blink/renderer/core/css/media_query_exp.h
@@ -35,6 +35,7 @@ #include "third_party/blink/renderer/core/css/media_feature_names.h" #include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -124,6 +125,86 @@ }; }; +// https://drafts.csswg.org/mediaqueries-4/#mq-syntax +enum class MediaQueryOperator { + // Used for <mf-plain>, <mf-boolean> + kNone, + + // Used for <mf-range> + kEq, + kLt, + kLe, + kGt, + kGe, +}; + +// This represents the following part of a <media-feature> (example): +// +// (width >= 10px) +// ^^^^^^^ +// +struct CORE_EXPORT MediaQueryExpComparison { + DISALLOW_NEW(); + MediaQueryExpComparison() = default; + explicit MediaQueryExpComparison(const MediaQueryExpValue& value) + : value(value) {} + MediaQueryExpComparison(const MediaQueryExpValue& value, + MediaQueryOperator op) + : value(value), op(op) {} + + bool operator==(const MediaQueryExpComparison& o) const { + return value == o.value && op == o.op; + } + bool operator!=(const MediaQueryExpComparison& o) const { + return !(*this == o); + } + + bool IsValid() const { return value.IsValid(); } + + MediaQueryExpValue value; + MediaQueryOperator op = MediaQueryOperator::kNone; +}; + +// There exists three types of <media-feature>s. +// +// 1) Boolean features, which is just the feature name, e.g. (color) +// 2) Plain features, which can appear in two different forms: +// - Feature with specific value, e.g. (width: 100px) +// - Feature with min/max prefix, e.g. (min-width: 100px) +// 3) Range features, which can appear in three different forms: +// - Feature compared with value, e.g. (width >= 100px) +// - Feature compared with value (reversed), e.g. (100px <= width) +// - Feature within a certain range, e.g. (100px < width < 200px) +// +// In the first case, both |left| and |right| values are not set. +// In the second case, only |right| is set. +// In the third case, either |left| is set, |right| is set, or both, depending +// on the form. +// +// https://drafts.csswg.org/mediaqueries-4/#typedef-media-feature +struct CORE_EXPORT MediaQueryExpBounds { + DISALLOW_NEW(); + MediaQueryExpBounds() = default; + explicit MediaQueryExpBounds(const MediaQueryExpComparison& right) + : right(right) {} + MediaQueryExpBounds(const MediaQueryExpComparison& left, + const MediaQueryExpComparison& right) + : left(left), right(right) {} + + bool IsRange() const { + return left.op != MediaQueryOperator::kNone || + right.op != MediaQueryOperator::kNone; + } + + bool operator==(const MediaQueryExpBounds& o) const { + return left == o.left && right == o.right; + } + bool operator!=(const MediaQueryExpBounds& o) const { return !(*this == o); } + + MediaQueryExpComparison left; + MediaQueryExpComparison right; +}; + class CORE_EXPORT MediaQueryExp { DISALLOW_NEW(); @@ -133,6 +214,8 @@ CSSParserTokenRange&, const CSSParserContext&, const ExecutionContext*); + static MediaQueryExp Create(const String& media_feature, + const MediaQueryExpBounds&); static MediaQueryExp Invalid() { return MediaQueryExp(String(), MediaQueryExpValue()); } @@ -142,11 +225,20 @@ const String& MediaFeature() const { return media_feature_; } - MediaQueryExpValue ExpValue() const { return exp_value_; } + // TODO(crbug.com/1034465): Replace with MediaQueryExpBounds. + MediaQueryExpValue ExpValue() const { + DCHECK(!bounds_.left.IsValid()); + return bounds_.right.value; + } + + const MediaQueryExpBounds& Bounds() const { return bounds_; } bool IsValid() const { return !media_feature_.IsNull(); } bool operator==(const MediaQueryExp& other) const; + bool operator!=(const MediaQueryExp& other) const { + return !(*this == other); + } bool IsViewportDependent() const; @@ -160,9 +252,161 @@ private: MediaQueryExp(const String&, const MediaQueryExpValue&); + MediaQueryExp(const String&, const MediaQueryExpBounds&); String media_feature_; - MediaQueryExpValue exp_value_; + MediaQueryExpBounds bounds_; +}; + +// MediaQueryExpNode representing a tree of MediaQueryExp objects capable of +// nested/compound expressions. +class CORE_EXPORT MediaQueryExpNode { + USING_FAST_MALLOC(MediaQueryExpNode); + + public: + virtual ~MediaQueryExpNode() = default; + + enum class Type { kFeature, kNested, kNot, kAnd, kOr }; + + String Serialize() const; + + virtual Type GetType() const = 0; + virtual void SerializeTo(StringBuilder&) const = 0; + virtual std::unique_ptr<MediaQueryExpNode> Copy() const = 0; +}; + +class CORE_EXPORT MediaQueryFeatureExpNode : public MediaQueryExpNode { + USING_FAST_MALLOC(MediaQueryFeatureExpNode); + + public: + explicit MediaQueryFeatureExpNode(const MediaQueryExp& exp) : exp_(exp) {} + + MediaQueryExp Expression() const { return exp_; } + + Type GetType() const override { return Type::kFeature; } + void SerializeTo(StringBuilder&) const override; + std::unique_ptr<MediaQueryExpNode> Copy() const override; + + private: + MediaQueryExp exp_; +}; + +class CORE_EXPORT MediaQueryNestedExpNode : public MediaQueryExpNode { + USING_FAST_MALLOC(MediaQueryNestedExpNode); + + public: + explicit MediaQueryNestedExpNode(std::unique_ptr<MediaQueryExpNode> child) + : child_(std::move(child)) { + DCHECK(child_); + } + + const MediaQueryExpNode& Child() const { return *child_; } + + Type GetType() const override { return Type::kNested; } + void SerializeTo(StringBuilder&) const override; + std::unique_ptr<MediaQueryExpNode> Copy() const override; + + private: + std::unique_ptr<MediaQueryExpNode> child_; +}; + +class CORE_EXPORT MediaQueryNotExpNode : public MediaQueryExpNode { + USING_FAST_MALLOC(MediaQueryNotExpNode); + + public: + explicit MediaQueryNotExpNode(std::unique_ptr<MediaQueryExpNode> operand) + : operand_(std::move(operand)) { + DCHECK(operand_); + } + + const MediaQueryExpNode& Operand() const { return *operand_; } + + Type GetType() const override { return Type::kNot; } + void SerializeTo(StringBuilder&) const override; + std::unique_ptr<MediaQueryExpNode> Copy() const override; + + private: + std::unique_ptr<MediaQueryExpNode> operand_; +}; + +class CORE_EXPORT MediaQueryCompoundExpNode : public MediaQueryExpNode { + USING_FAST_MALLOC(MediaQueryCompoundExpNode); + + public: + MediaQueryCompoundExpNode(std::unique_ptr<MediaQueryExpNode> left, + std::unique_ptr<MediaQueryExpNode> right) + : left_(std::move(left)), right_(std::move(right)) { + DCHECK(left_); + DCHECK(right_); + } + + const MediaQueryExpNode& Left() const { return *left_; } + const MediaQueryExpNode& Right() const { return *right_; } + + private: + std::unique_ptr<MediaQueryExpNode> left_; + std::unique_ptr<MediaQueryExpNode> right_; +}; + +class CORE_EXPORT MediaQueryAndExpNode : public MediaQueryCompoundExpNode { + USING_FAST_MALLOC(MediaQueryAndExpNode); + + public: + MediaQueryAndExpNode(std::unique_ptr<MediaQueryExpNode> left, + std::unique_ptr<MediaQueryExpNode> right) + : MediaQueryCompoundExpNode(std::move(left), std::move(right)) {} + + Type GetType() const override { return Type::kAnd; } + void SerializeTo(StringBuilder&) const override; + std::unique_ptr<MediaQueryExpNode> Copy() const override; +}; + +class CORE_EXPORT MediaQueryOrExpNode : public MediaQueryCompoundExpNode { + USING_FAST_MALLOC(MediaQueryOrExpNode); + + public: + MediaQueryOrExpNode(std::unique_ptr<MediaQueryExpNode> left, + std::unique_ptr<MediaQueryExpNode> right) + : MediaQueryCompoundExpNode(std::move(left), std::move(right)) {} + + Type GetType() const override { return Type::kOr; } + void SerializeTo(StringBuilder&) const override; + std::unique_ptr<MediaQueryExpNode> Copy() const override; +}; + +template <> +struct DowncastTraits<MediaQueryFeatureExpNode> { + static bool AllowFrom(const MediaQueryExpNode& node) { + return node.GetType() == MediaQueryExpNode::Type::kFeature; + } +}; + +template <> +struct DowncastTraits<MediaQueryNestedExpNode> { + static bool AllowFrom(const MediaQueryExpNode& node) { + return node.GetType() == MediaQueryExpNode::Type::kNested; + } +}; + +template <> +struct DowncastTraits<MediaQueryNotExpNode> { + static bool AllowFrom(const MediaQueryExpNode& node) { + return node.GetType() == MediaQueryExpNode::Type::kNot; + } +}; + +template <> +struct DowncastTraits<MediaQueryAndExpNode> { + static bool AllowFrom(const MediaQueryExpNode& node) { + return node.GetType() == MediaQueryExpNode::Type::kAnd; + } +}; + +template <> +struct DowncastTraits<MediaQueryOrExpNode> { + static bool AllowFrom(const MediaQueryExpNode& node) { + return node.GetType() == MediaQueryExpNode::Type::kOr; + } }; } // namespace blink
diff --git a/third_party/blink/renderer/core/css/media_query_exp_test.cc b/third_party/blink/renderer/core/css/media_query_exp_test.cc index 69de52f..f5b3d3e 100644 --- a/third_party/blink/renderer/core/css/media_query_exp_test.cc +++ b/third_party/blink/renderer/core/css/media_query_exp_test.cc
@@ -30,6 +30,74 @@ return MediaQueryExpValue(); } +MediaQueryExpComparison NoCmp(MediaQueryExpValue v) { + return MediaQueryExpComparison(v); +} + +MediaQueryExpComparison LtCmp(MediaQueryExpValue v) { + return MediaQueryExpComparison(v, MediaQueryOperator::kLt); +} + +MediaQueryExpComparison LeCmp(MediaQueryExpValue v) { + return MediaQueryExpComparison(v, MediaQueryOperator::kLe); +} + +MediaQueryExpComparison GtCmp(MediaQueryExpValue v) { + return MediaQueryExpComparison(v, MediaQueryOperator::kGt); +} + +MediaQueryExpComparison GeCmp(MediaQueryExpValue v) { + return MediaQueryExpComparison(v, MediaQueryOperator::kGe); +} + +MediaQueryExpComparison EqCmp(MediaQueryExpValue v) { + return MediaQueryExpComparison(v, MediaQueryOperator::kEq); +} + +MediaQueryExp LeftExp(String feature, MediaQueryExpComparison cmp) { + return MediaQueryExp::Create(feature, + MediaQueryExpBounds(cmp, NoCmp(InvalidValue()))); +} + +MediaQueryExp RightExp(String feature, MediaQueryExpComparison cmp) { + return MediaQueryExp::Create(feature, + MediaQueryExpBounds(NoCmp(InvalidValue()), cmp)); +} + +MediaQueryExp PairExp(String feature, + MediaQueryExpComparison left, + MediaQueryExpComparison right) { + return MediaQueryExp::Create(feature, MediaQueryExpBounds(left, right)); +} + +std::unique_ptr<MediaQueryExpNode> FeatureNode(MediaQueryExp expr) { + return std::make_unique<MediaQueryFeatureExpNode>(expr); +} + +std::unique_ptr<MediaQueryExpNode> NestedNode( + std::unique_ptr<MediaQueryExpNode> child) { + return std::make_unique<MediaQueryNestedExpNode>(std::move(child)); +} + +std::unique_ptr<MediaQueryExpNode> NotNode( + std::unique_ptr<MediaQueryExpNode> operand) { + return std::make_unique<MediaQueryNotExpNode>(std::move(operand)); +} + +std::unique_ptr<MediaQueryExpNode> AndNode( + std::unique_ptr<MediaQueryExpNode> left, + std::unique_ptr<MediaQueryExpNode> right) { + return std::make_unique<MediaQueryAndExpNode>(std::move(left), + std::move(right)); +} + +std::unique_ptr<MediaQueryExpNode> OrNode( + std::unique_ptr<MediaQueryExpNode> left, + std::unique_ptr<MediaQueryExpNode> right) { + return std::make_unique<MediaQueryOrExpNode>(std::move(left), + std::move(right)); +} + } // namespace TEST(MediaQueryExpTest, ValuesType) { @@ -64,4 +132,114 @@ EXPECT_NE(RatioValue(0, 1), InvalidValue()); } +TEST(MediaQueryExpTest, ComparisonEquality) { + auto px1 = PxValue(10.0); + auto px2 = PxValue(20.0); + + EXPECT_EQ(LtCmp(px1), LtCmp(px1)); + + EXPECT_NE(LtCmp(px1), LeCmp(px1)); + EXPECT_NE(LtCmp(px1), LtCmp(px2)); +} + +TEST(MediaQueryExpTest, BoundaryEquality) { + auto px1 = PxValue(10.0); + auto px2 = PxValue(20.0); + + EXPECT_EQ(MediaQueryExpBounds(LtCmp(px1), LeCmp(px1)), + MediaQueryExpBounds(LtCmp(px1), LeCmp(px1))); + + EXPECT_NE(MediaQueryExpBounds(LtCmp(px1), LeCmp(px1)), + MediaQueryExpBounds(GtCmp(px1), LeCmp(px1))); + EXPECT_NE(MediaQueryExpBounds(LtCmp(px1), LeCmp(px1)), + MediaQueryExpBounds(LtCmp(px1), GeCmp(px1))); + EXPECT_NE(MediaQueryExpBounds(LtCmp(px1), LeCmp(px2)), + MediaQueryExpBounds(LtCmp(px1), LeCmp(px1))); +} + +TEST(MediaQueryExpTest, ExpEquality) { + auto px1 = PxValue(10.0); + auto px2 = PxValue(20.0); + + EXPECT_EQ(LeftExp("width", LtCmp(px1)), LeftExp("width", LtCmp(px1))); + + EXPECT_NE(LeftExp("width", LtCmp(px1)), LeftExp("height", LtCmp(px1))); + EXPECT_NE(LeftExp("width", LtCmp(px2)), LeftExp("width", LtCmp(px1))); + EXPECT_NE(LeftExp("width", LtCmp(px1)), RightExp("width", LtCmp(px1))); + EXPECT_NE(LeftExp("width", LtCmp(px1)), LeftExp("width", GtCmp(px1))); +} + +TEST(MediaQueryExpTest, Serialize) { + // Boolean feature: + EXPECT_EQ("(color)", RightExp("color", NoCmp(InvalidValue())).Serialize()); + + auto px = PxValue(10.0); + + // Plain feature: + EXPECT_EQ("(width: 10px)", RightExp("width", NoCmp(px)).Serialize()); + + // Ranges: + EXPECT_EQ("(width = 10px)", RightExp("width", EqCmp(px)).Serialize()); + EXPECT_EQ("(width < 10px)", RightExp("width", LtCmp(px)).Serialize()); + EXPECT_EQ("(width <= 10px)", RightExp("width", LeCmp(px)).Serialize()); + EXPECT_EQ("(width > 10px)", RightExp("width", GtCmp(px)).Serialize()); + EXPECT_EQ("(width >= 10px)", RightExp("width", GeCmp(px)).Serialize()); + + EXPECT_EQ("(10px = width)", LeftExp("width", EqCmp(px)).Serialize()); + EXPECT_EQ("(10px < width)", LeftExp("width", LtCmp(px)).Serialize()); + EXPECT_EQ("(10px <= width)", LeftExp("width", LeCmp(px)).Serialize()); + EXPECT_EQ("(10px > width)", LeftExp("width", GtCmp(px)).Serialize()); + EXPECT_EQ("(10px >= width)", LeftExp("width", GeCmp(px)).Serialize()); + + EXPECT_EQ( + "(10px < width < 20px)", + PairExp("width", LtCmp(PxValue(10.0)), LtCmp(PxValue(20.0))).Serialize()); + EXPECT_EQ( + "(20px > width > 10px)", + PairExp("width", GtCmp(PxValue(20.0)), GtCmp(PxValue(10.0))).Serialize()); + EXPECT_EQ( + "(10px <= width <= 20px)", + PairExp("width", LeCmp(PxValue(10.0)), LeCmp(PxValue(20.0))).Serialize()); + EXPECT_EQ( + "(20px > width >= 10px)", + PairExp("width", GtCmp(PxValue(20.0)), GeCmp(PxValue(10.0))).Serialize()); +} + +TEST(MediaQueryExpTest, SerializeNode) { + EXPECT_EQ("(width < 10px)", + FeatureNode(RightExp("width", LtCmp(PxValue(10))))->Serialize()); + + EXPECT_EQ( + "(width < 10px) and (11px >= thing) and (height = 12px)", + AndNode(FeatureNode(RightExp("width", LtCmp(PxValue(10)))), + AndNode(FeatureNode(LeftExp("thing", GeCmp(PxValue(11)))), + FeatureNode(RightExp("height", EqCmp(PxValue(12)))))) + ->Serialize()); + + // Same as previous, but with 'or' instead: + EXPECT_EQ("(width < 10px) or (11px >= thing) or (height = 12px)", + OrNode(FeatureNode(RightExp("width", LtCmp(PxValue(10)))), + OrNode(FeatureNode(LeftExp("thing", GeCmp(PxValue(11)))), + FeatureNode(RightExp("height", EqCmp(PxValue(12)))))) + ->Serialize()); + + EXPECT_EQ( + "not (width < 10px)", + NotNode(FeatureNode(RightExp("width", LtCmp(PxValue(10)))))->Serialize()); + + EXPECT_EQ("((width < 10px))", + NestedNode(FeatureNode(RightExp("width", LtCmp(PxValue(10))))) + ->Serialize()); + EXPECT_EQ( + "(((width < 10px)))", + NestedNode(NestedNode(FeatureNode(RightExp("width", LtCmp(PxValue(10)))))) + ->Serialize()); + + EXPECT_EQ("not ((11px >= thing) and (height = 12px))", + NotNode(NestedNode(AndNode( + FeatureNode(LeftExp("thing", GeCmp(PxValue(11)))), + FeatureNode(RightExp("height", EqCmp(PxValue(12))))))) + ->Serialize()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/events/mouse_event.cc b/third_party/blink/renderer/core/events/mouse_event.cc index f2ba3b0b..041d6d1 100644 --- a/third_party/blink/renderer/core/events/mouse_event.cc +++ b/third_party/blink/renderer/core/events/mouse_event.cc
@@ -153,7 +153,6 @@ buttons_(initializer->buttons()), related_target_(initializer->relatedTarget()), synthetic_event_type_(synthetic_event_type), - region_(initializer->region()), menu_source_type_(menu_source_type) { InitCoordinates(initializer->clientX(), initializer->clientY()); modifiers_ |= ButtonsToWebInputEventModifiers(buttons_);
diff --git a/third_party/blink/renderer/core/events/mouse_event.h b/third_party/blink/renderer/core/events/mouse_event.h index 3108b5d..d4e5711 100644 --- a/third_party/blink/renderer/core/events/mouse_event.h +++ b/third_party/blink/renderer/core/events/mouse_event.h
@@ -111,8 +111,6 @@ SyntheticEventType GetSyntheticEventType() const { return synthetic_event_type_; } - const String& region() const { return region_; } - virtual Node* toElement() const; virtual Node* fromElement() const; @@ -217,7 +215,6 @@ uint16_t buttons_; Member<EventTarget> related_target_; SyntheticEventType synthetic_event_type_; - String region_; // Only used for contextmenu events. WebMenuSourceType menu_source_type_;
diff --git a/third_party/blink/renderer/core/events/mouse_event.idl b/third_party/blink/renderer/core/events/mouse_event.idl index 8ba6df5..ebd955771 100644 --- a/third_party/blink/renderer/core/events/mouse_event.idl +++ b/third_party/blink/renderer/core/events/mouse_event.idl
@@ -65,10 +65,6 @@ [MeasureAs=MouseEventMovementX] readonly attribute long movementX; [MeasureAs=MouseEventMovementY] readonly attribute long movementY; - // Canvas Hit Regions - // https://html.spec.whatwg.org/C/#MouseEvent-partial - [RuntimeEnabled=CanvasHitRegion] readonly attribute DOMString? region; - // Non-standard [MeasureAs=MouseEventFromElement] readonly attribute Node fromElement; [MeasureAs=MouseEventToElement] readonly attribute Node toElement;
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc index a20effbe..b29c7dcb8 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -485,11 +485,19 @@ if (!directive.source_list) return true; - // We ignore URL-based allowlists if we're allowing dynamic script injection. + String suffix = String(); if (CheckSource(policy, directive.source_list, *csp.self_origin, url, - redirect_status) && - !CheckDynamic(directive.source_list, effective_type)) - return true; + redirect_status)) { + // We ignore URL-based allowlists if we're allowing dynamic script + // injection. + if (!CheckDynamic(directive.source_list, effective_type)) { + return true; + } else { + suffix = + " Note that 'strict-dynamic' is present, so host-based allowlisting " + "is disabled."; + } + } // We should never have a violation against `child-src` or `default-src` // directly; the effective directive should always be one of the explicit @@ -527,12 +535,6 @@ else if (CSPDirectiveName::NavigateTo == effective_type) prefix = prefix + "navigate to '"; - String suffix = String(); - if (CheckDynamic(directive.source_list, effective_type)) { - suffix = - " 'strict-dynamic' is present, so host-based allowlisting is disabled."; - } - String directive_name = ContentSecurityPolicy::GetDirectiveName(directive.type); String effective_directive_name =
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc index d0c3180..1fa55ef 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
@@ -7,15 +7,21 @@ #include <list> #include <string> +#include "base/memory/scoped_refptr.h" #include "base/test/scoped_feature_list.h" #include "services/network/public/cpp/features.h" #include "services/network/public/mojom/content_security_policy.mojom-blink.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" +#include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/inspector/inspector_audits_issue.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/loader/subresource_integrity.h" #include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/text/string_operators.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -27,6 +33,55 @@ class CSPDirectiveListTest : public testing::Test { public: + // Simple CSP delegate that stores the console messages logged by the + // ContentSecurityPolicy context and allows retrieving them. + class TestCSPDelegate final : public GarbageCollected<TestCSPDelegate>, + public ContentSecurityPolicyDelegate { + public: + Vector<String>& console_messages() { return console_messages_; } + + // ContentSecurityPolicyDelegate override + const SecurityOrigin* GetSecurityOrigin() override { + return security_origin_.get(); + } + const KURL& Url() const override { return url_; } + void SetSandboxFlags(network::mojom::blink::WebSandboxFlags) override {} + void SetRequireTrustedTypes() override {} + void AddInsecureRequestPolicy( + mojom::blink::InsecureRequestPolicy) override {} + std::unique_ptr<SourceLocation> GetSourceLocation() override { + return nullptr; + } + absl::optional<uint16_t> GetStatusCode() override { return absl::nullopt; } + String GetDocumentReferrer() override { return ""; } + void DispatchViolationEvent(const SecurityPolicyViolationEventInit&, + Element*) override {} + void PostViolationReport(const SecurityPolicyViolationEventInit&, + const String& stringified_report, + bool is_frame_ancestors_violation, + const Vector<String>& report_endpoints, + bool use_reporting_api) override {} + void Count(WebFeature) override {} + void AddConsoleMessage(ConsoleMessage* message) override { + console_messages_.push_back(message->Message()); + } + void AddInspectorIssue(AuditsIssue) override {} + void DisableEval(const String& error_message) override {} + void ReportBlockedScriptExecutionToInspector( + const String& directive_text) override {} + void DidAddContentSecurityPolicies( + WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>) override { + } + + void Trace(Visitor*) const override {} + + private: + const KURL url_ = KURL("https://example.test/index.html"); + const scoped_refptr<SecurityOrigin> security_origin_ = + SecurityOrigin::Create(url_); + Vector<String> console_messages_; + }; + CSPDirectiveListTest() : csp(MakeGarbageCollected<ContentSecurityPolicy>()) {} void SetUp() override { scoped_feature_list_.InitWithFeatures({network::features::kReporting}, {}); @@ -830,4 +885,88 @@ EXPECT_FALSE(directive_list->report_endpoints.IsEmpty()); } +MATCHER_P(HasSubstr, s, "") { + return arg.Contains(s); +} + +TEST_F(CSPDirectiveListTest, StrictDynamicIgnoresAllowlistWarning) { + KURL blocked_url = KURL("https://blocked.com"); + KURL other_blocked_url = KURL("https://other-blocked.com"); + network::mojom::blink::ContentSecurityPolicyPtr directive_list_with_blocked = + CreateList("script-src 'nonce-abc' https://blocked.com 'strict-dynamic'", + ContentSecurityPolicyType::kEnforce); + network::mojom::blink::ContentSecurityPolicyPtr + directive_list_without_blocked = + CreateList("script-src 'nonce-abc' 'strict-dynamic'", + ContentSecurityPolicyType::kEnforce); + + struct { + const char* name; + const network::mojom::blink::ContentSecurityPolicyPtr& directive_list; + const KURL& script_url; + const char* script_nonce; + bool allowed; + bool console_message; + } testCases[]{ + { + "Url in the allowlist ignored because of 'strict-dynamic'", + directive_list_with_blocked, + blocked_url, + "", + false, + true, + }, + { + "Url in the allowlist ignored because of 'strict-dynamic', but " + "script allowed by nonce", + directive_list_with_blocked, + blocked_url, + "abc", + true, + false, + }, + { + "No allowlistUrl", + directive_list_without_blocked, + blocked_url, + "", + false, + false, + }, + { + "Url in the allowlist ignored because of 'strict-dynamic', but " + "script has another url", + directive_list_with_blocked, + other_blocked_url, + "", + false, + false, + }, + }; + for (const auto& testCase : testCases) { + SCOPED_TRACE(testCase.name); + ContentSecurityPolicy* context = + MakeGarbageCollected<ContentSecurityPolicy>(); + TestCSPDelegate* test_delegate = MakeGarbageCollected<TestCSPDelegate>(); + context->BindToDelegate(*test_delegate); + EXPECT_EQ( + testCase.allowed, + CSPDirectiveListAllowFromSource( + *testCase.directive_list, context, CSPDirectiveName::ScriptSrcElem, + testCase.script_url, testCase.script_url, + ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kReport, testCase.script_nonce)); + static const char* message = + "Note that 'strict-dynamic' is present, so " + "host-based allowlisting is disabled."; + if (testCase.console_message) { + EXPECT_THAT(test_delegate->console_messages(), + testing::Contains(HasSubstr(message))); + } else { + EXPECT_THAT(test_delegate->console_messages(), + testing::Not(testing::Contains(HasSubstr(message)))); + } + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index 989951b..cde4f0c 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -585,25 +585,35 @@ } } -static void RunAddConsoleMessageTask(mojom::ConsoleMessageSource source, - mojom::ConsoleMessageLevel level, - const String& message, - LocalDOMWindow* window, - bool discard_duplicates) { - window->AddConsoleMessageImpl( - MakeGarbageCollected<ConsoleMessage>(source, level, message), - discard_duplicates); +static void RunAddConsoleMessageTask( + mojom::blink::ConsoleMessageSource source, + mojom::blink::ConsoleMessageLevel level, + const String& message, + LocalDOMWindow* window, + bool discard_duplicates, + std::unique_ptr<mojom::blink::ConsoleMessageCategory> category) { + auto* console_message = + MakeGarbageCollected<ConsoleMessage>(source, level, message); + if (category) + console_message->SetCategory(*category); + window->AddConsoleMessageImpl(console_message, discard_duplicates); } void LocalDOMWindow::AddConsoleMessageImpl(ConsoleMessage* console_message, bool discard_duplicates) { if (!IsContextThread()) { + std::unique_ptr<mojom::blink::ConsoleMessageCategory> category; + if (console_message->Category()) { + category = std::make_unique<mojom::blink::ConsoleMessageCategory>( + *console_message->Category()); + } PostCrossThreadTask( *GetTaskRunner(TaskType::kInternalInspector), FROM_HERE, - CrossThreadBindOnce( - &RunAddConsoleMessageTask, console_message->Source(), - console_message->Level(), console_message->Message(), - WrapCrossThreadPersistent(this), discard_duplicates)); + CrossThreadBindOnce(&RunAddConsoleMessageTask, + console_message->Source(), console_message->Level(), + console_message->Message(), + WrapCrossThreadPersistent(this), discard_duplicates, + std::move(category))); return; } @@ -621,12 +631,16 @@ line_number = parser->LineNumber().OneBasedInt(); } Vector<DOMNodeId> nodes(console_message->Nodes()); + absl::optional<mojom::blink::ConsoleMessageCategory> category = + console_message->Category(); console_message = MakeGarbageCollected<ConsoleMessage>( console_message->Source(), console_message->Level(), console_message->Message(), std::make_unique<SourceLocation>(Url().GetString(), line_number, 0, nullptr)); console_message->SetNodes(GetFrame(), std::move(nodes)); + if (category) + console_message->SetCategory(*category); } GetFrame()->Console().AddMessage(console_message, discard_duplicates);
diff --git a/third_party/blink/renderer/core/frame/local_dom_window_test.cc b/third_party/blink/renderer/core/frame/local_dom_window_test.cc index cc8fbdfc..95c8f40e 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window_test.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window_test.cc
@@ -34,10 +34,13 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/loader/referrer_utils.h" +#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink-forward.h" #include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h" #include "third_party/blink/renderer/core/execution_context/agent.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/inspector/console_message_storage.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -306,4 +309,21 @@ } } +TEST_F(LocalDOMWindowTest, ConsoleMessageCategory) { + auto unknown_location = SourceLocation::Capture(String(), 0, 0); + auto* console_message = MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kJavaScript, + mojom::blink::ConsoleMessageLevel::kError, "Kaboom!", + std::move(unknown_location)); + console_message->SetCategory(mojom::blink::ConsoleMessageCategory::Cors); + auto* window = GetFrame().DomWindow(); + window->AddConsoleMessageImpl(console_message, false); + auto* message_storage = &GetFrame().GetPage()->GetConsoleMessageStorage(); + EXPECT_EQ(1u, message_storage->size()); + for (WTF::wtf_size_t i = 0; i < message_storage->size(); ++i) { + EXPECT_EQ(mojom::blink::ConsoleMessageCategory::Cors, + *message_storage->at(i)->Category()); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/input/touch.cc b/third_party/blink/renderer/core/input/touch.cc index d590511..69519ff 100644 --- a/third_party/blink/renderer/core/input/touch.cc +++ b/third_party/blink/renderer/core/input/touch.cc
@@ -65,8 +65,7 @@ const FloatPoint& page_pos, const FloatSize& radius, float rotation_angle, - float force, - String region) + float force) : target_(target), identifier_(identifier), client_pos_(page_pos - ContentsOffset(frame)), @@ -75,7 +74,6 @@ radius_(radius), rotation_angle_(rotation_angle), force_(force), - region_(region), absolute_location_(PageToAbsolute(frame, page_pos)) {} Touch::Touch(EventTarget* target, @@ -86,7 +84,6 @@ const FloatSize& radius, float rotation_angle, float force, - String region, LayoutPoint absolute_location) : target_(target), identifier_(identifier), @@ -96,7 +93,6 @@ radius_(radius), rotation_angle_(rotation_angle), force_(force), - region_(region), absolute_location_(absolute_location) {} Touch::Touch(LocalFrame* frame, const TouchInit* initializer) @@ -108,13 +104,12 @@ radius_(FloatSize(initializer->radiusX(), initializer->radiusY())), rotation_angle_(initializer->rotationAngle()), force_(initializer->force()), - region_(initializer->region()), absolute_location_(PageToAbsolute(frame, page_pos_)) {} Touch* Touch::CloneWithNewTarget(EventTarget* event_target) const { return MakeGarbageCollected<Touch>( event_target, identifier_, client_pos_, screen_pos_, page_pos_, radius_, - rotation_angle_, force_, region_, absolute_location_); + rotation_angle_, force_, absolute_location_); } void Touch::Trace(Visitor* visitor) const {
diff --git a/third_party/blink/renderer/core/input/touch.h b/third_party/blink/renderer/core/input/touch.h index 2e768a8..31fe09f 100644 --- a/third_party/blink/renderer/core/input/touch.h +++ b/third_party/blink/renderer/core/input/touch.h
@@ -51,11 +51,9 @@ const FloatPoint& page_pos, const FloatSize& radius, float rotation_angle, - float force, - String region) { + float force) { return MakeGarbageCollected<Touch>(frame, target, identifier, screen_pos, - page_pos, radius, rotation_angle, force, - region); + page_pos, radius, rotation_angle, force); } static Touch* Create(const Document& document, const TouchInit* initializer) { @@ -69,8 +67,7 @@ const FloatPoint& page_pos, const FloatSize& radius, float rotation_angle, - float force, - String region); + float force); Touch(EventTarget*, int identifier, @@ -80,7 +77,6 @@ const FloatSize& radius, float rotation_angle, float force, - String region, LayoutPoint absolute_location); Touch(LocalFrame*, const TouchInit*); @@ -98,7 +94,6 @@ float radiusY() const { return radius_.Height(); } float rotationAngle() const { return rotation_angle_; } float force() const { return force_; } - const String& region() const { return region_; } // Blink-internal methods const LayoutPoint& AbsoluteLocation() const { return absolute_location_; } @@ -120,7 +115,6 @@ FloatSize radius_; float rotation_angle_; float force_; - String region_; // FIXME(rbyers): Shouldn't we be able to migrate callers to relying on // screenPos, pagePos or clientPos? absoluteLocation appears to be the same as // pagePos but without browser scale applied.
diff --git a/third_party/blink/renderer/core/input/touch.idl b/third_party/blink/renderer/core/input/touch.idl index 58f05bd..43a5564 100644 --- a/third_party/blink/renderer/core/input/touch.idl +++ b/third_party/blink/renderer/core/input/touch.idl
@@ -41,8 +41,4 @@ readonly attribute float radiusY; readonly attribute float rotationAngle; [HighEntropy=Direct, Measure] readonly attribute float force; - - // Canvas Hit Regions - // https://html.spec.whatwg.org/C/#Touch-partial - [RuntimeEnabled=CanvasHitRegion] readonly attribute DOMString? region; };
diff --git a/third_party/blink/renderer/core/input/touch_event_manager.cc b/third_party/blink/renderer/core/input/touch_event_manager.cc index 0e9575d..c89165c 100644 --- a/third_party/blink/renderer/core/input/touch_event_manager.cc +++ b/third_party/blink/renderer/core/input/touch_event_manager.cc
@@ -172,7 +172,6 @@ const TouchEventManager::TouchPointAttributes* point_attr, bool* known_target) { Node* touch_node = point_attr->target_; - String region_id = point_attr->region_; *known_target = false; LocalFrame* target_frame = nullptr; @@ -221,7 +220,7 @@ target_frame, touch_node, point_attr->event_.id, FloatPoint(transformed_event.PositionInScreen()), document_point, adjusted_radius, transformed_event.rotation_angle, - transformed_event.force, region_id); + transformed_event.force); } WebCoalescedInputEvent TouchEventManager::GenerateWebCoalescedInputEvent() { @@ -520,7 +519,6 @@ MakeGarbageCollected<TouchPointAttributes>(event)); Node* touch_node = pointer_event_target.target_element; - String region = pointer_event_target.region; HitTestRequest::HitTestRequestType hit_type = HitTestRequest::kTouchEvent | HitTestRequest::kReadOnly | @@ -564,7 +562,6 @@ TouchPointAttributes* attributes = touch_attribute_map_.at(event.id); attributes->target_ = touch_node; - attributes->region_ = region; TouchAction effective_touch_action = touch_action_util::ComputeEffectiveTouchAction(*touch_node);
diff --git a/third_party/blink/renderer/core/input/touch_event_manager.h b/third_party/blink/renderer/core/input/touch_event_manager.h index 5fd1213..6c20fd77 100644 --- a/third_party/blink/renderer/core/input/touch_event_manager.h +++ b/third_party/blink/renderer/core/input/touch_event_manager.h
@@ -68,7 +68,6 @@ // unless more new events arrives for this touch point. Vector<WebPointerEvent> coalesced_events_; Member<Node> target_; // The target of each active touch point. - String region_; // // The region of each active touch point. bool stale_; };
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc index 2a8ace6..4940609 100644 --- a/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc +++ b/third_party/blink/renderer/modules/media_controls/media_controls_display_cutout_delegate_test.cc
@@ -155,7 +155,7 @@ Touch* CreateTouchAtPoint(int x, int y) { return Touch::Create(GetDocument().GetFrame(), &GetVideoElement(), 1 /* identifier */, FloatPoint(x, y), FloatPoint(x, y), - FloatSize(1, 1), 90, 0, "test"); + FloatSize(1, 1), 90, 0); } mojom::ViewportFit CurrentViewportFit() const {
diff --git a/third_party/blink/renderer/modules/mediastream/OWNERS b/third_party/blink/renderer/modules/mediastream/OWNERS index 7a52048..ac33cb15 100644 --- a/third_party/blink/renderer/modules/mediastream/OWNERS +++ b/third_party/blink/renderer/modules/mediastream/OWNERS
@@ -1,3 +1,4 @@ +eladalon@chromium.org guidou@chromium.org hbos@chromium.org tommi@chromium.org
diff --git a/third_party/blink/renderer/platform/bindings/multi_worlds_v8_reference.cc b/third_party/blink/renderer/platform/bindings/multi_worlds_v8_reference.cc index 0d86cf85..0358b94 100644 --- a/third_party/blink/renderer/platform/bindings/multi_worlds_v8_reference.cc +++ b/third_party/blink/renderer/platform/bindings/multi_worlds_v8_reference.cc
@@ -10,14 +10,35 @@ namespace blink { MultiWorldsV8Reference::MultiWorldsV8Reference(v8::Isolate* isolate, - v8::Local<v8::Object> object) - : object_(isolate, object), - script_state_(ScriptState::From(object->CreationContext())) {} + v8::Local<v8::Value> value) + : value_(isolate, value) { + if (value->IsObject()) { + script_state_ = + ScriptState::From(value.As<v8::Object>()->CreationContext()); + } else { + script_state_ = nullptr; + } +} + +v8::Local<v8::Value> MultiWorldsV8Reference::GetValue( + ScriptState* script_state) { + v8::Local<v8::Value> value = value_.NewLocal(script_state->GetIsolate()); + if (value->IsObject()) { + return GetObject(script_state); + } else { + return value; + } +} + +void MultiWorldsV8Reference::Trace(Visitor* visitor) const { + visitor->Trace(value_); + visitor->Trace(script_state_); +} v8::Local<v8::Object> MultiWorldsV8Reference::GetObject( ScriptState* script_state) { if (&script_state->World() == &script_state_->World()) { - return object_.NewLocal(script_state_->GetIsolate()); + return value_.NewLocal(script_state->GetIsolate()).As<v8::Object>(); } V8ObjectDataStore& map = script_state->World().GetV8ObjectDataStore(); @@ -35,9 +56,4 @@ return copy_object; } -void MultiWorldsV8Reference::Trace(Visitor* visitor) const { - visitor->Trace(object_); - visitor->Trace(script_state_); -} - } // namespace blink
diff --git a/third_party/blink/renderer/platform/bindings/multi_worlds_v8_reference.h b/third_party/blink/renderer/platform/bindings/multi_worlds_v8_reference.h index 8b6ed86..1fb0611 100644 --- a/third_party/blink/renderer/platform/bindings/multi_worlds_v8_reference.h +++ b/third_party/blink/renderer/platform/bindings/multi_worlds_v8_reference.h
@@ -13,14 +13,16 @@ class MultiWorldsV8Reference : public GarbageCollected<MultiWorldsV8Reference> { public: - MultiWorldsV8Reference(v8::Isolate* isolate, v8::Local<v8::Object> object); + MultiWorldsV8Reference(v8::Isolate* isolate, v8::Local<v8::Value> value); - v8::Local<v8::Object> GetObject(ScriptState* script_state); + v8::Local<v8::Value> GetValue(ScriptState* script_state); virtual void Trace(Visitor*) const; private: - TraceWrapperV8Reference<v8::Object> object_; + v8::Local<v8::Object> GetObject(ScriptState* script_state); + + TraceWrapperV8Reference<v8::Value> value_; Member<ScriptState> script_state_; };
diff --git a/third_party/blink/renderer/platform/bindings/v8_interface_bridge_base.h b/third_party/blink/renderer/platform/bindings/v8_interface_bridge_base.h index d407d0d1..0ed96b5 100644 --- a/third_party/blink/renderer/platform/bindings/v8_interface_bridge_base.h +++ b/third_party/blink/renderer/platform/bindings/v8_interface_bridge_base.h
@@ -7,7 +7,7 @@ #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "v8/include/v8.h" +#include "v8/include/v8-forward.h" namespace blink {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 8b1fbc4a..c73cfd69 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -350,10 +350,6 @@ status: "experimental", }, { - name: "CanvasHitRegion", - status: "experimental", - }, - { name: "CanvasImageSmoothing", status: "experimental", },
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index ebba1e7..3a35ef16 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2696,8 +2696,10 @@ crbug.com/27659 external/wpt/css/css-ruby/empty-ruby-base-container.html [ Failure ] crbug.com/27659 external/wpt/css/css-ruby/empty-ruby-text-container-float.html [ Failure ] crbug.com/27659 external/wpt/css/css-ruby/improperly-contained-annotation-001.html [ Failure ] +crbug.com/27659 external/wpt/css/css-ruby/rb-display-001.html [ Failure ] crbug.com/27659 external/wpt/css/css-ruby/root-block-ruby.xhtml [ Failure ] crbug.com/27659 external/wpt/css/css-ruby/root-ruby.xhtml [ Failure ] +crbug.com/27659 external/wpt/css/css-ruby/rt-display-001.html [ Failure ] crbug.com/27659 external/wpt/css/css-ruby/ruby-align-001.html [ Failure ] crbug.com/27659 external/wpt/css/css-ruby/ruby-align-001a.html [ Failure ] crbug.com/27659 external/wpt/css/css-ruby/ruby-align-002.html [ Failure ] @@ -2851,14 +2853,12 @@ crbug.com/626703 [ Linux ] external/wpt/input-events/input-events-get-target-ranges.html [ Failure Timeout ] crbug.com/626703 [ Linux ] external/wpt/input-events/input-events-get-target-ranges-non-collapsed-selection.tentative.html?TypingA [ Skip Timeout ] crbug.com/626703 [ Linux ] external/wpt/input-events/input-events-typing.html [ Failure Timeout ] -crbug.com/626703 external/wpt/css/css-ruby/rb-display-001.html [ Failure ] crbug.com/626703 external/wpt/css/css-pseudo/cascade-highlight-005.html [ Failure ] crbug.com/626703 [ Linux ] external/wpt/css/css-pseudo/selection-originating-decoration-color.html [ Failure ] crbug.com/626703 [ Linux ] external/wpt/css/css-pseudo/selection-background-painting-order.html [ Failure ] crbug.com/626703 [ Linux ] external/wpt/infrastructure/testdriver/actions/eventOrder.html [ Timeout ] crbug.com/626703 [ Linux ] external/wpt/input-events/input-events-cut-paste.html [ Failure Timeout ] crbug.com/626703 external/wpt/css/CSS2/tables/table-anonymous-objects-211.xht [ Failure ] -crbug.com/626703 external/wpt/css/css-ruby/rt-display-001.html [ Failure ] crbug.com/626703 [ Mac10.14 ] external/wpt/pointerevents/pointerevent_contextmenu_is_a_pointerevent.html?touch [ Timeout ] crbug.com/626703 [ Mac10.15 ] external/wpt/pointerevents/pointerevent_contextmenu_is_a_pointerevent.html?touch [ Timeout ] crbug.com/626703 [ Mac11.0 ] external/wpt/pointerevents/pointerevent_contextmenu_is_a_pointerevent.html?touch [ Timeout ] @@ -4912,8 +4912,6 @@ crbug.com/535738 external/wpt/media-source/mediasource-changetype-play-negative.html [ Failure ] crbug.com/535738 external/wpt/media-source/mediasource-changetype-play-without-codecs-parameter.html [ Failure ] -crbug.com/974675 http/tests/devtools/sources/debugger-frameworks/frameworks-jquery.js [ Crash Pass ] - # Sheriff 2019-06-26 crbug.com/978966 [ Mac ] paint/markers/ellipsis-mixed-text-in-ltr-flow-with-markers.html [ Failure Pass ] @@ -6422,9 +6420,6 @@ crbug.com/1210658 [ Mac10.15 ] virtual/jxl-enabled/images/jxl/jxl-images.html [ Failure ] crbug.com/1210658 [ Win ] virtual/jxl-enabled/images/jxl/jxl-images.html [ Failure ] -# Temporarily disabled to unblock https://crrev.com/c/3099011 -crbug.com/1199701 http/tests/devtools/console/console-big-array.js [ Skip ] - # Sheriff 2021-5-19 # Flaky on Webkit Linux Leak crbug.com/1210731 [ Linux ] http/tests/devtools/sources/debugger-step/debugger-step-out-document-write.js [ Failure Pass ]
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-big-array-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-big-array-expected.txt index 2ee9b8c..02b97e3 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-big-array-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-big-array-expected.txt
@@ -48,6 +48,7 @@ 41: 41 100: 100 length: 101 + [[Prototype]]: Array(0) console-big-array.js:23 Array(10) 0: undefined 1: undefined @@ -74,6 +75,7 @@ 9: 9 100: 100 length: 101 + [[Prototype]]: Array(0) console-big-array.js:34 Array(405) [0 … 399] [0 … 19] @@ -103,6 +105,7 @@ 403: 403 404: 404 length: 405 + [[Prototype]]: Array(0) console-big-array.js:47 Array(124) 0: 0 1: 1 @@ -123,6 +126,7 @@ -123: -123 NaN: NaN length: 124 + [[Prototype]]: Array(0) console-big-array.js:57 Array(4294967295) [0 … 19] 0: 0 @@ -179,6 +183,7 @@ 4294967296: 4294967296 8589934592: 8589934592 length: 4294967295 + [[Prototype]]: Array(0) console-big-array.js:60 Uint8Array(64160003) [0 … 63999999] [0 … 3199999] @@ -204,4 +209,16 @@ [64000000 … 64160002] [64000000 … 64159999] [64160000 … 64160002] + buffer: ArrayBuffer(64160003) + byteLength: 64160003 + [[Prototype]]: ArrayBuffer + [[Int8Array]]: Int8Array(64160003) + [[Uint8Array]]: Uint8Array(64160003) + [[ArrayBufferByteLength]]: 64160003 + [[ArrayBufferData]]: 1 + byteLength: 64160003 + byteOffset: 0 + length: 64160003 + Symbol(Symbol.toStringTag): (...) + [[Prototype]]: TypedArray
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index 343a4d93..7b176c77 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -5592,7 +5592,6 @@ getter offsetY getter pageX getter pageY - getter region getter relatedTarget getter screenX getter screenY @@ -8723,7 +8722,6 @@ getter pageY getter radiusX getter radiusY - getter region getter rotationAngle getter screenX getter screenY
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index e2e7697..2cb5de00 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-11-0-87-g619036096 -Revision: 61903609674f2a4ad18abbbcb1d40f5c8beeeaf4 +Version: VER-2-11-0-90-gb4dddd824 +Revision: b4dddd8244fb59795f030530ad2b401ec4d5b477 CPEPrefix: cpe:/a:freetype:freetype:2.10.4 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses"
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 74f80201..7161fe2 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -30232,6 +30232,16 @@ <int value="4" label="Regular User"/> </enum> +<enum name="FastPairEngagementFlowEvent"> + <int value="1" label="Discovery UI Shown"/> + <int value="11" label="Discovery UI Dismissed"/> + <int value="12" label="Discovery UI: Connect Button Pressed"/> + <int value="121" label="Pairing Failed"/> + <int value="122" label="Pairing Succeeded"/> + <int value="1211" label="Pairing Failed: Error UI Dismissed"/> + <int value="1212" label="Pairing Failed: Error UI Settings Button Pressed"/> +</enum> + <enum name="FaultTolerantHeap"> <int value="0" label="FTH_OFF">FTH is completely off.</int> <int value="1" label="FTH_HKLM">FTH is enabled in HKLM.</int> @@ -43982,7 +43992,7 @@ <int value="1" label="Open in New Incognito Tab"/> <int value="2" label="Open in New Window"/> <int value="3" label="Open all in New Tabs"/> - <int value="4" label="Copy"/> + <int value="4" label="Copy URL"/> <int value="5" label="Edit"/> <int value="6" label="Move"/> <int value="7" label="Share"/> @@ -43997,9 +44007,13 @@ <int value="16" label="Add to Bookmarks"/> <int value="17" label="Close Tab"/> <int value="18" label="Edit Bookmark"/> - <int value="19" label="Save"/> - <int value="20" label="Open in Current Tab"/> + <int value="19" label="Save Image"/> + <int value="20" label="Open Image in Current Tab"/> <int value="21" label="Search Image"/> + <int value="22" label="Close all Tabs"/> + <int value="23" label="Select Tabs"/> + <int value="24" label="Open Image in New Tab"/> + <int value="25" label="Copy Image"/> </enum> <enum name="IOSMenuScenario"> @@ -51045,6 +51059,7 @@ <int value="767543730" label="DoubleTapToZoomInTabletMode:enabled"/> <int value="767549069" label="ScreenTime:enabled"/> <int value="767970385" label="ResamplingScrollEvents:enabled"/> + <int value="768855962" label="PaymentRequestBasicCard:enabled"/> <int value="770680432" label="DecodeLossyWebPImagesToYUV:enabled"/> <int value="772272625" label="simplify-https-indicator"/> <int value="772348426" label="AffiliationBasedMatching:enabled"/> @@ -51873,6 +51888,7 @@ label="DesktopPWAsFlashAppNameInsteadOfOrigin:enabled"/> <int value="1420007919" label="SyncTrustedVaultPassphrasePromo:disabled"/> <int value="1421620678" label="simple-clear-browsing-data-support-string"/> + <int value="1422462035" label="PaymentRequestBasicCard:disabled"/> <int value="1424775876" label="ToolbarIphAndroid:enabled"/> <int value="1425103276" label="SharedHighlightingV2:enabled"/> <int value="1427427985" @@ -75236,6 +75252,9 @@ </enum> <enum name="ServiceWorkerSite"> + <obsolete> + Removed in November 2021. + </obsolete> <int value="0" label="Other (unused)"/> <int value="1" label="NewTabPage"/> <int value="2" label="WithFetchHandler"/>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 4b9d279..2cf76ba6b 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -3064,6 +3064,103 @@ </summary> </histogram> +<histogram name="Ash.UserDataStatsRecorder.DataSize.{ItemName}" units="MB" + expires_after="M101"> + <owner>ythjkt@chromium.org</owner> + <owner>hidehiko@chromium.org</owner> + <summary> + Records the size of each file/dir directly under user data directory. + </summary> + <token key="ItemName"> + <variant name="AccountManagerTokensBin"/> + <variant name="Accounts"/> + <variant name="AffiliationDatabase"/> + <variant name="AppRankerPb"/> + <variant name="ArcApps"/> + <variant name="Autobrightness"/> + <variant name="AutofillStrikeDatabase"/> + <variant name="BlobStorage"/> + <variant name="Bookmarks"/> + <variant name="BudgetDatabase"/> + <variant name="Cache"/> + <variant name="CodeCache"/> + <variant name="Cookies"/> + <variant name="CrostiniIcons"/> + <variant name="Databases"/> + <variant name="DataReductionProxyLeveldb"/> + <variant name="DNRExtensionRules"/> + <variant name="Downloads"/> + <variant name="DownloadService"/> + <variant name="ExtensionCookies"/> + <variant name="ExtensionInstallLog"/> + <variant name="ExtensionRules"/> + <variant name="Extensions"/> + <variant name="ExtensionState"/> + <variant name="Favicons"/> + <variant name="FeatureEngagementTracker"/> + <variant name="FileSystem"/> + <variant name="FullRestoreData"/> + <variant name="GCache"/> + <variant name="GCMStore"/> + <variant name="GoogleAssistantLibrary"/> + <variant name="GPUCache"/> + <variant name="HeavyAdInterventionOptOutDb"/> + <variant name="History"/> + <variant name="IndexedDB"/> + <variant name="LocalAppSettings"/> + <variant name="LocalExtensionSettings"/> + <variant name="LocalStorage"/> + <variant name="LOCK"/> + <variant name="LOG"/> + <variant name="LoginData"/> + <variant name="LoginDataForAccount"/> + <variant name="LoginTimes"/> + <variant name="LOGOld"/> + <variant name="LogoutTimes"/> + <variant name="ManagedExtensionSettings"/> + <variant name="MyFiles"/> + <variant name="NearbySharePublicCertificateDatabase"/> + <variant name="NetworkActionPredictor"/> + <variant name="NetworkPersistentState"/> + <variant name="OptimizationGuideHintCacheStore"/> + <variant name="OptimizationGuideModelAndFeaturesStore"/> + <variant name="PlatformNotifications"/> + <variant name="Policy"/> + <variant name="PPDCache"/> + <variant name="Preferences"/> + <variant name="PreferredApps"/> + <variant name="PreviewsOptOutDb"/> + <variant name="PrintJobDatabase"/> + <variant name="QuotaManager"/> + <variant name="README"/> + <variant name="ReportingAndNEL"/> + <variant name="RLZData"/> + <variant name="ServiceWorker"/> + <variant name="Sessions"/> + <variant name="SessionStorage"/> + <variant name="SharedProtoDb"/> + <variant name="Shortcuts"/> + <variant name="SiteCharacteristicsDatabase"/> + <variant name="Smartcharging"/> + <variant name="StructuredMetrics"/> + <variant name="SyncAppSettings"/> + <variant name="SyncData"/> + <variant name="SyncExtensionSettings"/> + <variant name="TopSites"/> + <variant name="TranslateRankerModel"/> + <variant name="TransportSecurity"/> + <variant name="TrustedVault"/> + <variant name="Unknown"/> + <variant name="VisitedLinks"/> + <variant name="WebApplications"/> + <variant name="WebData"/> + <variant name="WebrtcEventLogs"/> + <variant name="WebRTCLogs"/> + <variant name="ZeroStateGroupRankerPb"/> + <variant name="ZeroStateLocalFilesPb"/> + </token> +</histogram> + <histogram name="Ash.Wallpaper.Collection" enum="WallpaperCollection" expires_after="2022-05-17"> <owner>jasontt@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/bluetooth/histograms.xml b/tools/metrics/histograms/metadata/bluetooth/histograms.xml index 79429b7..4b32a0e 100644 --- a/tools/metrics/histograms/metadata/bluetooth/histograms.xml +++ b/tools/metrics/histograms/metadata/bluetooth/histograms.xml
@@ -187,6 +187,19 @@ </token> </histogram> +<histogram name="Bluetooth.ChromeOS.FastPair.EngagementFunnel.Steps" + enum="FastPairEngagementFlowEvent" expires_after="2022-09-20"> + <owner>shanefitz@google.com</owner> + <owner>julietlevesque@google.com</owner> + <owner>chromeos-cross-device-eng@google.com</owner> + <summary> + Records each step in the Fast Pair flow. Emitted when the discovery UI is + shown, the discovery UI is dismissed, pairing progress begins, pairing + fails, pairing suceeded, the error UI is dismissed, and/or when the setting + button on the error UI is pressed. + </summary> +</histogram> + <histogram name="Bluetooth.ChromeOS.Forget.Result" enum="ForgetResult" expires_after="2022-07-21"> <owner>khorimoto@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml index 42c4576..be54ea9 100644 --- a/tools/metrics/histograms/metadata/ios/histograms.xml +++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -531,9 +531,9 @@ </histogram> <histogram name="IOS.Incognito.BiometricAuthEnabled" enum="Boolean" - expires_after="2021-11-05"> + expires_after="2022-09-20"> <owner>stkhapugin@chromium.org</owner> - <owner>javierrobles@chromium.org</owner> + <owner>gambard@chromium.org</owner> <summary> Logged once per app launch. Logs whether the biometric incognito authentication setting is enabled. This metric is designed to measure % of @@ -542,6 +542,16 @@ </summary> </histogram> +<histogram name="IOS.Incognito.BiometricReauthAttemptSuccessful" enum="Boolean" + expires_after="2022-09-20"> + <owner>stkhapugin@chromium.org</owner> + <owner>gambard@chromium.org</owner> + <summary> + Logged when the user attempt to reauthenticate to display the incognito + tabs. This metric is designed to measure the success of the reauth. + </summary> +</histogram> + <histogram name="IOS.Incognito.TimeSpent" units="ms" expires_after="2022-01-16"> <owner>olivierrobin@chromium.org</owner> <owner>thegreenfrog@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/printing/histograms.xml b/tools/metrics/histograms/metadata/printing/histograms.xml index e387df7..67332730 100644 --- a/tools/metrics/histograms/metadata/printing/histograms.xml +++ b/tools/metrics/histograms/metadata/printing/histograms.xml
@@ -187,8 +187,8 @@ </histogram> <histogram name="Printing.CUPS.JobDuration.JobCancelled" units="ms" - expires_after="2021-06-01"> - <owner>skau@chromium.org</owner> + expires_after="2022-02-06"> + <owner>bmgordon@chromium.org</owner> <owner>project-bolton@google.com</owner> <summary> Records the print job duration of a cancelled print job. Includes time spent @@ -198,7 +198,7 @@ <histogram name="Printing.CUPS.JobDuration.JobDone" units="ms" expires_after="2022-02-06"> - <owner>skau@chromium.org</owner> + <owner>bmgordon@chromium.org</owner> <owner>project-bolton@google.com</owner> <summary> Records the print job duration of a done/completed print job. Includes time @@ -243,8 +243,8 @@ </histogram> <histogram name="Printing.CUPS.PrintDocumentSize" units="KB" - expires_after="2021-10-04"> - <owner>skau@chromium.org</owner> + expires_after="2022-02-06"> + <owner>bmgordon@chromium.org</owner> <owner>project-bolton@google.com</owner> <summary> Records the total size of the printed document (PDF) sent to CUPS. Only
diff --git a/tools/metrics/histograms/metadata/service/histograms.xml b/tools/metrics/histograms/metadata/service/histograms.xml index 58856a51..5f8f9f14 100644 --- a/tools/metrics/histograms/metadata/service/histograms.xml +++ b/tools/metrics/histograms/metadata/service/histograms.xml
@@ -301,18 +301,22 @@ </histogram> <histogram name="ServiceWorker.FetchEvent.Fallback.Time" units="ms" - expires_after="2021-08-01"> - <owner>falken@chromium.org</owner> + expires_after="2022-09-01"> + <owner>wanderview@chromium.org</owner> + <owner>asamidoi@chromium.org</owner> <owner>chrome-worker@google.com</owner> <summary> The time taken between dispatching a FetchEvent to a Service Worker and receiving a fallback-to-network reply. + + This histogram was expired between roughly 2021-08-01 and 2021-09-31. </summary> </histogram> <histogram name="ServiceWorker.FetchEvent.HasResponse.Time" units="ms" - expires_after="2021-10-17"> - <owner>falken@chromium.org</owner> + expires_after="2022-09-01"> + <owner>wanderview@chromium.org</owner> + <owner>asamidoi@chromium.org</owner> <owner>chrome-worker@google.com</owner> <summary> The time taken between dispatching a FetchEvent to a Service Worker and @@ -356,6 +360,9 @@ <histogram name="ServiceWorker.FetchEvent.WaitUntil.Time" units="ms" expires_after="2021-06-30"> + <obsolete> + Removed in September 2021. + </obsolete> <owner>falken@chromium.org</owner> <owner>chrome-worker@google.com</owner> <summary> @@ -643,6 +650,9 @@ <histogram name="ServiceWorker.MainFramePageLoad" enum="ServiceWorkerSite" expires_after="2021-10-17"> + <obsolete> + Removed in September 2021. + </obsolete> <owner>falken@chromium.org</owner> <owner>chrome-worker@google.com</owner> <summary> @@ -685,6 +695,9 @@ <histogram name="ServiceWorker.PageLoad" enum="ServiceWorkerSite" expires_after="2021-12-26"> + <obsolete> + Removed in September 2021. + </obsolete> <owner>falken@chromium.org</owner> <owner>chrome-worker@google.com</owner> <summary>Counts page loads controlled by a service worker.</summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index d4be67c..1654831 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,20 +5,20 @@ "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "win": { - "hash": "48fd837c0f913f877e8f18944d92b26b7ecf52fa", - "remote_path": "perfetto_binaries/trace_processor_shell/win/df2e9fecdfb26f36a6a674b1f97a9117ab714a42/trace_processor_shell.exe" + "hash": "f7fee3c2e09aa645cecef22d34222162495e4043", + "remote_path": "perfetto_binaries/trace_processor_shell/win/8f0fabf54bc923165ac47bc1b7de45b9eee0ff3d/trace_processor_shell.exe" }, "mac": { - "hash": "9899e114a729f2e9c905e59e9207fa9e2a4b6928", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/df2e9fecdfb26f36a6a674b1f97a9117ab714a42/trace_processor_shell" + "hash": "8495324ae7e10a679c39808028860364fc49b90d", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/8f0fabf54bc923165ac47bc1b7de45b9eee0ff3d/trace_processor_shell" }, "linux_arm64": { "hash": "5074025a2898ec41a872e70a5719e417acb0a380", "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "linux": { - "hash": "491e1b0dd44c26c81015509cd9dfba05b6a84ebb", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/df2e9fecdfb26f36a6a674b1f97a9117ab714a42/trace_processor_shell" + "hash": "0a894350c17c22987d16050cfab0fa165eb98697", + "remote_path": "perfetto_binaries/trace_processor_shell/linux/8f0fabf54bc923165ac47bc1b7de45b9eee0ff3d/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/typescript/definitions/language_settings_private.d.ts b/tools/typescript/definitions/language_settings_private.d.ts new file mode 100644 index 0000000..e71976b1 --- /dev/null +++ b/tools/typescript/definitions/language_settings_private.d.ts
@@ -0,0 +1,91 @@ +// 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. + +/** @fileoverview Definitions for chrome.languageSettingsPrivate API */ +// TODO(crbug.com/1203307): Auto-generate this file. + +import {ChromeEvent} from './chrome_event.js'; + +declare global { + export namespace chrome { + export namespace languageSettingsPrivate { + export enum MoveType { + TOP = 'TOP', + UP = 'UP', + DOWN = 'DOWN', + UNKNOWN = 'UNKNOWN', + } + + export interface Language { + code: string; + displayName: string; + nativeDisplayName: string; + supportsUI?: boolean; + supportsSpellcheck?: boolean; + supportsTranslate?: boolean; + isProhibitedLanguage?: boolean; + } + + export interface SpellcheckDictionaryStatus { + languageCode: string; + isReady: boolean; + isDownloading?: boolean; + downloadFailed?: boolean; + } + + export interface InputMethod { + id: string; + displayName: string; + languageCodes: Array<string>; + tags: Array<string>; + enabled?: boolean; + hasOptionsPage?: boolean; + isProhibitedByPolicy?: boolean; + } + + export interface InputMethodLists { + componentExtensionImes: Array<InputMethod>; + thirdPartyExtensionImes: Array<InputMethod>; + } + + type StringArrayCallback = (strings: Array<string>) => void; + + export function getLanguageList( + callback: (languages: Array<Language>) => void): void; + export function enableLanguage(languageCode: string): void; + export function disableLanguage(languageCode: string): void; + export function setEnableTranslationForLanguage( + languageCode: string, enable: boolean): void; + export function moveLanguage(languageCode: string, moveType: MoveType): + void; + export function getAlwaysTranslateLanguages( + callback: StringArrayCallback): void; + export function setLanguageAlwaysTranslateState( + languageCode: string, alwaysTranslate: boolean): void; + export function getNeverTranslateLanguages(callback: StringArrayCallback): + void; + export function getSpellcheckDictionaryStatuses( + callback: (statuses: Array<SpellcheckDictionaryStatus>) => void): + void; + export function getSpellcheckWords(callback: StringArrayCallback): void; + export function addSpellcheckWord(word: string): void; + export function removeSpellcheckWord(word: string): void; + export function getTranslateTargetLanguage( + callback: (languageCode: string) => void): void; + export function setTranslateTargetLanguage(languageCode: string): void; + export function getInputMethodLists( + callback: (lists: InputMethodLists) => void): void; + export function addInputMethod(inputMethodId: string): void; + export function removeInputMethod(inputMethodId: string): void; + export function retryDownloadDictionary(languageCode: string): void; + + export const onSpellcheckDictionariesChanged: ChromeEvent< + Array<SpellcheckDictionaryStatus>>; + export const onCustomDictionaryChanged: + ChromeEvent<(added: Array<string>, removed: Array<string>) => void>; + export const onInputMethodAdded: ChromeEvent<string>; + export const onInputMethodRemoved: ChromeEvent<string>; + } + } +}
diff --git a/ui/chromeos/translations/ui_chromeos_strings_my.xtb b/ui/chromeos/translations/ui_chromeos_strings_my.xtb index c64da66..d3f2ee0a 100644 --- a/ui/chromeos/translations/ui_chromeos_strings_my.xtb +++ b/ui/chromeos/translations/ui_chromeos_strings_my.xtb
@@ -44,7 +44,7 @@ <translation id="1353686479385938207"><ph name="PROVIDER_NAME" />: <ph name="NETWORK_NAME" /></translation> <translation id="1358735829858566124">ဖိုင်သို့မဟုတ် လမ်းကြောင်း အသုံးပြု၍ မရပါ။</translation> <translation id="1363028406613469049">သီချင်းပုဒ်</translation> -<translation id="1378727793141957596">Google Drive မှကြိုဆိုပါသည်!</translation> +<translation id="1378727793141957596">Google Drive က ကြိုဆိုပါသည်!</translation> <translation id="1379911846207762492">အင်တာနက်ချိတ်ဆက်မှု မရှိသည့်အခါ ဖွင့်ကြည့်နိုင်ရန် ဖိုင်များကို အော့ဖ်လိုင်းသုံးနိုင်အောင် ပြုလုပ်နိုင်သည်။</translation> <translation id="1383876407941801731">ရှာဖွေမှု</translation> <translation id="1395262318152388157">ဆလိုက်ဒါးကို ရှာပါ</translation>
diff --git a/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc b/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc index 3b900b02..f92b36b 100644 --- a/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc +++ b/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc
@@ -112,7 +112,7 @@ void GLSurfaceWayland::UpdateVisualSize() { window_->ui_task_runner()->PostTask( FROM_HERE, base::BindOnce(&WaylandWindow::UpdateVisualSize, - base::Unretained(window_), size_)); + window_->AsWeakPtr(), size_)); } } // namespace ui
diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h index c8f3b6b..29f951d3 100644 --- a/ui/ozone/platform/wayland/host/wayland_window.h +++ b/ui/ozone/platform/wayland/host/wayland_window.h
@@ -14,6 +14,7 @@ #include "base/containers/flat_set.h" #include "base/gtest_prod_util.h" #include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom-forward.h" #include "ui/events/platform/platform_event_dispatcher.h" @@ -257,6 +258,10 @@ // Returns bounds in DIP. gfx::Rect GetBoundsInDIP() const; + base::WeakPtr<WaylandWindow> AsWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + protected: WaylandWindow(PlatformWindowDelegate* delegate, WaylandConnection* connection);