diff --git a/.vpython3 b/.vpython3 index 0a9aa38..450470f 100644 --- a/.vpython3 +++ b/.vpython3
@@ -387,19 +387,7 @@ wheel: < name: "infra/python/wheels/pandas/${vpython_platform}" version: "version:1.3.2.chromium.1" - match_tag: < - platform: "win32" - > - match_tag: < - platform: "win_amd64" - > - match_tag: < - platform: "manylinux1_i686" - > - match_tag: < - platform: "manylinux1_x86_64" - > - match_tag: < - platform: "macosx_10_6_intel" + not_match_tag: < + platform: "linux_aarch64" > >
diff --git a/DEPS b/DEPS index ffebf83..2bb88b7b 100644 --- a/DEPS +++ b/DEPS
@@ -234,11 +234,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': 'f4db9165ebe4c81130957cb73ff2e3925c4134b1', + 'skia_revision': 'fa2edac74af81de2d50aee934903dc5d081d28fa', # 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': '95d3d4db9271707b31ccb1b57743505b332f5262', + 'v8_revision': 'e5295095036eefaadf795df8fad10d9250c4ba7a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. @@ -246,11 +246,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '0f6b833bc7610538766018326d525ec2307df998', + 'swiftshader_revision': 'e068963d1dcf8e5bd4e940ca76edbd19abab9d44', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '8d64cb50a5bb4486695a010338cf950eb6a85364', + 'pdfium_revision': '15c1e6ae5cf2cd2ca02b0a530fdb85e106ab4781', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. @@ -281,7 +281,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': 'd31bafcb9ce7dee7036089a394556ebf201221ec', + 'freetype_revision': 'e4f7673e46450298db1ce5fda8a3d310cfb50d78', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -301,7 +301,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '1a5ffbc5f1b40458da2fa20082d5a93db35665de', + 'catapult_revision': 'ccdf6bde5f204ff8d1c4acb5dfddc501669a1d47', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -309,7 +309,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': '492e3aa917fa44fc5af1428e221c7d02c5b580e8', + 'devtools_frontend_revision': 'b087748aad6c9fef9f564ff4b9ce7a9ad3913dc5', # 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. @@ -349,7 +349,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': '8f4eacd082cf1e78242dce452b520da632010bc5', + 'dawn_revision': '8ce15b3ce97efbb175ba67ae1df9a10cdc3ea4af', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -416,7 +416,7 @@ 'libcxx_revision': '79a2e924d96e2fc1e4b937c42efd08898fa472d7', # GN CIPD package version. - 'gn_version': 'git_revision:185124551408e7a5349c2aa31051b5a629dc3a5e', + 'gn_version': 'git_revision:4aa9bdfa05b688c58d3d7d3e496f3f18cbb3d89e', } # Only these hosts are allowed for dependencies in this DEPS file. @@ -627,7 +627,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '2fedfe98108e93345d56f3a3d61a7a297256f2e0', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '6ae6c2edacaceb6ae459de19415488d6a12db16a', 'condition': 'checkout_ios', }, @@ -791,7 +791,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'eenVsfeHLKnm1MmzR1_7Zz7iUfRKwHG4j5jTupRbzrcC', + 'version': 'GpsjLtmFq0wH_145hryWddxYQ-dHC-2cy5x8AoOf7pIC', }, ], 'condition': 'checkout_android', @@ -901,7 +901,7 @@ Var('chromium_git') + '/angle/angle.git' + '@' + Var('angle_revision'), 'src/third_party/dav1d/libdav1d': - Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + '7b433e077298d0f4faf8da6d6eb5774e29bffa54', + Var('chromium_git') + '/external/github.com/videolan/dav1d.git' + '@' + '692c0ce873d7d823f2255968e32b233d71d88b43', 'src/third_party/dawn': Var('dawn_git') + '/dawn.git' + '@' + Var('dawn_revision'), @@ -1010,7 +1010,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '81a96e6cdf9906cf1feaefce69f6a69d12474010', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'c8416d0eb4a9010cbcfecf6789ed34171f39fc5b', 'condition': 'checkout_chromeos', }, @@ -1030,7 +1030,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '067f0e55d3764ee267cf5ce6e61054ebe6860e54', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '64cb3ee4cddbb44a7fa474a8f08cff4d52897181', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1085,7 +1085,7 @@ Var('chromium_git') + '/external/github.com/google/gemmlowp.git' + '@' + '13d57703abca3005d97b19df1f2db731607a7dc2', 'src/third_party/grpc/src': { - 'url': Var('chromium_git') + '/external/github.com/grpc/grpc.git' + '@' + '1777ddf3c344f110323a625d75ff87c5ebc8d789', + 'url': Var('chromium_git') + '/external/github.com/grpc/grpc.git' + '@' + 'da47e8823754d12f1dd643bc911e80703b557ade', }, 'src/third_party/freetype/src': @@ -1173,7 +1173,7 @@ Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '18e09b9197a3b1d771c077c530d1a4ebad04c167', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '3e05d9daa98b765632fb5f79aa66f407efe1e262', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'd3ba6ae0c0a1b940c496771431feff25d4262d42', 'src/third_party/icu4j': { 'packages': [ @@ -1302,7 +1302,7 @@ }, 'src/third_party/libvpx/source/libvpx': - Var('chromium_git') + '/webm/libvpx.git' + '@' + 'e259e6951d794ca6a6f2f3c9c40c5c99818613d3', + Var('chromium_git') + '/webm/libvpx.git' + '@' + 'ec80f88c5d05539c89f8bda8df571b66cab9566d', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + 'e4fbea0c9751ae8aa86629b197a28d8276a2b0da', @@ -1399,7 +1399,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '3dd5b80bc4f172dd82925bb259cb7c82348409c5', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + 'deacb4eddbbcd90e97837951da1f1dfbcd46366f', + Var('chromium_git') + '/openscreen' + '@' + 'f1c6841fc07df323c0dd90fa1be000152a7cd99a', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245', @@ -1416,7 +1416,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '4d59d2eea6b38fd64ed37d640d02b5d161d66594', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f890ec27af91a43e1f0ca7795a902ef972590c5f', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1637,7 +1637,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '5e8ac4959f931fcffb7d0d97b82b22ba0db6258e', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'efe46b6beea9c1f31d3e6686bb1fd0c7d5f35375', + Var('webrtc_git') + '/src.git' + '@' + 'c09b14c3c57d521416a57dde57bf969cbf41ac17', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1695,7 +1695,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@6d2ea22c3fe59f965ad76bde0cec078e1fd5e1bd', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1ec54d50b8c144dfe2cfc5710d04655caa3fcdd1', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_settings.cc b/android_webview/browser/aw_settings.cc index 8624cfa8..088e20a 100644 --- a/android_webview/browser/aw_settings.cc +++ b/android_webview/browser/aw_settings.cc
@@ -404,10 +404,6 @@ web_prefs->plugins_enabled = false; - // TODO(enne): Remove this pref, and clean up Android settings. - web_prefs->application_cache_enabled = - Java_AwSettings_getAppCacheEnabledLocked(env, obj); - web_prefs->local_storage_enabled = Java_AwSettings_getDomStorageEnabledLocked(env, obj);
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSettings.java b/android_webview/java/src/org/chromium/android_webview/AwSettings.java index 671c65a..484d72d 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwSettings.java +++ b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
@@ -116,7 +116,6 @@ private boolean mAllowFileAccessFromFileURLs; private boolean mJavaScriptCanOpenWindowsAutomatically; private boolean mSupportMultipleWindows; - private boolean mAppCacheEnabled; private boolean mDomStorageEnabled; private boolean mDatabaseEnabled; private boolean mUseWideViewport; @@ -169,10 +168,6 @@ // Protects access to settings global fields. private static final Object sGlobalContentSettingsLock = new Object(); - // For compatibility with the legacy WebView, we can only enable AppCache when the path is - // provided. However, we don't use the path, so we just check if we have received it from the - // client. - private static boolean sAppCachePathIsSet; // The native side of this object. It's lifetime is bounded by the WebContent it is attached to. private long mNativeAwSettings; @@ -1441,52 +1436,14 @@ * See {@link android.webkit.WebSettings#setAppCacheEnabled}. */ public void setAppCacheEnabled(boolean flag) { - if (TRACE) Log.i(LOGTAG, "setAppCacheEnabled=" + flag); - synchronized (mAwSettingsLock) { - if (mAppCacheEnabled != flag) { - mAppCacheEnabled = flag; - mEventHandler.updateWebkitPreferencesLocked(); - } - } + // Deprecated no-op. } /** * See {@link android.webkit.WebSettings#setAppCachePath}. */ public void setAppCachePath(String path) { - if (TRACE) Log.i(LOGTAG, "setAppCachePath=" + path); - boolean needToSync = false; - synchronized (sGlobalContentSettingsLock) { - // AppCachePath can only be set once. - if (!sAppCachePathIsSet && path != null && !path.isEmpty()) { - sAppCachePathIsSet = true; - needToSync = true; - } - } - // The obvious problem here is that other WebViews will not be updated, - // until they execute synchronization from Java to the native side. - // But this is the same behaviour as it was in the legacy WebView. - if (needToSync) { - synchronized (mAwSettingsLock) { - mEventHandler.updateWebkitPreferencesLocked(); - } - } - } - - /** - * Gets whether Application Cache is enabled. - * - * @return true if Application Cache is enabled - */ - @CalledByNative - private boolean getAppCacheEnabledLocked() { - assert Thread.holdsLock(mAwSettingsLock); - if (!mAppCacheEnabled) { - return false; - } - synchronized (sGlobalContentSettingsLock) { - return sAppCachePathIsSet; - } + // Deprecated no-op. } /**
diff --git a/android_webview/ui/grit_strings_allowlist.txt b/android_webview/ui/grit_strings_allowlist.txt index 811ce717..4c2e97c 100644 --- a/android_webview/ui/grit_strings_allowlist.txt +++ b/android_webview/ui/grit_strings_allowlist.txt
@@ -40,7 +40,6 @@ IDS_HARMFUL_WEBVIEW_EXPLANATION_PARAGRAPH IDS_BILLING_WEBVIEW_HEADING IDS_BILLING_WEBVIEW_EXPLANATION_PARAGRAPH -IDS_SB_UNDER_CONSTRUCTION IDS_AUTOFILL_CC_AMEX IDS_AUTOFILL_CC_AMEX_SHORT IDS_AUTOFILL_CC_DINERS
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 38c043a..6bf8776c 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -3029,6 +3029,7 @@ "//testing/gtest", "//third_party/blink/public:blink_headers", "//ui/display:display_manager_test_api", + "//ui/lottie", ] deps = [ "//ash",
diff --git a/ash/accelerators/pre_target_accelerator_handler.cc b/ash/accelerators/pre_target_accelerator_handler.cc index 31ed5e8..0e6b85f 100644 --- a/ash/accelerators/pre_target_accelerator_handler.cc +++ b/ash/accelerators/pre_target_accelerator_handler.cc
@@ -35,6 +35,7 @@ case ui::VKEY_POWER: case ui::VKEY_SLEEP: case ui::VKEY_PRIVACY_SCREEN_TOGGLE: + case ui::VKEY_SETTINGS: return true; case ui::VKEY_MEDIA_NEXT_TRACK: case ui::VKEY_MEDIA_PAUSE:
diff --git a/ash/app_list/BUILD.gn b/ash/app_list/BUILD.gn index c2f730a..233f908 100644 --- a/ash/app_list/BUILD.gn +++ b/ash/app_list/BUILD.gn
@@ -127,6 +127,8 @@ "views/search_result_list_view.h", "views/search_result_page_anchored_dialog.cc", "views/search_result_page_anchored_dialog.h", + "views/search_result_page_dialog_controller.cc", + "views/search_result_page_dialog_controller.h", "views/search_result_page_view.cc", "views/search_result_page_view.h", "views/search_result_suggestion_chip_view.cc",
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index 212f576..6b668766 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -1208,6 +1208,7 @@ switch (launched_from) { case AppListLaunchedFrom::kLaunchedFromSearchBox: case AppListLaunchedFrom::kLaunchedFromSuggestionChip: + case AppListLaunchedFrom::kLaunchedFromRecentApps: RecordAppLaunched(launched_from); break; case AppListLaunchedFrom::kLaunchedFromGrid: @@ -1321,9 +1322,11 @@ void AppListControllerImpl::GetContextMenuModel( const std::string& id, + bool add_sort_options, GetContextMenuModelCallback callback) { if (client_) - client_->GetContextMenuModel(profile_id_, id, std::move(callback)); + client_->GetContextMenuModel(profile_id_, id, add_sort_options, + std::move(callback)); } ui::ImplicitAnimationObserver* AppListControllerImpl::GetAnimationObserver(
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h index 16aee49..bc19d87 100644 --- a/ash/app_list/app_list_controller_impl.h +++ b/ash/app_list/app_list_controller_impl.h
@@ -176,6 +176,7 @@ int event_flags, AppListLaunchedFrom launched_from) override; void GetContextMenuModel(const std::string& id, + bool add_sort_options, GetContextMenuModelCallback callback) override; ui::ImplicitAnimationObserver* GetAnimationObserver( AppListViewState target_state) override;
diff --git a/ash/app_list/app_list_metrics.cc b/ash/app_list/app_list_metrics.cc index 6577801..816f3fe 100644 --- a/ash/app_list/app_list_metrics.cc +++ b/ash/app_list/app_list_metrics.cc
@@ -348,6 +348,9 @@ case CommandId::USE_LAUNCH_TYPE_WINDOW: case CommandId::USE_LAUNCH_TYPE_TABBED_WINDOW: case CommandId::USE_LAUNCH_TYPE_COMMAND_END: + case CommandId::REORDER_SUBMENU: + case CommandId::REORDER_BY_NAME_ALPHABETICAL: + case CommandId::REORDER_BY_NAME_REVERSE_ALPHABETICAL: case CommandId::SHUTDOWN_GUEST_OS: case CommandId::EXTENSIONS_CONTEXT_CUSTOM_FIRST: case CommandId::EXTENSIONS_CONTEXT_CUSTOM_LAST:
diff --git a/ash/app_list/app_list_metrics_unittest.cc b/ash/app_list/app_list_metrics_unittest.cc index da421cd..4eafdc10 100644 --- a/ash/app_list/app_list_metrics_unittest.cc +++ b/ash/app_list/app_list_metrics_unittest.cc
@@ -504,6 +504,77 @@ 1 /* Number of times launched from search box */); } +class AppListProductivityAppLaunchedMetricTest + : public AppListAppLaunchedMetricTest { + public: + AppListProductivityAppLaunchedMetricTest() { + scoped_feature_list_.InitWithFeatures({features::kProductivityLauncher}, + {}); + } + ~AppListProductivityAppLaunchedMetricTest() override = default; + + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// Test that the histogram records an app launch from a recent app suggestion +// while the bubble launcher all apps is showing. +TEST_F(AppListProductivityAppLaunchedMetricTest, + BubbleAllAppsLaunchFromRecentApps) { + base::HistogramTester histogram_tester; + auto* helper = GetAppListTestHelper(); + + helper->WaitUntilIdle(); + + helper->AddRecentApps(5); + helper->AddAppItems(5); + helper->ShowAppList(); + + helper->WaitUntilIdle(); + views::View* recent_apps = helper->GetBubbleRecentAppsView(); + + // Get focus on the first chip. + recent_apps->children().front()->RequestFocus(); + helper->WaitUntilIdle(); + + // Press return to simulate an app launch from the recent apps. + PressAndReleaseKey(ui::KeyboardCode::VKEY_RETURN); + helper->WaitUntilIdle(); + + histogram_tester.ExpectBucketCount( + "Apps.AppListAppLaunchedV2.BubbleAllApps", + AppListLaunchedFrom::kLaunchedFromRecentApps, + 1 /* Number of times launched from chip */); +} + +// Test that the histogram records an app launch from a recent app suggestion +// while the homecher all apps is showing. +TEST_F(AppListProductivityAppLaunchedMetricTest, HomecherLaunchFromRecentApps) { + base::HistogramTester histogram_tester; + auto* helper = GetAppListTestHelper(); + + helper->WaitUntilIdle(); + + helper->AddRecentApps(5); + helper->AddAppItems(5); + Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); + + helper->WaitUntilIdle(); + views::View* recent_apps = helper->GetFullscreenRecentAppsView(); + + // Get focus on the first chip. + recent_apps->children().front()->RequestFocus(); + helper->WaitUntilIdle(); + + // Press return to simulate an app launch from the recent apps. + PressAndReleaseKey(ui::KeyboardCode::VKEY_RETURN); + helper->WaitUntilIdle(); + + histogram_tester.ExpectBucketCount( + "Apps.AppListAppLaunchedV2.HomecherAllApps", + AppListLaunchedFrom::kLaunchedFromRecentApps, + 1 /* Number of times launched from chip */); +} + class AppListShowSourceMetricTest : public AshTestBase { public: AppListShowSourceMetricTest() = default;
diff --git a/ash/app_list/app_list_presenter_impl.cc b/ash/app_list/app_list_presenter_impl.cc index 0dc0e2ba..e85e1f25 100644 --- a/ash/app_list/app_list_presenter_impl.cc +++ b/ash/app_list/app_list_presenter_impl.cc
@@ -542,7 +542,8 @@ !base::Contains(kIdsOfContainersThatWontHideAppList, gained_focus_container_id); - const bool app_list_gained_focus = applist_window->Contains(gained_focus); + const bool app_list_gained_focus = applist_window->Contains(gained_focus) || + applist_container->Contains(gained_focus); const bool app_list_lost_focus = gained_focus ? gained_focus_hides_app_list : (lost_focus && applist_container->Contains(lost_focus));
diff --git a/ash/app_list/app_list_presenter_unittest.cc b/ash/app_list/app_list_presenter_unittest.cc index 00ee6ab..24c88a8 100644 --- a/ash/app_list/app_list_presenter_unittest.cc +++ b/ash/app_list/app_list_presenter_unittest.cc
@@ -157,6 +157,7 @@ auto suggestion_result = std::make_unique<TestSearchResult>(); suggestion_result->set_result_id(result_id); suggestion_result->set_is_omnibox_search(true); + suggestion_result->set_best_match(true); suggestion_result->set_display_type(SearchResultDisplayType::kList); SearchResultActions actions; actions.push_back(SearchResultAction(gfx::ImageSkia(), u"Remove", @@ -166,14 +167,35 @@ return suggestion_result; } +// Verifies the current search result page anchored dialog bounds. +// The dialog is expected to be positioned horizontally centered within the +// search box bounds. +void SanityCheckSearchResultsAnchoredDialogBounds( + const views::Widget* dialog, + const SearchBoxView* search_box_view) { + auto horizontal_center_offset = [](const gfx::Rect& inner, + const gfx::Rect& outer) -> int { + return outer.CenterPoint().x() - inner.CenterPoint().x(); + }; + + const gfx::Rect dialog_bounds = dialog->GetWindowBoundsInScreen(); + const gfx::Rect search_box_bounds = + search_box_view->GetWidget()->GetWindowBoundsInScreen(); + // The dialog should be horizontally centered within the search box. + EXPECT_EQ(0, horizontal_center_offset(dialog_bounds, search_box_bounds)); + // Verify the confirmation dialog is positioned with the top within search + // box bounds. + EXPECT_GT(dialog_bounds.y(), search_box_bounds.y()); + EXPECT_LT(dialog_bounds.y(), search_box_bounds.bottom()); +} + } // namespace // This suite used to be called AppListPresenterDelegateTest. It's not called // AppListPresenterImplTest because that name was already taken. The two test // suite were not merged in order to maintain git blame history for this file. -class AppListPresenterTest - : public AshTestBase, - public testing::WithParamInterface<std::tuple<bool, bool>> { +class AppListPresenterTest : public AshTestBase, + public testing::WithParamInterface<bool> { public: AppListPresenterTest() = default; AppListPresenterTest(const AppListPresenterTest&) = delete; @@ -182,8 +204,6 @@ // testing::Test: void SetUp() override { - feature_list_.InitWithFeatureState( - app_list_features::kNewDragSpecInLauncher, std::get<1>(GetParam())); AshTestBase::SetUp(); // Make the display big enough to hold the app list. @@ -197,10 +217,10 @@ } // Whether to run the test with mouse or gesture events. - bool TestMouseEventParam() const { return std::get<0>(GetParam()); } + bool TestMouseEventParam() const { return GetParam(); } - // Whether to run the test with mouse or gesture events. - bool GetTestFullscreen() const { return std::get<0>(GetParam()); } + // Whether to run the test with fullscreen or not. + bool GetTestFullscreen() const { return GetParam(); } gfx::Point GetPointOutsideSearchbox() { // Ensures that the point satisfies the following conditions: @@ -275,35 +295,12 @@ views::DialogDelegate* GetSearchResultPageAnchoredDialog() { return search_result_page() - ->anchored_dialog_for_test() + ->dialog_for_test() ->widget() ->widget_delegate() ->AsDialogDelegate(); } - // Verifies the current search result page anchored dialog bounds. - // The dialog is expected to be positioned horizontally centered within the - // search box bounds. - void SanityCheckSearchResultsAnchoredDialogBounds( - const views::Widget* dialog) { - auto horizontal_center_offset = [](const gfx::Rect& inner, - const gfx::Rect& outer) -> int { - return outer.CenterPoint().x() - inner.CenterPoint().x(); - }; - - const gfx::Rect dialog_bounds = dialog->GetWindowBoundsInScreen(); - const gfx::Rect search_box_bounds = GetAppListView() - ->search_box_view() - ->GetWidget() - ->GetWindowBoundsInScreen(); - // The dialog should be horizontally centered within the search box. - EXPECT_EQ(0, horizontal_center_offset(dialog_bounds, search_box_bounds)); - // Verify the confirmation dialog is positioned with the top within search - // box bounds. - EXPECT_GT(dialog_bounds.y(), search_box_bounds.y()); - EXPECT_LT(dialog_bounds.y(), search_box_bounds.bottom()); - } - // Returns the |dialog| vertical offset from the top of the search box bounds. int GetSearchResultsAnchoredDialogTopOffset(const views::Widget* dialog) { const gfx::Rect dialog_bounds = dialog->GetWindowBoundsInScreen(); @@ -361,15 +358,67 @@ return !productivity_launcher_param(); } + SearchBoxView* GetSearchBoxView() { + return should_show_bubble_launcher() + ? GetAppListTestHelper()->GetBubbleSearchBoxView() + : GetAppListTestHelper()->GetAppListView()->search_box_view(); + } + + SearchResultPageView* GetFullscreenSearchPage() { + return GetAppListTestHelper() + ->GetAppListView() + ->app_list_main_view() + ->contents_view() + ->search_result_page_view(); + } + bool AppListSearchResultPageVisible() { return should_show_bubble_launcher() ? GetAppListTestHelper()->GetBubbleSearchPage()->GetVisible() - : GetAppListTestHelper() - ->GetAppListView() - ->app_list_main_view() - ->contents_view() - ->search_result_page_view() - ->GetVisible(); + : GetFullscreenSearchPage()->GetVisible(); + } + + SearchResultContainerView* GetDefaultSearchResultListView() { + if (should_show_bubble_launcher()) { + return GetAppListTestHelper() + ->GetProductivityLauncherSearchView() + ->result_container_views_for_test()[0]; + } + if (productivity_launcher_param()) { + return GetFullscreenSearchPage() + ->productivity_launcher_search_view_for_test() + ->result_container_views_for_test()[0]; + } + return GetFullscreenSearchPage()->GetSearchResultListViewForTest(); + } + + ResultSelectionController* GetResultSelectionController() { + if (should_show_bubble_launcher()) { + return GetAppListTestHelper() + ->GetProductivityLauncherSearchView() + ->result_selection_controller_for_test(); + } + + if (productivity_launcher_param()) { + return GetFullscreenSearchPage() + ->productivity_launcher_search_view_for_test() + ->result_selection_controller_for_test(); + } + + return GetFullscreenSearchPage()->result_selection_controller(); + } + + SearchResultPageAnchoredDialog* GetSearchResultPageDialog() { + return should_show_bubble_launcher() + ? GetAppListTestHelper()->GetBubbleSearchPageDialog() + : GetAppListTestHelper()->GetFullscreenSearchPageDialog(); + } + + views::DialogDelegate* GetSearchResultPageDialogDelegate() { + return GetSearchResultPageDialog() + ->widget() + ->widget_delegate() + ->AsDialogDelegate(); } ContinueSectionView* GetContinueSectionView() { @@ -391,6 +440,13 @@ ->GetFullscreenLauncherAppsSeparatorView(); } + void LongPressAt(const gfx::Point& point) { + ui::TouchEvent long_press(ui::ET_GESTURE_LONG_PRESS, point, + base::TimeTicks::Now(), + ui::PointerDetails(ui::EventPointerType::kTouch)); + GetEventGenerator()->Dispatch(&long_press); + } + void EnsureLauncherShown() { auto* helper = GetAppListTestHelper(); if (should_show_bubble_launcher()) { @@ -437,15 +493,12 @@ }; // Used to test app_list behavior with a populated apps_grid -class PopulatedAppListTest : public AshTestBase, - public testing::WithParamInterface<bool> { +class PopulatedAppListTest : public AshTestBase { public: PopulatedAppListTest() = default; ~PopulatedAppListTest() override = default; void SetUp() override { - feature_list_.InitWithFeatureState( - app_list_features::kNewDragSpecInLauncher, GetParam()); AppListConfigProvider::Get().ResetForTesting(); AshTestBase::SetUp(); @@ -531,8 +584,6 @@ std::unique_ptr<test::AppsGridViewTestApi> apps_grid_test_api_; AppListView* app_list_view_ = nullptr; // Owned by native widget. PagedAppsGridView* apps_grid_view_ = nullptr; // Owned by |app_list_view_|. - - base::test::ScopedFeatureList feature_list_; }; // Subclass of PopuplatedAppListTest which enables the virtual keyboard. @@ -548,22 +599,10 @@ } }; -// Instantiate the values in the parameterized tests. First boolean is used to +// Instantiate the values in the parameterized tests. Used to // toggle mouse and touch events and in some tests to toggle fullscreen mode -// tests. The second one toggles cardfied state feature enabled or disabled. -INSTANTIATE_TEST_SUITE_P(All, - AppListPresenterTest, - testing::Combine(testing::Bool(), testing::Bool())); - -// Instantiate the Boolean which is used to toggle cardified state in the -// parameterized tests. -INSTANTIATE_TEST_SUITE_P(All, PopulatedAppListTest, testing::Bool()); - -// Instantiate the Boolean which is used to toggle cardified state in the -// parameterized tests. -INSTANTIATE_TEST_SUITE_P(All, - PopulatedAppListWithVKEnabledTest, - testing::Bool()); +// tests. +INSTANTIATE_TEST_SUITE_P(All, AppListPresenterTest, testing::Bool()); // Instantiate the values in the parameterized tests. First boolean is used to // determine whether to use the kProductivityLauncher feature flag. The second @@ -828,20 +867,16 @@ GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps); } -TEST_P(AppListPresenterTest, RemoveSuggestionShowsConfirmDialog) { - ShowZeroStateSearchInHalfState(); +TEST_P(AppListBubbleAndTabletTest, RemoveSuggestionShowsConfirmDialog) { + EnableTabletMode(tablet_mode_param()); + EnsureLauncherShown(); - // Mark the suggested content info as dismissed so that it does not interfere - // with the layout. - Shell::Get()->app_list_controller()->MarkSuggestedContentInfoDismissed(); - GetAppListView() - ->app_list_main_view() - ->contents_view() - ->search_result_page_view() - ->GetPrivacyContainerViewForTest() - ->Update(); + // Show search page. + ui::test::EventGenerator* generator = GetEventGenerator(); + generator->PressKey(ui::VKEY_A, 0); + EXPECT_TRUE(AppListSearchResultPageVisible()); - // Add a zero state suggestion results - the result that will be tested is in + // Add suggestion results - the result that will be tested is in // the second place. GetSearchModel()->results()->Add( CreateOmniboxSuggestionResult("Another suggestion")); @@ -849,16 +884,17 @@ GetSearchModel()->results()->Add( CreateOmniboxSuggestionResult(kTestResultId)); // The result list is updated asynchronously. - GetAppListTestHelper()->WaitUntilIdle(); + base::RunLoop().RunUntilIdle(); - SearchResultBaseView* result_view = GetSearchResultListViewItemAt(1); + SearchResultBaseView* result_view = + GetDefaultSearchResultListView()->GetResultViewAt(1); ASSERT_TRUE(result_view); ASSERT_TRUE(result_view->result()); ASSERT_EQ(kTestResultId, result_view->result()->id()); // Make sure the search results page is laid out after adding result action // buttons. - GetAppListView()->GetWidget()->LayoutRootViewIfNecessary(); + result_view->GetWidget()->LayoutRootViewIfNecessary(); ASSERT_TRUE(result_view->actions_view()); EXPECT_EQ(1u, result_view->actions_view()->children().size()); @@ -866,38 +902,37 @@ // The remove action button is visible on hover only. EXPECT_FALSE(action_view->GetVisible()); - - ui::test::EventGenerator* generator = GetEventGenerator(); generator->MoveMouseTo(result_view->GetBoundsInScreen().CenterPoint()); EXPECT_TRUE(action_view->GetVisible()); // Record the current result selection before clicking the remove action // button. ResultSelectionController* result_selection_controller = - search_result_page()->result_selection_controller(); + GetResultSelectionController(); EXPECT_TRUE(result_selection_controller->selected_result()->selected()); ResultLocationDetails* result_location = result_selection_controller->selected_location_details(); // Ensure layout after the action view visibility has been updated. - GetAppListView()->GetWidget()->LayoutRootViewIfNecessary(); + result_view->GetWidget()->LayoutRootViewIfNecessary(); // Click the remove action button, this should surface a confirmation dialog. - ClickMouseAt(action_view->GetBoundsInScreen().CenterPoint()); + generator->MoveMouseTo(action_view->GetBoundsInScreen().CenterPoint()); + generator->ClickLeftButton(); EXPECT_TRUE(GetAppListTestHelper() ->app_list_client() ->GetAndClearInvokedResultActions() .empty()); - ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + ASSERT_TRUE(GetSearchResultPageDialog()); // Cancel the dialog - the app list should remain in the search result page, // the suggestion removal dialog should be hidden, and no result action should // be invoked. - GetSearchResultPageAnchoredDialog()->CancelDialog(); + GetSearchResultPageDialogDelegate()->CancelDialog(); - GetAppListTestHelper()->CheckState(AppListViewState::kHalf); - EXPECT_FALSE(search_result_page()->anchored_dialog_for_test()); + EXPECT_TRUE(AppListSearchResultPageVisible()); + EXPECT_FALSE(GetSearchResultPageDialog()); EXPECT_TRUE(GetAppListTestHelper() ->app_list_client() ->GetAndClearInvokedResultActions() @@ -909,16 +944,17 @@ result_selection_controller->selected_location_details()); // Click remove suggestion action button again. - ClickMouseAt(action_view->GetBoundsInScreen().CenterPoint()); + generator->MoveMouseTo(action_view->GetBoundsInScreen().CenterPoint()); + generator->ClickLeftButton(); // Expect the removal confirmation dialog - this time, accept it. - ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); - GetSearchResultPageAnchoredDialog()->AcceptDialog(); + ASSERT_TRUE(GetSearchResultPageDialog()); + GetSearchResultPageDialogDelegate()->AcceptDialog(); // The app list should remain showing search results, the dialog should be // closed, and result removal action should be invoked. - GetAppListTestHelper()->CheckState(AppListViewState::kHalf); - EXPECT_FALSE(search_result_page()->anchored_dialog_for_test()); + EXPECT_TRUE(AppListSearchResultPageVisible()); + EXPECT_FALSE(GetSearchResultPageDialog()); // The result selection should be at the same position. EXPECT_TRUE(result_selection_controller->selected_result()->selected()); @@ -934,10 +970,16 @@ EXPECT_EQ(expected_actions, invoked_actions); } -TEST_P(AppListPresenterTest, RemoveSuggestionUsingLongTap) { - ShowZeroStateSearchInHalfState(); +TEST_P(AppListBubbleAndTabletTest, RemoveSuggestionUsingLongTap) { + EnableTabletMode(tablet_mode_param()); + EnsureLauncherShown(); - // Add a zero state suggestion results - the result that will be tested is in + // Show search page. + ui::test::EventGenerator* generator = GetEventGenerator(); + generator->PressKey(ui::VKEY_A, 0); + EXPECT_TRUE(AppListSearchResultPageVisible()); + + // Add suggestion results - the result that will be tested is in // the second place. GetSearchModel()->results()->Add( CreateOmniboxSuggestionResult("Another suggestion")); @@ -946,14 +988,15 @@ CreateOmniboxSuggestionResult(kTestResultId)); GetAppListTestHelper()->WaitUntilIdle(); - SearchResultBaseView* result_view = GetSearchResultListViewItemAt(1); + SearchResultBaseView* result_view = + GetDefaultSearchResultListView()->GetResultViewAt(1); ASSERT_TRUE(result_view); ASSERT_TRUE(result_view->result()); ASSERT_EQ(kTestResultId, result_view->result()->id()); // Make sure the search results page is laid out after adding result action // buttons. - GetAppListView()->GetWidget()->LayoutRootViewIfNecessary(); + result_view->GetWidget()->LayoutRootViewIfNecessary(); // Long tap on the search result. This should show the removal confirmation // dialog. @@ -964,15 +1007,16 @@ ->app_list_client() ->GetAndClearInvokedResultActions() .empty()); - ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + ASSERT_TRUE(GetSearchResultPageDialog()); // Cancel the dialog - the app list should remain in the search result page, // the suggestion removal dialog should be hidden, and no result action should // be invoked. - GetSearchResultPageAnchoredDialog()->CancelDialog(); + GetSearchResultPageDialogDelegate()->CancelDialog(); - GetAppListTestHelper()->CheckState(AppListViewState::kHalf); - EXPECT_FALSE(search_result_page()->anchored_dialog_for_test()); + EXPECT_TRUE(AppListSearchResultPageVisible()); + EXPECT_FALSE(GetSearchResultPageDialog()); + EXPECT_TRUE(GetAppListTestHelper() ->app_list_client() ->GetAndClearInvokedResultActions() @@ -983,13 +1027,13 @@ LongPressAt(result_view->GetBoundsInScreen().CenterPoint()); // Expect the removal confirmation dialog - this time, accept it. - ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); - GetSearchResultPageAnchoredDialog()->AcceptDialog(); + ASSERT_TRUE(GetSearchResultPageDialog()); + GetSearchResultPageDialogDelegate()->AcceptDialog(); // The app list should remain showing search results, the dialog should be // closed, and result removal action should be invoked. - GetAppListTestHelper()->CheckState(AppListViewState::kHalf); - EXPECT_FALSE(search_result_page()->anchored_dialog_for_test()); + EXPECT_TRUE(AppListSearchResultPageVisible()); + EXPECT_FALSE(GetSearchResultPageDialog()); EXPECT_FALSE(result_view->selected()); std::vector<TestAppListClient::SearchResultActionId> expected_actions = { @@ -1018,13 +1062,14 @@ // Show remove suggestion dialog. LongPressAt(result_view->GetBoundsInScreen().CenterPoint()); - ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + ASSERT_TRUE(search_result_page()->dialog_for_test()); views::Widget* const confirmation_dialog = - search_result_page()->anchored_dialog_for_test()->widget(); + search_result_page()->dialog_for_test()->widget(); ASSERT_TRUE(confirmation_dialog); - SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog); + SanityCheckSearchResultsAnchoredDialogBounds( + confirmation_dialog, GetAppListView()->search_box_view()); const gfx::Rect initial_dialog_bounds = confirmation_dialog->GetWindowBoundsInScreen(); @@ -1033,7 +1078,7 @@ // Transition to fullscreen search state. GetAppListView()->SetState(AppListViewState::kFullscreenSearch); - ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + ASSERT_TRUE(search_result_page()->dialog_for_test()); EXPECT_NE(confirmation_dialog->GetLayer()->transform(), gfx::Transform()); EXPECT_EQ(confirmation_dialog->GetLayer()->GetTargetTransform(), @@ -1064,35 +1109,39 @@ // Show the remove suggestion dialog. LongPressAt(result_view->GetBoundsInScreen().CenterPoint()); - ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + ASSERT_TRUE(search_result_page()->dialog_for_test()); views::Widget* const confirmation_dialog = - search_result_page()->anchored_dialog_for_test()->widget(); + search_result_page()->dialog_for_test()->widget(); ASSERT_TRUE(confirmation_dialog); SCOPED_TRACE("Initial confirmation dialog bounds"); - SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog); + SanityCheckSearchResultsAnchoredDialogBounds( + confirmation_dialog, GetAppListView()->search_box_view()); const int dialog_margin = GetSearchResultsAnchoredDialogTopOffset(confirmation_dialog); // Transition to fullscreen search state. GetAppListView()->SetState(AppListViewState::kFullscreenSearch); - ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + ASSERT_TRUE(search_result_page()->dialog_for_test()); // Verify that the confirmation dialog followed the search box widget. SCOPED_TRACE("Confirmation dialog bounds after transition"); - SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog); + SanityCheckSearchResultsAnchoredDialogBounds( + confirmation_dialog, GetAppListView()->search_box_view()); EXPECT_EQ(dialog_margin, GetSearchResultsAnchoredDialogTopOffset(confirmation_dialog)); } -TEST_P(AppListPresenterTest, +TEST_P(AppListBubbleAndTabletTest, TransitionToAppsContainerClosesRemoveSuggestionDialog) { - GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); - GetAppListView()->SetState(AppListViewState::kFullscreenAllApps); + EnableTabletMode(tablet_mode_param()); + EnsureLauncherShown(); + + // Show search page. ui::test::EventGenerator* generator = GetEventGenerator(); - generator->GestureTapAt(GetPointInsideSearchbox()); - GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch); + generator->PressKey(ui::VKEY_A, 0); + EXPECT_TRUE(AppListSearchResultPageVisible()); // Add a zero state suggestion result. const std::string kTestResultId = "Test suggestion"; @@ -1100,7 +1149,8 @@ CreateOmniboxSuggestionResult(kTestResultId)); GetAppListTestHelper()->WaitUntilIdle(); - SearchResultBaseView* result_view = GetSearchResultListViewItemAt(0); + SearchResultBaseView* result_view = + GetDefaultSearchResultListView()->GetResultViewAt(0); ASSERT_TRUE(result_view); ASSERT_TRUE(result_view->result()); ASSERT_EQ(kTestResultId, result_view->result()->id()); @@ -1110,38 +1160,47 @@ ui::ET_GESTURE_LONG_PRESS, result_view->GetBoundsInScreen().CenterPoint(), base::TimeTicks::Now(), ui::PointerDetails(ui::EventPointerType::kTouch)); GetEventGenerator()->Dispatch(&long_press); - ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + ASSERT_TRUE(GetSearchResultPageDialog()); views::Widget* const confirmation_dialog = - search_result_page()->anchored_dialog_for_test()->widget(); + GetSearchResultPageDialog()->widget(); ASSERT_TRUE(confirmation_dialog); - SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog); + SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog, + GetSearchBoxView()); // Verify that transition to apps page hides the removal confirmation dialog. views::test::WidgetDestroyedWaiter widget_close_waiter(confirmation_dialog); - GetAppListView()->SetState(AppListViewState::kFullscreenAllApps); + GetSearchBoxView()->ClearSearchAndDeactivateSearchBox(); + EXPECT_FALSE(AppListSearchResultPageVisible()); widget_close_waiter.Wait(); } -TEST_P(AppListPresenterTest, RemoveSuggestionDialogBoundsUpdateWhenVKHidden) { +TEST_P(AppListBubbleAndTabletTest, + RemoveSuggestionDialogBoundsUpdateWhenVKHidden) { // Enable virtual keyboard for this test. KeyboardController* const keyboard_controller = Shell::Get()->keyboard_controller(); keyboard_controller->SetEnableFlag( keyboard::KeyboardEnableFlag::kCommandLineEnabled); - ShowZeroStateSearchInHalfState(); + EnableTabletMode(tablet_mode_param()); + EnsureLauncherShown(); - // Add a zero state suggestion result. + // Show search page. + ui::test::EventGenerator* generator = GetEventGenerator(); + generator->PressKey(ui::VKEY_A, 0); + EXPECT_TRUE(AppListSearchResultPageVisible()); + + // Add a suggestion result. const std::string kTestResultId = "Test suggestion"; GetSearchModel()->results()->Add( CreateOmniboxSuggestionResult(kTestResultId)); GetAppListTestHelper()->WaitUntilIdle(); - GetAppListView()->GetWidget()->LayoutRootViewIfNecessary(); - SearchResultBaseView* result_view = GetSearchResultListViewItemAt(0); + SearchResultBaseView* result_view = + GetDefaultSearchResultListView()->GetResultViewAt(0); ASSERT_TRUE(result_view); ASSERT_TRUE(result_view->result()); ASSERT_EQ(kTestResultId, result_view->result()->id()); @@ -1151,8 +1210,9 @@ ASSERT_TRUE(keyboard::WaitUntilShown()); // Show remove suggestion dialog. + result_view->GetWidget()->LayoutRootViewIfNecessary(); LongPressAt(result_view->GetBoundsInScreen().CenterPoint()); - ASSERT_TRUE(search_result_page()->anchored_dialog_for_test()); + ASSERT_TRUE(GetSearchResultPageDialog()); // The search box should have lost the focus, which should have hidden the // keyboard. @@ -1162,26 +1222,22 @@ // changed the position of the search box - the confirmation dialog should // have followed it). views::Widget* const confirmation_dialog = - search_result_page()->anchored_dialog_for_test()->widget(); - SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog); + GetSearchResultPageDialog()->widget(); + SanityCheckSearchResultsAnchoredDialogBounds(confirmation_dialog, + GetSearchBoxView()); views::test::WidgetDestroyedWaiter widget_close_waiter(confirmation_dialog); + GetSearchBoxView()->ClearSearchAndDeactivateSearchBox(); + EXPECT_FALSE(AppListSearchResultPageVisible()); + EXPECT_FALSE(keyboard_controller->IsKeyboardVisible()); - // Go to peeking state, and verify the keyboard is not reshown. - GetAppListView()->SetState(AppListViewState::kPeeking); - GetAppListTestHelper()->WaitUntilIdle(); // Exiting the search results page should close the dialog. widget_close_waiter.Wait(); - EXPECT_FALSE(keyboard_controller->IsKeyboardVisible()); - - GetAppListTestHelper()->DismissAndRunLoop(); - GetAppListTestHelper()->CheckVisibility(false); - EXPECT_FALSE(keyboard_controller->IsKeyboardVisible()); } // Verifies that the downward mouse drag on AppsGridView's first page should // be handled by AppList. -TEST_P(PopulatedAppListTest, MouseDragAppsGridViewHandledByAppList) { +TEST_F(PopulatedAppListTest, MouseDragAppsGridViewHandledByAppList) { InitializeAppsGrid(); PopulateApps(2); @@ -1205,7 +1261,7 @@ // Verifies that the upward mouse drag on AppsGridView's first page should // be handled by PaginationController. -TEST_P(PopulatedAppListTest, +TEST_F(PopulatedAppListTest, MouseDragAppsGridViewHandledByPaginationController) { InitializeAppsGrid(); PopulateApps(apps_grid_test_api_->TilesPerPage(0) + 1); @@ -1238,7 +1294,7 @@ // Tests that mouse app list item drag is cancelled when mouse capture is lost // (e.g. on screen rotation). -TEST_P(PopulatedAppListTest, CancelItemDragOnMouseCaptureLoss) { +TEST_F(PopulatedAppListTest, CancelItemDragOnMouseCaptureLoss) { InitializeAppsGrid(); PopulateApps(apps_grid_test_api_->TilesPerPage(0) + 1); @@ -1272,7 +1328,7 @@ // Tests that app list item drag gets canceled if the dragged app list item gets // deleted. -TEST_P(PopulatedAppListTest, CancelItemDragOnDragItemDeletion) { +TEST_F(PopulatedAppListTest, CancelItemDragOnDragItemDeletion) { InitializeAppsGrid(); PopulateApps(4); @@ -1307,7 +1363,7 @@ // Tests that app list item drag in folder gets canceled if the dragged app list // item gets deleted. -TEST_P(PopulatedAppListTest, CancelFolderItemDragOnDragItemDeletion) { +TEST_F(PopulatedAppListTest, CancelFolderItemDragOnDragItemDeletion) { InitializeAppsGrid(); PopulateApps(2); AppListFolderItem* folder = CreateAndPopulateFolderWithApps(3); @@ -1353,7 +1409,7 @@ // Tests that app list item drag from folder to root apps grid gets canceled if // the dragged app list item gets deleted. -TEST_P(PopulatedAppListTest, CancelFolderItemReparentDragOnDragItemDeletion) { +TEST_F(PopulatedAppListTest, CancelFolderItemReparentDragOnDragItemDeletion) { InitializeAppsGrid(); PopulateApps(2); AppListFolderItem* folder = CreateAndPopulateFolderWithApps(3); @@ -1411,7 +1467,7 @@ helper->DismissAndRunLoop(); } -TEST_P(PopulatedAppListTest, +TEST_F(PopulatedAppListTest, CancelFolderItemReparentDragOnDragItemAndFolderDeletion) { InitializeAppsGrid(); PopulateApps(2); @@ -1472,7 +1528,7 @@ // Tests that apps grid item layers are not destroyed immediately after item // drag ends. -TEST_P(PopulatedAppListTest, +TEST_F(PopulatedAppListTest, ItemLayersNotDestroyedDuringBoundsAnimationAfterDrag) { InitializeAppsGrid(); const int kItemCount = 5; @@ -1518,7 +1574,7 @@ // Tests that apps grid item drag operation can continue normally after display // rotation (and app list config change). -TEST_P(PopulatedAppListTest, ScreenRotationDuringAppsGridItemDrag) { +TEST_F(PopulatedAppListTest, ScreenRotationDuringAppsGridItemDrag) { // Set the display dimensions so rotation also changes the app list config. UpdateDisplay("1200x600"); @@ -1563,7 +1619,7 @@ // Tests screen rotation during apps grid item drag where the drag item ends up // in page-scroll area. Tests that the apps grid page scrolls without a crash, // and that releasing drag does not change the item position in the model. -TEST_P(PopulatedAppListTest, +TEST_F(PopulatedAppListTest, ScreenRotationDuringAppsGridItemDragWithPageScroll) { // Set the display dimensions so rotation also changes the app list config. UpdateDisplay("1200x600"); @@ -1606,7 +1662,7 @@ // Tests screen rotation while app list folder item is in progress, and the item // remains in the folder bounds during the drag. -TEST_P(PopulatedAppListTest, ScreenRotationDuringFolderItemDrag) { +TEST_F(PopulatedAppListTest, ScreenRotationDuringFolderItemDrag) { // Set the display dimensions so rotation also changes the app list config. UpdateDisplay("1200x600"); @@ -1657,7 +1713,7 @@ // Tests that app list folder item reparenting drag (where a folder item is // dragged outside the folder bounds, and dropped within the apps grid) can // continue normally after screen rotation. -TEST_P(PopulatedAppListTest, ScreenRotationDuringAppsGridItemReparentDrag) { +TEST_F(PopulatedAppListTest, ScreenRotationDuringAppsGridItemReparentDrag) { UpdateDisplay("1200x600"); InitializeAppsGrid(); @@ -1768,7 +1824,7 @@ // Tests that an item can be removed just after creating a folder that contains // that item. See https://crbug.com/1083942 -TEST_P(PopulatedAppListTest, RemoveFolderItemAfterFolderCreation) { +TEST_F(PopulatedAppListTest, RemoveFolderItemAfterFolderCreation) { InitializeAppsGrid(); const int kItemCount = 5; PopulateApps(kItemCount); @@ -1833,7 +1889,7 @@ apps_grid_view_->GetWidget()->LayoutRootViewIfNecessary(); } -TEST_P(PopulatedAppListWithVKEnabledTest, +TEST_F(PopulatedAppListWithVKEnabledTest, TappingAppsGridClosesVirtualKeyboard) { InitializeAppsGrid(); PopulateApps(2); @@ -1876,7 +1932,7 @@ // Tests that a folder item that is dragged to the page flip area and released // will discard empty pages in the apps grid. If an empty page is not discarded, // the apps grid crashes (See http://crbug.com/1100011). -TEST_P(PopulatedAppListTest, FolderItemDroppedRemovesBlankPage) { +TEST_F(PopulatedAppListTest, FolderItemDroppedRemovesBlankPage) { InitializeAppsGrid(); AppListFolderItem* folder_item = CreateAndPopulateFolderWithApps(3); PopulateApps(2); @@ -3905,7 +3961,7 @@ // Tests that the touch selection menu created when tapping an open folder's // folder name view be interacted with. -TEST_P(PopulatedAppListTest, TouchSelectionMenu) { +TEST_F(PopulatedAppListTest, TouchSelectionMenu) { InitializeAppsGrid(); AppListFolderItem* folder_item = CreateAndPopulateFolderWithApps(4); @@ -4015,12 +4071,10 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -// Instantiate the values in the parameterized tests. First boolean is used to +// Instantiate the values in the parameterized tests. Used to // toggle mouse and touch events and in some tests to toggle fullscreen mode // tests. The second one toggles cardfied state feature enabled or disabled. -INSTANTIATE_TEST_SUITE_P(All, - AppListPresenterLayoutTest, - testing::Combine(testing::Bool(), testing::Bool())); +INSTANTIATE_TEST_SUITE_P(All, AppListPresenterLayoutTest, testing::Bool()); // Tests that the app list contents top margin is gradually updated during drag // between peeking and fullscreen view state while showing apps page. @@ -4417,21 +4471,10 @@ } // Test a variety of behaviors for home launcher (app list in tablet mode). -class AppListPresenterHomeLauncherTest - : public AshTestBase, - public testing::WithParamInterface<bool> { +class AppListPresenterHomeLauncherTest : public AshTestBase { public: AppListPresenterHomeLauncherTest() { - if (GetParam()) { - scoped_feature_list_.InitWithFeatures( - {features::kEnableBackgroundBlur, - app_list_features::kNewDragSpecInLauncher}, - {}); - } else { - scoped_feature_list_.InitWithFeatures( - {features::kEnableBackgroundBlur}, - {app_list_features::kNewDragSpecInLauncher}); - } + scoped_feature_list_.InitAndEnableFeature(features::kEnableBackgroundBlur); } AppListPresenterHomeLauncherTest(const AppListPresenterHomeLauncherTest&) = delete; @@ -4512,14 +4555,8 @@ std::unique_ptr<WallpaperControllerTestApi> wallpaper_test_api_; }; -// Instantiate the Boolean which is used to toggle cardified state in the -// parameterized tests. -INSTANTIATE_TEST_SUITE_P(All, - AppListPresenterHomeLauncherTest, - testing::Bool()); - // Verifies that mouse dragging AppListView is enabled. -TEST_P(AppListPresenterHomeLauncherTest, MouseDragAppList) { +TEST_F(AppListPresenterHomeLauncherTest, MouseDragAppList) { std::unique_ptr<AppListItem> item(new AppListItem("fake id")); GetAppListModel()->AddItem(std::move(item)); @@ -4549,7 +4586,7 @@ // Verifies that mouse dragging AppListView creates layers, causes to change the // opacity, and destroys the layers when done. -TEST_P(AppListPresenterHomeLauncherTest, MouseDragAppListItemOpacity) { +TEST_F(AppListPresenterHomeLauncherTest, MouseDragAppListItemOpacity) { const int items_in_page = SharedAppListConfig::instance().GetMaxNumOfItemsPerPage(); for (int i = 0; i < items_in_page; ++i) { @@ -4611,7 +4648,7 @@ // Tests that ending of the mouse dragging of app-list destroys the layers for // the items which are in the second page. See https://crbug.com/990529. -TEST_P(AppListPresenterHomeLauncherTest, LayerOnSecondPage) { +TEST_F(AppListPresenterHomeLauncherTest, LayerOnSecondPage) { const int items_in_page = SharedAppListConfig::instance().GetMaxNumOfItemsPerPage(); AppListModel* model = GetAppListModel(); @@ -4687,7 +4724,7 @@ // Tests that the app list is shown automatically when the tablet mode is on. // The app list is dismissed when the tablet mode is off. -TEST_P(AppListPresenterHomeLauncherTest, ShowAppListForTabletMode) { +TEST_F(AppListPresenterHomeLauncherTest, ShowAppListForTabletMode) { GetAppListTestHelper()->CheckVisibility(false); // Turns on tablet mode. @@ -4701,7 +4738,7 @@ // Tests that the app list window's parent is changed after entering tablet // mode. -TEST_P(AppListPresenterHomeLauncherTest, ParentWindowContainer) { +TEST_F(AppListPresenterHomeLauncherTest, ParentWindowContainer) { // Show app list in non-tablet mode. The window container should be // kShellWindowId_AppListContainer. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); @@ -4718,7 +4755,7 @@ } // Tests that the background opacity change for app list. -TEST_P(AppListPresenterHomeLauncherTest, BackgroundOpacity) { +TEST_F(AppListPresenterHomeLauncherTest, BackgroundOpacity) { // Show app list in non-tablet mode. The background shield opacity should be // 70%. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); @@ -4753,7 +4790,7 @@ // Tests that the background blur which is present in clamshell mode does not // show in tablet mode. -TEST_P(AppListPresenterHomeLauncherTest, BackgroundBlur) { +TEST_F(AppListPresenterHomeLauncherTest, BackgroundBlur) { // Show app list in non-tablet mode. The background blur should be enabled. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); EXPECT_GT(GetAppListView() @@ -4771,7 +4808,7 @@ } // Tests that tapping or clicking on background cannot dismiss the app list. -TEST_P(AppListPresenterHomeLauncherTest, TapOrClickToDismiss) { +TEST_F(AppListPresenterHomeLauncherTest, TapOrClickToDismiss) { // Show app list in non-tablet mode. Click outside search box. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); GetAppListTestHelper()->CheckVisibility(true); @@ -4802,7 +4839,7 @@ GetAppListTestHelper()->CheckVisibility(true); } -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, EscapeKeyInNonTabletModeClosesLauncher) { ShowAppList(); EXPECT_TRUE(IsAppListVisible()); @@ -4812,7 +4849,7 @@ EXPECT_FALSE(IsAppListVisible()); } -TEST_P(AppListPresenterHomeLauncherTest, BackKeyInNonTabletModeClosesLauncher) { +TEST_F(AppListPresenterHomeLauncherTest, BackKeyInNonTabletModeClosesLauncher) { ShowAppList(); EXPECT_TRUE(IsAppListVisible()); @@ -4821,7 +4858,7 @@ EXPECT_FALSE(IsAppListVisible()); } -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, SearchKeyInNonTabletModeClosesLauncher) { ShowAppList(); EXPECT_TRUE(IsAppListVisible()); @@ -4831,7 +4868,7 @@ EXPECT_FALSE(IsAppListVisible()); } -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, EscapeKeyInTabletModeDoesNotCloseLauncher) { EnableTabletMode(true); EXPECT_TRUE(IsAppListVisible()); @@ -4841,7 +4878,7 @@ EXPECT_TRUE(IsAppListVisible()); } -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, BackKeyInTabletModeDoesNotCloseLauncher) { EnableTabletMode(true); EXPECT_TRUE(IsAppListVisible()); @@ -4851,7 +4888,7 @@ EXPECT_TRUE(IsAppListVisible()); } -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, SearchKeyInTabletModeDoesNotCloseLauncher) { EnableTabletMode(true); EXPECT_TRUE(IsAppListVisible()); @@ -4862,7 +4899,7 @@ } // Tests that moving focus outside app list window can dismiss it. -TEST_P(AppListPresenterHomeLauncherTest, FocusOutToDismiss) { +TEST_F(AppListPresenterHomeLauncherTest, FocusOutToDismiss) { // Show app list in non-tablet mode. Move focus to another window. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); GetAppListTestHelper()->CheckVisibility(true); @@ -4891,7 +4928,7 @@ } // Tests that the gesture-scroll cannot dismiss the app list. -TEST_P(AppListPresenterHomeLauncherTest, GestureScrollToDismiss) { +TEST_F(AppListPresenterHomeLauncherTest, GestureScrollToDismiss) { // Show app list in non-tablet mode. Fling down. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); GetAppListTestHelper()->CheckVisibility(true); @@ -4907,7 +4944,7 @@ GetAppListTestHelper()->CheckVisibility(true); } -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, MouseScrollUpFromPeekingShowsFullscreenLauncher) { // Show app list in non-tablet mode. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); @@ -4926,7 +4963,7 @@ EXPECT_TRUE(app_list->IsVisible()); } -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, MouseScrollDownFromPeekingClosesLauncher) { // Show app list in non-tablet mode. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); @@ -4945,7 +4982,7 @@ } // Tests that mouse-scroll up at fullscreen will dismiss app list. -TEST_P(AppListPresenterHomeLauncherTest, MouseScrollToDismissFromFullscreen) { +TEST_F(AppListPresenterHomeLauncherTest, MouseScrollToDismissFromFullscreen) { // Show app list in non-tablet mode. Mouse-scroll down. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); GetAppListTestHelper()->CheckState(AppListViewState::kPeeking); @@ -4968,7 +5005,7 @@ // Test that the AppListView opacity is reset after it is hidden during the // overview mode animation. -TEST_P(AppListPresenterHomeLauncherTest, LauncherShowsAfterOverviewMode) { +TEST_F(AppListPresenterHomeLauncherTest, LauncherShowsAfterOverviewMode) { // Show the AppList in clamshell mode. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId()); GetAppListTestHelper()->CheckVisibility(true); @@ -4992,7 +5029,7 @@ // Tests that tapping home button while home screen is visible and showing // search results moves the home screen to apps container page. -TEST_P(AppListPresenterHomeLauncherTest, HomeButtonDismissesSearchResults) { +TEST_F(AppListPresenterHomeLauncherTest, HomeButtonDismissesSearchResults) { // Show app list in tablet mode. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5017,7 +5054,7 @@ } // Tests the app list opacity in overview mode. -TEST_P(AppListPresenterHomeLauncherTest, OpacityInOverviewMode) { +TEST_F(AppListPresenterHomeLauncherTest, OpacityInOverviewMode) { // Show app list in tablet mode. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5035,13 +5072,13 @@ EXPECT_EQ(1.0f, layer->opacity()); } -TEST_P(AppListPresenterHomeLauncherTest, AppListHiddenDuringWallpaperPreview) { +TEST_F(AppListPresenterHomeLauncherTest, AppListHiddenDuringWallpaperPreview) { EnableTabletMode(true); wallpaper_test_api_->StartWallpaperPreview(); GetAppListTestHelper()->CheckVisibility(false); } -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, AppListShownAfterWallpaperPreviewConfirmed) { EnableTabletMode(true); wallpaper_test_api_->StartWallpaperPreview(); @@ -5049,7 +5086,7 @@ GetAppListTestHelper()->CheckVisibility(true); } -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, AppListShownAfterWallpaperPreviewCanceled) { EnableTabletMode(true); wallpaper_test_api_->StartWallpaperPreview(); @@ -5057,7 +5094,7 @@ GetAppListTestHelper()->CheckVisibility(true); } -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, AppListShownAfterWallpaperPreviewAndExitOverviewMode) { EnableTabletMode(true); wallpaper_test_api_->StartWallpaperPreview(); @@ -5070,7 +5107,7 @@ } // Tests that going home will minimize all windows. -TEST_P(AppListPresenterHomeLauncherTest, GoingHomeMinimizesAllWindows) { +TEST_F(AppListPresenterHomeLauncherTest, GoingHomeMinimizesAllWindows) { // Show app list in tablet mode. Maximize all windows. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5107,7 +5144,7 @@ } // Tests that going home will end split view mode. -TEST_P(AppListPresenterHomeLauncherTest, GoingHomeEndsSplitViewMode) { +TEST_F(AppListPresenterHomeLauncherTest, GoingHomeEndsSplitViewMode) { // Show app list in tablet mode. Enter split view mode. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5121,7 +5158,7 @@ } // Tests that going home will end overview mode. -TEST_P(AppListPresenterHomeLauncherTest, GoingHomeEndOverviewMode) { +TEST_F(AppListPresenterHomeLauncherTest, GoingHomeEndOverviewMode) { // Show app list in tablet mode. Enter overview mode. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5137,7 +5174,7 @@ // Tests that going home will end overview and split view mode if both are // active (e.g. one side of the split view contains overview). -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, GoingHomeEndsSplitViewModeWithOverview) { // Show app list in tablet mode. Enter split view mode. EnableTabletMode(true); @@ -5163,7 +5200,7 @@ // Tests that the context menu is triggered in the same way as if we are on // the wallpaper. -TEST_P(AppListPresenterHomeLauncherTest, WallpaperContextMenu) { +TEST_F(AppListPresenterHomeLauncherTest, WallpaperContextMenu) { // Show app list in tablet mode. EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5206,7 +5243,7 @@ // Tests app list visibility when switching to tablet mode during dragging from // shelf. -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, SwitchToTabletModeDuringDraggingFromShelf) { UpdateDisplay("1080x900"); GetAppListTestHelper()->CheckVisibility(false); @@ -5249,7 +5286,7 @@ // Tests app list visibility when switching to tablet mode during dragging to // close app list. -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, SwitchToTabletModeDuringDraggingToClose) { UpdateDisplay("1080x900"); @@ -5286,7 +5323,7 @@ } // Test backdrop exists for active non-fullscreen window in tablet mode. -TEST_P(AppListPresenterHomeLauncherTest, BackdropTest) { +TEST_F(AppListPresenterHomeLauncherTest, BackdropTest) { WorkspaceControllerTestApi test_helper(ShellTestApi().workspace_controller()); EnableTabletMode(true); GetAppListTestHelper()->CheckVisibility(true); @@ -5301,7 +5338,7 @@ // Tests that app list is not active when switching to tablet mode if an active // window exists. -TEST_P(AppListPresenterHomeLauncherTest, +TEST_F(AppListPresenterHomeLauncherTest, NotActivateAppListWindowWhenActiveWindowExists) { // No window is active. EXPECT_EQ(nullptr, window_util::GetActiveWindow()); @@ -5351,12 +5388,12 @@ } }; -// Instantiate the values in the parameterized tests. First boolean is used to +// Instantiate the values in the parameterized tests. Used to // toggle mouse and touch events and in some tests to toggle fullscreen mode -// tests. The second one toggles cardfied state feature enabled or disabled. +// tests. INSTANTIATE_TEST_SUITE_P(All, AppListPresenterVirtualKeyboardTest, - testing::Combine(testing::Bool(), testing::Bool())); + testing::Bool()); // Tests that tapping or clicking the body of the applist with an active virtual // keyboard when there exists text in the searchbox results in the virtual @@ -5424,7 +5461,7 @@ EXPECT_FALSE(GetAppListView()->search_box_view()->is_search_box_active()); } -TEST_P(AppListPresenterHomeLauncherTest, TapHomeButtonOnExternalDisplay) { +TEST_F(AppListPresenterHomeLauncherTest, TapHomeButtonOnExternalDisplay) { UpdateDisplay("800x600,1000x768"); TapHomeButton(GetSecondaryDisplay().id());
diff --git a/ash/app_list/app_list_test_view_delegate.cc b/ash/app_list/app_list_test_view_delegate.cc index 026031a..e3dafa9 100644 --- a/ash/app_list/app_list_test_view_delegate.cc +++ b/ash/app_list/app_list_test_view_delegate.cc
@@ -56,6 +56,7 @@ switch (launched_from) { case ash::AppListLaunchedFrom::kLaunchedFromSearchBox: case ash::AppListLaunchedFrom::kLaunchedFromSuggestionChip: + case ash::AppListLaunchedFrom::kLaunchedFromRecentApps: RecordAppLaunched(launched_from); return; case ash::AppListLaunchedFrom::kLaunchedFromGrid: @@ -108,6 +109,7 @@ void AppListTestViewDelegate::GetContextMenuModel( const std::string& id, + bool add_sort_options, GetContextMenuModelCallback callback) { AppListItem* item = model_->FindItem(id); // TODO(stevenjb/jennyz): Implement this for folder items
diff --git a/ash/app_list/app_list_test_view_delegate.h b/ash/app_list/app_list_test_view_delegate.h index b3051649..8b2d045f 100644 --- a/ash/app_list/app_list_test_view_delegate.h +++ b/ash/app_list/app_list_test_view_delegate.h
@@ -85,6 +85,7 @@ int event_flags, ash::AppListLaunchedFrom launched_from) override; void GetContextMenuModel(const std::string& id, + bool add_sort_options, GetContextMenuModelCallback callback) override; ui::ImplicitAnimationObserver* GetAnimationObserver( ash::AppListViewState target_state) override;
diff --git a/ash/app_list/app_list_view_delegate.h b/ash/app_list/app_list_view_delegate.h index 773fc78..af3c049 100644 --- a/ash/app_list/app_list_view_delegate.h +++ b/ash/app_list/app_list_view_delegate.h
@@ -99,8 +99,11 @@ // Returns the context menu model for a ChromeAppListItem with |id|, or // nullptr if there is currently no menu for the item (e.g. during install). - // Note the returned menu model is owned by that item. + // Requests the menu model to include sort options that can sort the app list + // if `add_sort_options` is true. Note the returned menu model is owned by + // that item. virtual void GetContextMenuModel(const std::string& id, + bool add_sort_options, GetContextMenuModelCallback callback) = 0; // Returns an animation observer if the |target_state| is interesting to the
diff --git a/ash/app_list/test/app_list_test_helper.cc b/ash/app_list/test/app_list_test_helper.cc index d987e90..d6c83e4 100644 --- a/ash/app_list/test/app_list_test_helper.cc +++ b/ash/app_list/test/app_list_test_helper.cc
@@ -21,6 +21,7 @@ #include "ash/app_list/views/apps_container_view.h" #include "ash/app_list/views/contents_view.h" #include "ash/app_list/views/productivity_launcher_search_view.h" +#include "ash/app_list/views/search_result_page_dialog_controller.h" #include "ash/app_list/views/search_result_page_view.h" #include "ash/constants/ash_features.h" #include "ash/shell.h" @@ -184,6 +185,15 @@ return GetAppsContainerView()->GetSeparatorView(); } +SearchResultPageAnchoredDialog* +AppListTestHelper::GetFullscreenSearchPageDialog() { + return GetAppListView() + ->app_list_main_view() + ->contents_view() + ->search_result_page_view() + ->dialog_for_test(); +} + AppListBubbleView* AppListTestHelper::GetBubbleView() { return app_list_controller_->bubble_presenter_for_test() ->bubble_view_for_test(); @@ -225,6 +235,11 @@ ->search_page_; } +SearchResultPageAnchoredDialog* AppListTestHelper::GetBubbleSearchPageDialog() { + return app_list_controller_->bubble_presenter_for_test() + ->bubble_view_for_test() + ->search_page_dialog_controller_->dialog(); +} AppListBubbleAssistantPage* AppListTestHelper::GetBubbleAssistantPage() { return app_list_controller_->bubble_presenter_for_test() ->bubble_view_for_test()
diff --git a/ash/app_list/test/app_list_test_helper.h b/ash/app_list/test/app_list_test_helper.h index c70d9df2..4bb6dd5 100644 --- a/ash/app_list/test/app_list_test_helper.h +++ b/ash/app_list/test/app_list_test_helper.h
@@ -19,6 +19,7 @@ namespace ash { +class SearchResultPageAnchoredDialog; class AppListBubbleAppsPage; class AppListBubbleAssistantPage; class AppListBubbleSearchPage; @@ -107,6 +108,7 @@ AppListFolderView* GetFullscreenFolderView(); RecentAppsView* GetFullscreenRecentAppsView(); ContinueSectionView* GetFullscreenContinueSectionView(); + SearchResultPageAnchoredDialog* GetFullscreenSearchPageDialog(); ProductivityLauncherSearchView* GetProductivityLauncherSearchView(); views::View* GetFullscreenLauncherAppsSeparatorView(); @@ -122,6 +124,7 @@ RecentAppsView* GetBubbleRecentAppsView(); ScrollableAppsGridView* GetScrollableAppsGridView(); AppListBubbleSearchPage* GetBubbleSearchPage(); + SearchResultPageAnchoredDialog* GetBubbleSearchPageDialog(); AppListBubbleAssistantPage* GetBubbleAssistantPage(); SearchModel::SearchResults* GetSearchResults(); views::View* GetBubbleLauncherAppsSeparatorView();
diff --git a/ash/app_list/test_app_list_client.cc b/ash/app_list/test_app_list_client.cc index 930e3784..740e643 100644 --- a/ash/app_list/test_app_list_client.cc +++ b/ash/app_list/test_app_list_client.cc
@@ -53,6 +53,7 @@ void TestAppListClient::GetContextMenuModel( int profile_id, const std::string& id, + bool add_sort_options, GetContextMenuModelCallback callback) { auto model = std::make_unique<ui::SimpleMenuModel>(/*delegate=*/nullptr); model->AddItem(/*command_id=*/0, u"Menu item");
diff --git a/ash/app_list/test_app_list_client.h b/ash/app_list/test_app_list_client.h index 12d2cdd..74cc820 100644 --- a/ash/app_list/test_app_list_client.h +++ b/ash/app_list/test_app_list_client.h
@@ -49,6 +49,7 @@ int event_flags) override; void GetContextMenuModel(int profile_id, const std::string& id, + bool add_sort_options, GetContextMenuModelCallback callback) override; void OnAppListVisibilityWillChange(bool visible) override {} void OnAppListVisibilityChanged(bool visible) override {}
diff --git a/ash/app_list/views/app_list_bubble_search_page.cc b/ash/app_list/views/app_list_bubble_search_page.cc index 3b4ebbc..b6074a6 100644 --- a/ash/app_list/views/app_list_bubble_search_page.cc +++ b/ash/app_list/views/app_list_bubble_search_page.cc
@@ -4,6 +4,8 @@ #include "ash/app_list/views/app_list_bubble_search_page.h" +#include <memory> + #include "ash/app_list/views/productivity_launcher_search_view.h" #include "ui/views/layout/fill_layout.h" @@ -11,10 +13,11 @@ AppListBubbleSearchPage::AppListBubbleSearchPage( AppListViewDelegate* view_delegate, + SearchResultPageDialogController* dialog_controller, SearchBoxView* search_box_view) { SetLayoutManager(std::make_unique<views::FillLayout>()); search_view_ = AddChildView(std::make_unique<ProductivityLauncherSearchView>( - view_delegate, search_box_view)); + view_delegate, dialog_controller, search_box_view)); } AppListBubbleSearchPage::~AppListBubbleSearchPage() = default;
diff --git a/ash/app_list/views/app_list_bubble_search_page.h b/ash/app_list/views/app_list_bubble_search_page.h index 9ae9ba1..eb27310 100644 --- a/ash/app_list/views/app_list_bubble_search_page.h +++ b/ash/app_list/views/app_list_bubble_search_page.h
@@ -13,6 +13,7 @@ class AppListViewDelegate; class ProductivityLauncherSearchView; class SearchBoxView; +class SearchResultPageDialogController; // The search results page for the app list bubble / clamshell launcher. // Contains a scrolling list of search results. Does not include the search box, @@ -20,6 +21,7 @@ class ASH_EXPORT AppListBubbleSearchPage : public views::View { public: AppListBubbleSearchPage(AppListViewDelegate* view_delegate, + SearchResultPageDialogController* dialog_controller, SearchBoxView* search_box_view); AppListBubbleSearchPage(const AppListBubbleSearchPage&) = delete; AppListBubbleSearchPage& operator=(const AppListBubbleSearchPage&) = delete;
diff --git a/ash/app_list/views/app_list_bubble_view.cc b/ash/app_list/views/app_list_bubble_view.cc index d89b841..db69bf8 100644 --- a/ash/app_list/views/app_list_bubble_view.cc +++ b/ash/app_list/views/app_list_bubble_view.cc
@@ -21,6 +21,7 @@ #include "ash/app_list/views/productivity_launcher_search_view.h" #include "ash/app_list/views/scrollable_apps_grid_view.h" #include "ash/app_list/views/search_box_view.h" +#include "ash/app_list/views/search_result_page_dialog_controller.h" #include "ash/keyboard/ui/keyboard_ui_controller.h" #include "ash/public/cpp/app_list/app_list_config_provider.h" #include "ash/public/cpp/metrics_util.h" @@ -160,6 +161,7 @@ // Show the assistant button until the user types text. params.show_close_button_when_active = false; params.create_background = false; + params.animate_changing_search_icon = false; search_box_view_->Init(params); // The main view has a solid color layer, so the separator needs its own @@ -177,9 +179,12 @@ // include empty space below the visible icons. layout->SetFlexForView(apps_page_, 1); + search_page_dialog_controller_ = + std::make_unique<SearchResultPageDialogController>(this); search_page_ = contents->AddChildView(std::make_unique<AppListBubbleSearchPage>( - view_delegate_, search_box_view_)); + view_delegate_, search_page_dialog_controller_.get(), + search_box_view_)); search_page_->SetVisible(false); } @@ -315,6 +320,7 @@ apps_page_->SetVisible(false); search_page_->SetVisible(false); + search_page_dialog_controller_->SetEnabled(false); assistant_page_->SetVisible(true); assistant_page_->RequestFocus(); } @@ -375,6 +381,7 @@ const bool has_search = search_box_view_->HasSearch(); apps_page_->SetVisible(!has_search); search_page_->SetVisible(has_search); + search_page_dialog_controller_->SetEnabled(has_search); assistant_page_->SetVisible(false); // Ask the controller to start the search.
diff --git a/ash/app_list/views/app_list_bubble_view.h b/ash/app_list/views/app_list_bubble_view.h index 9929dfc..fc158f68 100644 --- a/ash/app_list/views/app_list_bubble_view.h +++ b/ash/app_list/views/app_list_bubble_view.h
@@ -25,6 +25,7 @@ class AppListViewDelegate; class FolderBackgroundView; class SearchBoxView; +class SearchResultPageDialogController; // Contains the views for the bubble version of the launcher. It looks like a // system tray bubble. It does not derive from TrayBubbleView because it takes @@ -106,7 +107,13 @@ void DisableFocusForShowingActiveFolder(bool disabled); AppListViewDelegate* const view_delegate_; + std::unique_ptr<AppListA11yAnnouncer> a11y_announcer_; + + // Controller for showing a modal dialog in search results page. + std::unique_ptr<SearchResultPageDialogController> + search_page_dialog_controller_; + SearchBoxView* search_box_view_ = nullptr; views::View* separator_ = nullptr; AppListBubbleAppsPage* apps_page_ = nullptr;
diff --git a/ash/app_list/views/app_list_bubble_view_unittest.cc b/ash/app_list/views/app_list_bubble_view_unittest.cc index 8592d84..b5db74d 100644 --- a/ash/app_list/views/app_list_bubble_view_unittest.cc +++ b/ash/app_list/views/app_list_bubble_view_unittest.cc
@@ -214,7 +214,7 @@ // Check the bounds of the search box search icon. auto* search_box_view = GetSearchBoxView(); - auto* search_icon = search_box_view->get_search_icon_for_test(); + auto* search_icon = search_box_view->search_icon(); gfx::Rect search_icon_bounds = search_icon->ConvertRectToWidget(search_icon->GetLocalBounds()); EXPECT_EQ("16,16 24x24", search_icon_bounds.ToString());
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc index a54c9dd7..8aa51bc 100644 --- a/ash/app_list/views/app_list_item_view.cc +++ b/ash/app_list/views/app_list_item_view.cc
@@ -678,6 +678,11 @@ view_delegate_->IsInTabletMode()); context_menu_->Run(anchor_rect, views::MenuAnchorPosition::kBubbleRight, run_types); + + if (!context_menu_shown_callback_.is_null()) { + context_menu_shown_callback_.Run(); + } + grid_delegate_->SetSelectedView(this); } @@ -694,8 +699,14 @@ if (waiting_for_context_menu_options_) return; waiting_for_context_menu_options_ = true; + + // If this item view is in the AppsGridView with the app sort feature enabled, + // request the context menu model to add sort options that can sort the app + // list. + bool add_sort_options = features::IsLauncherAppSortEnabled() && + context_ == Context::kAppsGridView; view_delegate_->GetContextMenuModel( - item_weak_->id(), + item_weak_->id(), add_sort_options, base::BindOnce(&AppListItemView::OnContextMenuModelReceived, weak_ptr_factory_.GetWeakPtr(), point, source_type)); } @@ -998,6 +1009,11 @@ return notification_indicator_ && notification_indicator_->GetVisible(); } +void AppListItemView::SetContextMenuShownCallbackForTest( + base::RepeatingClosure closure) { + context_menu_shown_callback_ = std::move(closure); +} + void AppListItemView::AnimationProgressed(const gfx::Animation* animation) { DCHECK(!is_folder_);
diff --git a/ash/app_list/views/app_list_item_view.h b/ash/app_list/views/app_list_item_view.h index d7d55fa..89a47f55 100644 --- a/ash/app_list/views/app_list_item_view.h +++ b/ash/app_list/views/app_list_item_view.h
@@ -216,6 +216,11 @@ bool IsNotificationIndicatorShownForTest() const; GridDelegate* grid_delegate_for_test() { return grid_delegate_; } + AppListMenuModelAdapter* context_menu() const { return context_menu_.get(); } + + // Sets the callback which will run after the context menu is shown. + void SetContextMenuShownCallbackForTest(base::RepeatingClosure closure); + private: friend class test::AppsGridViewTest; friend class test::AppListMainViewTest; @@ -423,6 +428,9 @@ // Helper to trigger icon load. absl::optional<AppIconLoadHelper> icon_load_helper_; + // Called when the context menu is shown. + base::RepeatingClosure context_menu_shown_callback_; + base::WeakPtrFactory<AppListItemView> weak_ptr_factory_{this}; };
diff --git a/ash/app_list/views/app_list_main_view_unittest.cc b/ash/app_list/views/app_list_main_view_unittest.cc index 337cfd0..d90cd4c 100644 --- a/ash/app_list/views/app_list_main_view_unittest.cc +++ b/ash/app_list/views/app_list_main_view_unittest.cc
@@ -42,8 +42,7 @@ } // namespace -class AppListMainViewTest : public views::ViewsTestBase, - public testing::WithParamInterface<bool> { +class AppListMainViewTest : public views::ViewsTestBase { public: AppListMainViewTest() = default; AppListMainViewTest(const AppListMainViewTest& other) = delete; @@ -56,11 +55,6 @@ zero_duration_mode_ = std::make_unique<ui::ScopedAnimationDurationScaleMode>( ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); - // Allow TEST_F for tests that don't need to be parameterized. - if (testing::UnitTest::GetInstance()->current_test_info()->value_param()) { - feature_list_.InitWithFeatureState( - app_list_features::kNewDragSpecInLauncher, GetParam()); - } // Create, and show the app list is fullscreen apps grid state. delegate_ = std::make_unique<AppListTestViewDelegate>(); @@ -230,8 +224,6 @@ return dragged; } - bool IsPaginationPreviewActive() { return GetParam(); } - void PressKeyInSearchBox(ui::KeyboardCode key_code) { ui::KeyEvent press(ui::ET_KEY_PRESSED, key_code, ui::EF_NONE); search_box_view()->search_box()->OnKeyEvent(&press); @@ -249,12 +241,9 @@ std::unique_ptr<AppListTestViewDelegate> delegate_; private: - base::test::ScopedFeatureList feature_list_; std::unique_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_; }; -INSTANTIATE_TEST_SUITE_P(All, AppListMainViewTest, testing::Bool()); - // Tests that the close button becomes invisible after close button is clicked. TEST_F(AppListMainViewTest, CloseButtonInvisibleAfterCloseButtonClicked) { PressKeyInSearchBox(ui::VKEY_A); @@ -277,7 +266,7 @@ } // Tests changing the AppListModel when switching profiles. -TEST_P(AppListMainViewTest, ModelChanged) { +TEST_F(AppListMainViewTest, ModelChanged) { delegate_->GetTestModel()->PopulateApps(kInitialItems); EXPECT_EQ(kInitialItems, GetRootViewModel()->view_size()); @@ -294,7 +283,7 @@ // Tests dragging an item out of a single item folder and dropping it onto the // page switcher. Regression test for http://crbug.com/415530/. -TEST_P(AppListMainViewTest, DragReparentItemOntoPageSwitcher) { +TEST_F(AppListMainViewTest, DragReparentItemOntoPageSwitcher) { AppListItemView* folder_item_view = CreateAndOpenSingleItemFolder(); ASSERT_TRUE(folder_item_view); @@ -329,7 +318,7 @@ // Test that an interrupted drag while reparenting an item from a folder, when // canceled via the root grid, correctly forwards the cancelation to the drag // ocurring from the folder. -TEST_P(AppListMainViewTest, MouseDragItemOutOfFolderWithCancel) { +TEST_F(AppListMainViewTest, MouseDragItemOutOfFolderWithCancel) { CreateAndOpenSingleItemFolder(); AppListItemView* dragged = StartDragForReparent(0); @@ -352,10 +341,7 @@ // Test that dragging an app out of a single item folder and reparenting it // back into its original folder results in a cancelled reparent. This is a // regression test for http://crbug.com/429083. -TEST_P(AppListMainViewTest, ReparentSingleItemOntoSelf) { - // TODO(anasalazar): Fix for cardified state - if (IsPaginationPreviewActive()) - return; +TEST_F(AppListMainViewTest, ReparentSingleItemOntoSelf) { // Add a folder with 1 item. AppListItemView* folder_item_view = CreateAndOpenSingleItemFolder(); std::string folder_id = folder_item_view->item()->id();
diff --git a/ash/app_list/views/app_list_view.cc b/ash/app_list/views/app_list_view.cc index 1a611b7..2743ef61 100644 --- a/ash/app_list/views/app_list_view.cc +++ b/ash/app_list/views/app_list_view.cc
@@ -659,6 +659,8 @@ SearchBoxViewBase::InitParams params; params.show_close_button_when_active = true; params.create_background = true; + params.animate_changing_search_icon = + features::IsProductivityLauncherAnimationEnabled(); search_box_view_->Init(params); // Assign |app_list_main_view_| here since it is accessed during Init().
diff --git a/ash/app_list/views/continue_section_view.cc b/ash/app_list/views/continue_section_view.cc index c2464ef..f0956071 100644 --- a/ash/app_list/views/continue_section_view.cc +++ b/ash/app_list/views/continue_section_view.cc
@@ -40,7 +40,7 @@ // Suggested tasks layout constants. Should this change, we should update the // Layout to leave out empty rows. -constexpr size_t kMinFilesForContinueSection = 3; +constexpr int kMinFilesForContinueSection = 3; std::unique_ptr<views::Label> CreateContinueLabel(const std::u16string& text) { auto label = std::make_unique<views::Label>(text); @@ -61,9 +61,7 @@ views::BoxLayout::Orientation::kVertical, gfx::Insets(kSectionVerticalPadding, kSectionHorizontalPadding), kHeaderVerticalSpacing)); - layout->set_main_axis_alignment( - tablet_mode ? views::BoxLayout::MainAxisAlignment::kCenter - : views::BoxLayout::MainAxisAlignment::kStart); + layout->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kStart); layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kStretch); @@ -96,7 +94,7 @@ } size_t ContinueSectionView::GetTasksSuggestionsCount() const { - return suggestions_container_->num_results(); + return static_cast<size_t>(suggestions_container_->num_results()); } void ContinueSectionView::DisableFocusForShowingActiveFolder(bool disabled) {
diff --git a/ash/app_list/views/continue_section_view_unittest.cc b/ash/app_list/views/continue_section_view_unittest.cc index c1c641b..0f08fc9 100644 --- a/ash/app_list/views/continue_section_view_unittest.cc +++ b/ash/app_list/views/continue_section_view_unittest.cc
@@ -55,8 +55,6 @@ void SetUp() override { AshTestBase::SetUp(); } ContinueSectionView* GetContinueSectionView() { - if (Shell::Get()->tablet_mode_controller()->InTabletMode()) - return GetAppListTestHelper()->GetFullscreenContinueSectionView(); return GetAppListTestHelper()->GetBubbleContinueSectionView(); } @@ -353,50 +351,5 @@ EXPECT_EQ(std::vector<std::string>{}, GetResultIds()); } -TEST_F(ContinueSectionViewTest, TabletModeLayoutWithThreeSuggestions) { - AddSearchResult("id1", AppListSearchResultType::kFileChip); - AddSearchResult("id2", AppListSearchResultType::kDriveChip); - AddSearchResult("id3", AppListSearchResultType::kDriveChip); - - Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); - VerifyResultViewsUpdated(); - - ASSERT_TRUE(GetContinueSectionView()->GetVisible()); - ASSERT_EQ(3u, GetContinueSectionView()->GetTasksSuggestionsCount()); - - const int width = GetResultViewAt(0)->width(); - const int vertical_position = GetResultViewAt(0)->y(); - - for (int i = 1; i < 3; i++) { - EXPECT_EQ(width, GetResultViewAt(i)->width()); - EXPECT_EQ(vertical_position, GetResultViewAt(i)->y()); - EXPECT_GT(GetResultViewAt(i)->x(), - GetResultViewAt(i - 1)->bounds().right()); - } -} - -TEST_F(ContinueSectionViewTest, TabletModeLayoutWithFourSuggestions) { - AddSearchResult("id1", AppListSearchResultType::kFileChip); - AddSearchResult("id2", AppListSearchResultType::kDriveChip); - AddSearchResult("id3", AppListSearchResultType::kDriveChip); - AddSearchResult("id4", AppListSearchResultType::kFileChip); - - Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true); - VerifyResultViewsUpdated(); - - ASSERT_TRUE(GetContinueSectionView()->GetVisible()); - ASSERT_EQ(4u, GetContinueSectionView()->GetTasksSuggestionsCount()); - - const int width = GetResultViewAt(0)->width(); - const int vertical_position = GetResultViewAt(0)->y(); - - for (int i = 1; i < 4; i++) { - EXPECT_EQ(width, GetResultViewAt(i)->width()); - EXPECT_EQ(vertical_position, GetResultViewAt(i)->y()); - EXPECT_GT(GetResultViewAt(i)->x(), - GetResultViewAt(i - 1)->bounds().right()); - } -} - } // namespace } // namespace ash
diff --git a/ash/app_list/views/continue_task_container_view.cc b/ash/app_list/views/continue_task_container_view.cc index 24555d9..562387db 100644 --- a/ash/app_list/views/continue_task_container_view.cc +++ b/ash/app_list/views/continue_task_container_view.cc
@@ -20,15 +20,13 @@ #include "ui/views/border.h" #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" -#include "ui/views/layout/flex_layout.h" #include "ui/views/layout/table_layout.h" -using views::BoxLayout; -using views::FlexLayout; -using views::TableLayout; - namespace ash { namespace { +// Suggested tasks padding in dips +constexpr int kSuggestedTasksHorizontalPadding = 6; + // Suggested tasks layout constants. constexpr int kColumnSpacingClamshell = 8; constexpr int kColumnSpacingTablet = 16; @@ -69,16 +67,39 @@ int columns, OnResultsChanged update_callback, bool tablet_mode) - : view_delegate_(view_delegate), - update_callback_(update_callback), - tablet_mode_(tablet_mode) { + : view_delegate_(view_delegate), update_callback_(update_callback) { DCHECK(!update_callback_.is_null()); - if (tablet_mode_) { - InitializeFlexLayout(); - } else { - columns_ = columns; - InitializeTableLayout(); + SetBorder(views::CreateEmptyBorder( + gfx::Insets(0, kSuggestedTasksHorizontalPadding))); + + auto* layout = SetLayoutManager(std::make_unique<views::TableLayout>()); + for (int i = 0; i < columns; i++) { + if (i > 0) { + layout->AddPaddingColumn( + views::TableLayout::kFixedSize, + tablet_mode ? kColumnSpacingTablet : kColumnSpacingClamshell); + } + layout->AddColumn( + views::LayoutAlignment::kStretch, views::LayoutAlignment::kCenter, + /*resize_percent=*/1.0f, views::TableLayout::ColumnSize::kUsePreferred, + /*fixed_width=*/0, /*min_width=*/0); + } + + for (size_t i = 0; i < kMaxFilesForContinueSection; ++i) { + if (i % columns == 0) { + if (i > 0) + layout->AddPaddingRow(views::TableLayout::kFixedSize, kRowSpacing); + layout->AddRows(1, views::TableLayout::kFixedSize); + } + ContinueTaskView* task = AddChildView( + std::make_unique<ContinueTaskView>(view_delegate, tablet_mode)); + // This view has a predefined number of placeholder tasks views which toggle + // visibility depending on the result being null or not. The container's + // visibility is handled on the parent view. + task->SetVisible(false); + task->set_index_in_container(i); + suggestion_tasks_views_.emplace_back(task); } } @@ -107,18 +128,10 @@ std::vector<SearchResult*> tasks = GetTasksResultsForContinueSection(results_); - RemoveAllChildViews(); - suggestion_tasks_views_.clear(); - num_results_ = std::min(kMaxFilesForContinueSection, tasks.size()); - - for (size_t i = 0; i < num_results_; ++i) { - auto task = - std::make_unique<ContinueTaskView>(view_delegate_, tablet_mode_); - task->set_index_in_container(i); - task->SetResult(tasks[i]); - suggestion_tasks_views_.emplace_back(task.get()); - MaybeAddNewRowToLayout(i); - AddChildView(std::move(task)); + // Update search results here. + for (size_t i = 0; i < suggestion_tasks_views_.size(); ++i) { + suggestion_tasks_views_[i]->SetResult(i < tasks.size() ? tasks[i] + : nullptr); } auto* notifier = view_delegate_->GetNotifier(); @@ -126,9 +139,10 @@ std::vector<AppListNotifier::Result> notifier_results; for (const auto* task : tasks) notifier_results.emplace_back(task->id(), task->metrics_type()); - notifier->NotifyResultsUpdated(SearchResultDisplayType::kList, + notifier->NotifyResultsUpdated(SearchResultDisplayType::kChip, notifier_results); } + num_results_ = std::min(kMaxFilesForContinueSection, tasks.size()); if (!update_callback_.is_null()) update_callback_.Run(); } @@ -160,56 +174,6 @@ } } -void ContinueTaskContainerView::MaybeAddNewRowToLayout(int task_index) { - if (!table_layout_) - return; - - // Only adds a new row if the columns have been filled by previous views. - if (task_index % columns_) - return; - - if (task_index > 0) - table_layout_->AddPaddingRow(views::TableLayout::kFixedSize, kRowSpacing); - table_layout_->AddRows(1, views::TableLayout::kFixedSize); -} - -void ContinueTaskContainerView::InitializeFlexLayout() { - DCHECK(tablet_mode_); - DCHECK(!table_layout_); - DCHECK(!columns_); - - flex_layout_ = SetLayoutManager(std::make_unique<FlexLayout>()); - flex_layout_->SetOrientation(views::LayoutOrientation::kHorizontal) - .SetMainAxisAlignment(views::LayoutAlignment::kCenter) - .SetDefault(views::kMarginsKey, - gfx::Insets(0, kColumnSpacingTablet, 0, 0)) - .SetDefault(views::kFlexBehaviorKey, - views::FlexSpecification( - views::MinimumFlexSizeRule::kScaleToMinimum, - views::MaximumFlexSizeRule::kScaleToMaximum)); -} - -void ContinueTaskContainerView::InitializeTableLayout() { - DCHECK(!tablet_mode_); - DCHECK(!flex_layout_); - DCHECK_GT(columns_, 0); - - table_layout_ = SetLayoutManager(std::make_unique<views::TableLayout>()); - std::vector<size_t> linked_columns; - for (int i = 0; i < columns_; i++) { - if (i > 0) { - table_layout_->AddPaddingColumn(views::TableLayout::kFixedSize, - kColumnSpacingClamshell); - } - table_layout_->AddColumn( - views::LayoutAlignment::kStretch, views::LayoutAlignment::kCenter, - /*resize_percent=*/1.0f, views::TableLayout::ColumnSize::kFixed, - /*fixed_width=*/0, /*min_width=*/0); - linked_columns.push_back(2 * i); - } - table_layout_->LinkColumnSizes(linked_columns); -} - BEGIN_METADATA(ContinueTaskContainerView, views::View) END_METADATA
diff --git a/ash/app_list/views/continue_task_container_view.h b/ash/app_list/views/continue_task_container_view.h index 5ea32a04..5ae7635 100644 --- a/ash/app_list/views/continue_task_container_view.h +++ b/ash/app_list/views/continue_task_container_view.h
@@ -15,11 +15,6 @@ #include "ui/base/models/list_model_observer.h" #include "ui/views/view.h" -namespace views { -class FlexLayout; -class TableLayout; -} // namespace views - namespace ash { class AppListViewDelegate; @@ -28,7 +23,7 @@ // The container for the Continue Tasks results view. The view contains a preset // number of ContinueTaskViews that get populated based on the list of results // passed in SetResult. -// ContinueTaskContainerView will accommodate Continue Task views in a grid-like +// ContinueTaskContainerView will accommodate Continue Task views in a table // layout with the number of columns specified at construction. class ASH_EXPORT ContinueTaskContainerView : public ui::ListModelObserver, public views::View { @@ -54,7 +49,7 @@ void ListItemsChanged(size_t start, size_t count) override; void Update(); - size_t num_results() const { return num_results_; } + int num_results() const { return num_results_; } void SetResults(SearchModel::SearchResults* results); @@ -64,49 +59,15 @@ private: void ScheduleUpdate(); - // Adds a new row to `table_layout_` to make space for extra views. A new row - // need to be added if the number of views for the current row is already - // filling up the available `columns_`. This will be no-op if `table_layout_` - // is nullptr. - void MaybeAddNewRowToLayout(int task_index); - - // Initializes the view's layout manager to use |flex_layout_|. FlexLayout is - // used in tablet mode only. Views will be laid out in a single row centered - // in the container. Number of items displayed will depend on available space. - // This will not enforce any number of `columns_`. - void InitializeFlexLayout(); - - // Initializes the view's layout manager to use |table_layout_|. TableLayout - // is used in clamshell mode only. Views are laid out in a table with a - // specific number of `columns_`. This displays views to stretch as to use - // all vertical space available in the container. Extra views are added in - // multiple rows. - void InitializeTableLayout(); - AppListViewDelegate* const view_delegate_; // A callback to be invoked after an Update request finishes. OnResultsChanged update_callback_; SearchModel::SearchResults* results_ = nullptr; // Owned by SearchModel. - // Only one of the layouts is to be set. - // `flex_layout_` aligns the views as a single row centered in the container. - // Used in tablet mode. - views::FlexLayout* flex_layout_ = nullptr; - // `table_layout_` aligns the views as a table with multiple rows stretched - // to fill the container. Used in clamshell mode. - views::TableLayout* table_layout_ = nullptr; - // The list of tasks views for the container. std::vector<ContinueTaskView*> suggestion_tasks_views_; // The number of results shown on the container. Each result has one view. - size_t num_results_ = 0; - - // The number of columns available for the view. This is ignored in tablet - // mode. - int columns_ = 0; - - // Whether or not the view is showing for a table mode launcher or not. - bool tablet_mode_ = false; + int num_results_ = 0; base::ScopedObservation<SearchModel::SearchResults, ui::ListModelObserver> list_model_observation_{this};
diff --git a/ash/app_list/views/continue_task_view.cc b/ash/app_list/views/continue_task_view.cc index b09babbad..46cbaa9 100644 --- a/ash/app_list/views/continue_task_view.cc +++ b/ash/app_list/views/continue_task_view.cc
@@ -48,8 +48,6 @@ constexpr int kViewCornerRadiusClamshell = 8; constexpr int kViewCornerRadiusTablet = 20; -constexpr int kTaskMinWidth = 204; -constexpr int kTaskMaxWidth = 264; gfx::ImageSkia CreateIconWithCircleBackground(const gfx::ImageSkia& icon) { // The icon with circular background should only be styled when dark light @@ -122,15 +120,11 @@ std::make_unique<views::Label>(std::u16string())); title_->SetAccessibleName(std::u16string()); title_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); - title_->SetElideBehavior(gfx::ElideBehavior::ELIDE_MIDDLE); subtitle_ = label_container->AddChildView( std::make_unique<views::Label>(std::u16string())); subtitle_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT); - subtitle_->SetElideBehavior(gfx::ElideBehavior::ELIDE_MIDDLE); - - layout_manager->SetFlexForView(label_container, 1); - UpdateResult(); + set_context_menu_controller(this); } ContinueTaskView::~ContinueTaskView() {} @@ -141,24 +135,6 @@ bubble_utils::ApplyStyle(subtitle_, bubble_utils::LabelStyle::kSubtitle); } -gfx::Size ContinueTaskView::GetMaximumSize() const { - return gfx::Size(kTaskMaxWidth, - GetLayoutManager()->GetPreferredSize(this).height()); -} - -gfx::Size ContinueTaskView::GetMinimumSize() const { - return gfx::Size(kTaskMinWidth, - GetLayoutManager()->GetPreferredSize(this).height()); -} - -gfx::Size ContinueTaskView::CalculatePreferredSize() const { - gfx::Size preferred_size = GetLayoutManager()->GetPreferredSize(this); - - return gfx::Size( - base::clamp(preferred_size.width(), kTaskMinWidth, kTaskMaxWidth), - preferred_size.height()); -} - void ContinueTaskView::OnButtonPressed(const ui::Event& event) { OpenResult(event.flags()); }
diff --git a/ash/app_list/views/continue_task_view.h b/ash/app_list/views/continue_task_view.h index 7f3729e0..bd8f2c8 100644 --- a/ash/app_list/views/continue_task_view.h +++ b/ash/app_list/views/continue_task_view.h
@@ -44,9 +44,6 @@ ~ContinueTaskView() override; // views::View: - gfx::Size CalculatePreferredSize() const override; - gfx::Size GetMinimumSize() const override; - gfx::Size GetMaximumSize() const override; void OnThemeChanged() override; // SearchResultObserver:
diff --git a/ash/app_list/views/paged_apps_grid_view.cc b/ash/app_list/views/paged_apps_grid_view.cc index 5fbad4a..5953fab 100644 --- a/ash/app_list/views/paged_apps_grid_view.cc +++ b/ash/app_list/views/paged_apps_grid_view.cc
@@ -1089,8 +1089,6 @@ } void PagedAppsGridView::StartAppsGridCardifiedView() { - if (!app_list_features::IsNewDragSpecInLauncherEnabled()) - return; if (IsInFolder()) return; DCHECK(!cardified_state_); @@ -1112,8 +1110,6 @@ } void PagedAppsGridView::EndAppsGridCardifiedView() { - if (!app_list_features::IsNewDragSpecInLauncherEnabled()) - return; if (IsInFolder()) return; DCHECK(cardified_state_);
diff --git a/ash/app_list/views/productivity_launcher_search_view.cc b/ash/app_list/views/productivity_launcher_search_view.cc index dadfa5d..7eb8110 100644 --- a/ash/app_list/views/productivity_launcher_search_view.cc +++ b/ash/app_list/views/productivity_launcher_search_view.cc
@@ -45,8 +45,9 @@ ProductivityLauncherSearchView::ProductivityLauncherSearchView( AppListViewDelegate* view_delegate, + SearchResultPageDialogController* dialog_controller, SearchBoxView* search_box_view) - : search_box_view_(search_box_view) { + : dialog_controller_(dialog_controller), search_box_view_(search_box_view) { DCHECK(view_delegate); DCHECK(search_box_view_); SetUseDefaultFillLayout(true); @@ -84,7 +85,8 @@ // kBestMatch is always the first list view shown. auto* best_match_container = scroll_contents->AddChildView(std::make_unique<SearchResultListView>( - /*main_view=*/nullptr, view_delegate, absl::nullopt)); + /*main_view=*/nullptr, view_delegate, dialog_controller_, + absl::nullopt)); best_match_container->SetListType( SearchResultListView::SearchResultListType::kBestMatch); add_result_container(best_match_container); @@ -98,7 +100,7 @@ for (size_t i = 0; i < category_count; ++i) { auto* result_container = scroll_contents->AddChildView(std::make_unique<SearchResultListView>( - /*main_view=*/nullptr, view_delegate, i)); + /*main_view=*/nullptr, view_delegate, dialog_controller_, i)); add_result_container(result_container); }
diff --git a/ash/app_list/views/productivity_launcher_search_view.h b/ash/app_list/views/productivity_launcher_search_view.h index 8254b69..f7b6955 100644 --- a/ash/app_list/views/productivity_launcher_search_view.h +++ b/ash/app_list/views/productivity_launcher_search_view.h
@@ -20,6 +20,7 @@ class AppListViewDelegate; class ResultSelectionController; class SearchBoxView; +class SearchResultPageDialogController; // The search results view for productivity launcher. Contains a scrolling list // of search results. Does not include the search box, which is owned by a @@ -31,8 +32,10 @@ public: METADATA_HEADER(ProductivityLauncherSearchView); - ProductivityLauncherSearchView(AppListViewDelegate* view_delegate, - SearchBoxView* search_box_view); + ProductivityLauncherSearchView( + AppListViewDelegate* view_delegate, + SearchResultPageDialogController* dialog_controller, + SearchBoxView* search_box_view); ProductivityLauncherSearchView(const ProductivityLauncherSearchView&) = delete; ProductivityLauncherSearchView& operator=( @@ -57,6 +60,10 @@ return result_container_views_; } + ResultSelectionController* result_selection_controller_for_test() { + return result_selection_controller_.get(); + } + private: // Passed to |result_selection_controller_| as a callback that gets called // when the currently selected result changes. @@ -90,6 +97,8 @@ // result view unless overridden by |ignore_result_changes_for_a11y_|. void MaybeNotifySelectedResultChanged(); + SearchResultPageDialogController* const dialog_controller_; + SearchBoxView* const search_box_view_; // The scroll view that contains all the result_container_views_.
diff --git a/ash/app_list/views/productivity_launcher_search_view_unittest.cc b/ash/app_list/views/productivity_launcher_search_view_unittest.cc index bece30d..5e87f63e 100644 --- a/ash/app_list/views/productivity_launcher_search_view_unittest.cc +++ b/ash/app_list/views/productivity_launcher_search_view_unittest.cc
@@ -21,6 +21,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/accessibility/ax_node_data.h" #include "ui/events/keycodes/keyboard_codes_posix.h" +#include "ui/views/controls/button/label_button.h" #include "ui/views/controls/textfield/textfield.h" #include "ui/views/test/ax_event_counter.h" @@ -68,6 +69,13 @@ ->list_type_for_test(); } + std::u16string GetListLabel( + SearchResultContainerView* result_container_view) { + return static_cast<SearchResultListView*>(result_container_view) + ->title_label_for_test() + ->GetText(); + } + base::test::ScopedFeatureList scoped_feature_list_; }; @@ -120,12 +128,14 @@ EXPECT_TRUE(result_containers[2]->GetVisible()); EXPECT_FALSE(result_containers[3]->GetVisible()); + // Verify title labels are correctly updated. + EXPECT_EQ(GetListLabel(result_containers[1]), u"Apps"); + EXPECT_EQ(GetListLabel(result_containers[2]), u"Websites"); + // Verify result container ordering. - auto list_views = test_helper->GetProductivityLauncherSearchView() - ->result_container_views_for_test(); - EXPECT_EQ(GetListType(list_views[1]), + EXPECT_EQ(GetListType(result_containers[1]), SearchResultListView::SearchResultListType::kApps); - EXPECT_EQ(GetListType(list_views[2]), + EXPECT_EQ(GetListType(result_containers[2]), SearchResultListView::SearchResultListType::kWeb); // Create categorized results and order categories as {kWeb, kApps}. @@ -145,13 +155,18 @@ EXPECT_TRUE(result_containers[2]->GetVisible()); EXPECT_FALSE(result_containers[3]->GetVisible()); - // Verify result container ordering. - list_views = test_helper->GetProductivityLauncherSearchView() - ->result_container_views_for_test(); + // Verify title labels are correctly updated. - EXPECT_EQ(GetListType(list_views[1]), + EXPECT_EQ(GetListLabel(result_containers[1]), u"Websites"); + EXPECT_EQ(GetListLabel(result_containers[2]), u"Apps"); + + // Verify result container ordering. + result_containers = test_helper->GetProductivityLauncherSearchView() + ->result_container_views_for_test(); + + EXPECT_EQ(GetListType(result_containers[1]), SearchResultListView::SearchResultListType::kWeb); - EXPECT_EQ(GetListType(list_views[2]), + EXPECT_EQ(GetListType(result_containers[2]), SearchResultListView::SearchResultListType::kApps); }
diff --git a/ash/app_list/views/recent_apps_view.cc b/ash/app_list/views/recent_apps_view.cc index 5f53765..a020e76 100644 --- a/ash/app_list/views/recent_apps_view.cc +++ b/ash/app_list/views/recent_apps_view.cc
@@ -134,14 +134,13 @@ void EndDrag(bool cancel) override {} void OnAppListItemViewActivated(AppListItemView* pressed_item_view, const ui::Event& event) override { - // TODO(crbug.com/1216594): Add a new launch type for "recent apps". // NOTE: Avoid using |item->id()| as the parameter. In some rare situations, // activating the item may destruct it. Using the reference to an object // which may be destroyed during the procedure as the function parameter // may bring the crash like https://crbug.com/990282. const std::string id = pressed_item_view->item()->id(); - view_delegate_->ActivateItem( - id, event.flags(), AppListLaunchedFrom::kLaunchedFromSuggestionChip); + view_delegate_->ActivateItem(id, event.flags(), + AppListLaunchedFrom::kLaunchedFromRecentApps); // `this` may be deleted. }
diff --git a/ash/app_list/views/search_box_view_unittest.cc b/ash/app_list/views/search_box_view_unittest.cc index 6696643..8e0d840 100644 --- a/ash/app_list/views/search_box_view_unittest.cc +++ b/ash/app_list/views/search_box_view_unittest.cc
@@ -274,8 +274,7 @@ const gfx::ImageSkia expected_icon = gfx::CreateVectorIcon( kGoogleBlackIcon, kSearchBoxIconSize, kDefaultSearchboxColor); - const gfx::ImageSkia actual_icon = - view()->get_search_icon_for_test()->GetImage(); + const gfx::ImageSkia actual_icon = view()->search_icon()->GetImage(); EXPECT_TRUE(gfx::test::AreBitmapsEqual(*expected_icon.bitmap(), *actual_icon.bitmap())); @@ -288,8 +287,7 @@ const gfx::ImageSkia expected_icon = gfx::CreateVectorIcon( kGoogleColorIcon, kSearchBoxIconSize, kDefaultSearchboxColor); - const gfx::ImageSkia actual_icon = - view()->get_search_icon_for_test()->GetImage(); + const gfx::ImageSkia actual_icon = view()->search_icon()->GetImage(); EXPECT_TRUE(gfx::test::AreBitmapsEqual(*expected_icon.bitmap(), *actual_icon.bitmap())); @@ -302,8 +300,7 @@ const gfx::ImageSkia expected_icon = gfx::CreateVectorIcon( kSearchEngineNotGoogleIcon, kSearchBoxIconSize, kDefaultSearchboxColor); - const gfx::ImageSkia actual_icon = - view()->get_search_icon_for_test()->GetImage(); + const gfx::ImageSkia actual_icon = view()->search_icon()->GetImage(); EXPECT_TRUE(gfx::test::AreBitmapsEqual(*expected_icon.bitmap(), *actual_icon.bitmap())); @@ -316,8 +313,7 @@ const gfx::ImageSkia expected_icon = gfx::CreateVectorIcon( kSearchEngineNotGoogleIcon, kSearchBoxIconSize, kDefaultSearchboxColor); - const gfx::ImageSkia actual_icon = - view()->get_search_icon_for_test()->GetImage(); + const gfx::ImageSkia actual_icon = view()->search_icon()->GetImage(); EXPECT_TRUE(gfx::test::AreBitmapsEqual(*expected_icon.bitmap(), *actual_icon.bitmap())); @@ -1284,5 +1280,40 @@ EXPECT_EQ(assistant_animator->GetTargetOpacity(), 1.0f); } +// Test that activating and deactivating the search box causes the search icon +// to animate. +TEST_F(SearchBoxViewAnimationTest, SearchBoxIconImageViewAnimation) { + auto* search_box = GetAppListTestHelper()->GetSearchBoxView(); + + // Keep track of the animator for the icon layer which will animate out. + auto* old_animator = search_box->search_icon()->layer()->GetAnimator(); + + // Set search box to active state. + search_box->SetSearchBoxActive(true, ui::ET_MOUSE_PRESSED); + + // Check that the old layer is fading out and the new animator is fading in. + auto* animator = search_box->search_icon()->layer()->GetAnimator(); + EXPECT_TRUE(animator->IsAnimatingProperty( + ui::LayerAnimationElement::AnimatableProperty::OPACITY)); + EXPECT_EQ(animator->GetTargetOpacity(), 1.0f); + EXPECT_TRUE(old_animator->IsAnimatingProperty( + ui::LayerAnimationElement::AnimatableProperty::OPACITY)); + EXPECT_EQ(old_animator->GetTargetOpacity(), 0.0f); + + // Set search box to inactive state. + search_box->SetSearchBoxActive(false, ui::ET_MOUSE_PRESSED); + + old_animator = animator; + animator = search_box->search_icon()->layer()->GetAnimator(); + + // Check that the old layer is fading out and the new layer is fading in. + EXPECT_TRUE(animator->IsAnimatingProperty( + ui::LayerAnimationElement::AnimatableProperty::OPACITY)); + EXPECT_EQ(animator->GetTargetOpacity(), 1.0f); + EXPECT_TRUE(old_animator->IsAnimatingProperty( + ui::LayerAnimationElement::AnimatableProperty::OPACITY)); + EXPECT_EQ(old_animator->GetTargetOpacity(), 0.0f); +} + } // namespace } // namespace ash
diff --git a/ash/app_list/views/search_result_list_view.cc b/ash/app_list/views/search_result_list_view.cc index 5b8297f..402ef1fd 100644 --- a/ash/app_list/views/search_result_list_view.cc +++ b/ash/app_list/views/search_result_list_view.cc
@@ -104,6 +104,7 @@ SearchResultListView::SearchResultListView( AppListMainView* main_view, AppListViewDelegate* view_delegate, + SearchResultPageDialogController* dialog_controller, absl::optional<size_t> productivity_launcher_index) : SearchResultContainerView(view_delegate), main_view_(main_view), @@ -131,7 +132,7 @@ for (size_t i = 0; i < result_count; ++i) { search_result_views_.emplace_back(new SearchResultView( - this, view_delegate_, + this, view_delegate_, dialog_controller, features::IsProductivityLauncherEnabled() ? SearchResultView::SearchResultViewType::kDefault : SearchResultView::SearchResultViewType::kClassic)); @@ -205,7 +206,6 @@ title_label_->SetVisible(true); break; } - DoUpdate(); } void SearchResultListView::ListItemsRemoved(size_t start, size_t count) { @@ -241,8 +241,8 @@ AppListModelProvider::Get()->search_model()->ordered_categories(); if (productivity_launcher_index_ < ordered_categories->size()) { enabled_ = true; - list_type_ = CategoryToListType( - (*ordered_categories)[productivity_launcher_index_.value()]); + SetListType(CategoryToListType( + (*ordered_categories)[productivity_launcher_index_.value()])); } else { enabled_ = false; list_type_.reset();
diff --git a/ash/app_list/views/search_result_list_view.h b/ash/app_list/views/search_result_list_view.h index 2cd1c85..adcfc53 100644 --- a/ash/app_list/views/search_result_list_view.h +++ b/ash/app_list/views/search_result_list_view.h
@@ -28,6 +28,7 @@ class AppListMainView; class AppListViewDelegate; +class SearchResultPageDialogController; // SearchResultListView displays SearchResultList with a list of // SearchResultView. @@ -68,6 +69,7 @@ SearchResultListView(AppListMainView* main_view, AppListViewDelegate* view_delegate, + SearchResultPageDialogController* dialog_controller, absl::optional<size_t> productivity_launcher_index); SearchResultListView(const SearchResultListView&) = delete; @@ -105,6 +107,8 @@ // reset. SearchResultListType list_type_for_test() { return list_type_.value(); } + views::Label* title_label_for_test() { return title_label_; } + protected: // Overridden from views::View: void VisibilityChanged(View* starting_from, bool is_visible) override;
diff --git a/ash/app_list/views/search_result_list_view_unittest.cc b/ash/app_list/views/search_result_list_view_unittest.cc index 5bcd65a..2a541a4 100644 --- a/ash/app_list/views/search_result_list_view_unittest.cc +++ b/ash/app_list/views/search_result_list_view_unittest.cc
@@ -57,7 +57,7 @@ views::test::WidgetTest::SetUp(); widget_ = CreateTopLevelPlatformWidget(); view_ = std::make_unique<SearchResultListView>(nullptr, &view_delegate_, - absl::nullopt); + nullptr, absl::nullopt); view_->SetListType(SearchResultListView::SearchResultListType::kUnified); widget_->SetBounds(gfx::Rect(0, 0, 700, 500)); widget_->GetContentsView()->AddChildView(view_.get());
diff --git a/ash/app_list/views/search_result_page_anchored_dialog.cc b/ash/app_list/views/search_result_page_anchored_dialog.cc index e84679a3..192ed23a 100644 --- a/ash/app_list/views/search_result_page_anchored_dialog.cc +++ b/ash/app_list/views/search_result_page_anchored_dialog.cc
@@ -36,31 +36,29 @@ views::Widget* const parent = host_view_->GetWidget(); // The |dialog| ownership is passed to the window hierarchy. widget_ = views::DialogDelegate::CreateDialogWidget( - dialog.release(), nullptr, parent->GetNativeWindow()); + dialog.release(), parent->GetNativeWindow(), parent->GetNativeWindow()); widget_observations_.AddObservation(widget_); widget_observations_.AddObservation(parent); + + host_view_->AddObserver(this); } SearchResultPageAnchoredDialog::~SearchResultPageAnchoredDialog() { + host_view_->RemoveObserver(this); widget_observations_.RemoveAllObservations(); if (widget_) widget_->Close(); } -void SearchResultPageAnchoredDialog::UpdateBounds( - const gfx::Rect& anchor_bounds) { +void SearchResultPageAnchoredDialog::UpdateBounds() { if (!widget_) return; - anchor_bounds_ = anchor_bounds; - - gfx::Point anchor_point_in_screen = anchor_bounds.CenterPoint(); + gfx::Point anchor_point_in_screen(host_view_->width() / 2, 0); views::View::ConvertPointToScreen(host_view_, &anchor_point_in_screen); - // Calculate dialog offset from the anchor view center so the dialog frame - // (ignoring borders) respects kDialogVerticalMargin. const int vertical_offset = - kDialogVerticalMargin - anchor_bounds.height() / 2 - + kDialogVerticalMargin - widget_->non_client_view()->frame_view()->GetInsets().top(); gfx::Size dialog_size = widget_->GetContentsView()->GetPreferredSize(); widget_->SetBounds( @@ -71,7 +69,7 @@ float SearchResultPageAnchoredDialog::AdjustVerticalTransformOffset( float default_offset) { - // In addition to the search box offset (in host view coordinates), the + // In addition to the host view (in host view coordinates), the // widget has to consider the parent (app list view) widget transform to // correctly follow the anchor view animation. const float parent_offset = @@ -94,7 +92,13 @@ // app list layout, and thus the anchor bounds in the host view coordinates // may not change). if (widget == host_view_->GetWidget()) - UpdateBounds(anchor_bounds_); + UpdateBounds(); +} + +void SearchResultPageAnchoredDialog::OnViewBoundsChanged( + views::View* observed_view) { + DCHECK_EQ(host_view_, observed_view); + UpdateBounds(); } } // namespace ash
diff --git a/ash/app_list/views/search_result_page_anchored_dialog.h b/ash/app_list/views/search_result_page_anchored_dialog.h index 297c483..ba1edc6 100644 --- a/ash/app_list/views/search_result_page_anchored_dialog.h +++ b/ash/app_list/views/search_result_page_anchored_dialog.h
@@ -9,6 +9,7 @@ #include "base/callback.h" #include "base/scoped_multi_source_observation.h" +#include "ui/views/view_observer.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_observer.h" @@ -22,15 +23,16 @@ namespace ash { -// A helper to keep track and manage bounds of a dialog window anchored within -// the search results app list page. -class SearchResultPageAnchoredDialog : public views::WidgetObserver { +// A helper to keep track and manage bounds of a dialog window anchored to the +// search results app list page. +class SearchResultPageAnchoredDialog : public views::WidgetObserver, + public views::ViewObserver { public: // Creates a widget for the provided dialog delegate view. // |dialog| - The dialog delegate view whose widget this should manage. // |host_view| - The view that is "hosting" the dialog - the dialog widget - // will be parented by the host view's widget, and anchor bounds provided - // to UpdateBounds() will be expected to be in host view bounds. + // will be parented by the host view's widget, and the dialog will be + // positioned relative to this view's bounds. // |callback| - A closure called when the dialog widget gets closed. The // callback will not be called when the SearchResultPageAnchoredDialog // gets destroyed, @@ -44,10 +46,9 @@ const SearchResultPageAnchoredDialog& other) = delete; ~SearchResultPageAnchoredDialog() override; - // Repositions the dialog widget bounds relative to the provided anchor + // Repositions the dialog widget bounds relative to the current host view // bounds. - // |anchor_bounds| are expected to be in |host_view_| coordinates. - void UpdateBounds(const gfx::Rect& anchor_bounds); + void UpdateBounds(); // Adjusts the vertical translate offset to be used during search results page // animation. The default offset follows the search box bounds translation @@ -59,6 +60,9 @@ void OnWidgetBoundsChanged(views::Widget* widget, const gfx::Rect& new_bounds) override; + // views::ViewObserver: + void OnViewBoundsChanged(views::View* observed_view) override; + views::Widget* widget() { return widget_; } private: @@ -68,9 +72,6 @@ base::OnceClosure callback_; - // Most recent anchor bounds (in |host_view_| coordinates). - gfx::Rect anchor_bounds_; - base::ScopedMultiSourceObservation<views::Widget, views::WidgetObserver> widget_observations_{this}; };
diff --git a/ash/app_list/views/search_result_page_dialog_controller.cc b/ash/app_list/views/search_result_page_dialog_controller.cc new file mode 100644 index 0000000..fd4748d --- /dev/null +++ b/ash/app_list/views/search_result_page_dialog_controller.cc
@@ -0,0 +1,44 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/app_list/views/search_result_page_dialog_controller.h" + +#include <utility> + +#include "ash/app_list/views/search_result_page_anchored_dialog.h" +#include "ui/views/widget/widget.h" +#include "ui/views/window/dialog_delegate.h" + +namespace ash { + +SearchResultPageDialogController::SearchResultPageDialogController( + views::View* host_view) + : host_view_(host_view) {} + +SearchResultPageDialogController::~SearchResultPageDialogController() = default; + +void SearchResultPageDialogController::Show( + std::unique_ptr<views::DialogDelegateView> dialog) { + if (!enabled_) + return; + + dialog_ = std::make_unique<SearchResultPageAnchoredDialog>( + std::move(dialog), host_view_, + base::BindOnce(&SearchResultPageDialogController::OnAnchoredDialogClosed, + base::Unretained(this))); + dialog_->UpdateBounds(); + dialog_->widget()->Show(); +} + +void SearchResultPageDialogController::SetEnabled(bool enabled) { + enabled_ = enabled; + if (!enabled) + dialog_.reset(); +} + +void SearchResultPageDialogController::OnAnchoredDialogClosed() { + dialog_.reset(); +} + +} // namespace ash
diff --git a/ash/app_list/views/search_result_page_dialog_controller.h b/ash/app_list/views/search_result_page_dialog_controller.h new file mode 100644 index 0000000..be80670 --- /dev/null +++ b/ash/app_list/views/search_result_page_dialog_controller.h
@@ -0,0 +1,56 @@ +// 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_APP_LIST_VIEWS_SEARCH_RESULT_PAGE_DIALOG_CONTROLLER_H_ +#define ASH_APP_LIST_VIEWS_SEARCH_RESULT_PAGE_DIALOG_CONTROLLER_H_ + +#include <memory> + +namespace views { +class DialogDelegateView; +class View; +} // namespace views + +namespace ash { + +class SearchResultPageAnchoredDialog; + +// Controller that can be used to show a dialog anchored within the app list +// search UI. +class SearchResultPageDialogController { + public: + explicit SearchResultPageDialogController(views::View* host_view); + SearchResultPageDialogController(const SearchResultPageDialogController&) = + delete; + SearchResultPageDialogController& operator=( + const SearchResultPageDialogController&) = delete; + ~SearchResultPageDialogController(); + + // Shows a search results page dialog with contents `dialog_contents`. + // No-op if not enabled. + void Show(std::unique_ptr<views::DialogDelegateView> dialog_contents); + + // Sets whether search result page dialogs are enabled. Disabling dialoga will + // close any currently opened dialogs. + void SetEnabled(bool enabled); + + SearchResultPageAnchoredDialog* dialog() { return dialog_.get(); } + + private: + // Called when the search result page dialog gets closed. + void OnAnchoredDialogClosed(); + + views::View* const host_view_; + + // Whether search result page dialogs are allowed. If false, calls to `Show()` + // will be no-op. + bool enabled_ = false; + + // Currently shown dialog - null when no dialog is shown. + std::unique_ptr<SearchResultPageAnchoredDialog> dialog_; +}; + +} // namespace ash + +#endif // ASH_APP_LIST_VIEWS_SEARCH_RESULT_PAGE_DIALOG_CONTROLLER_H_
diff --git a/ash/app_list/views/search_result_page_view.cc b/ash/app_list/views/search_result_page_view.cc index aee141e..74f71c4 100644 --- a/ash/app_list/views/search_result_page_view.cc +++ b/ash/app_list/views/search_result_page_view.cc
@@ -231,10 +231,12 @@ AppListViewDelegate* view_delegate, AppListMainView* app_list_main_view, SearchBoxView* search_box_view) { + dialog_controller_ = std::make_unique<SearchResultPageDialogController>(this); + if (features::IsProductivityLauncherEnabled()) { std::unique_ptr<ProductivityLauncherSearchView> search_view_ptr = - std::make_unique<ProductivityLauncherSearchView>(view_delegate, - search_box_view); + std::make_unique<ProductivityLauncherSearchView>( + view_delegate, dialog_controller_.get(), search_box_view); productivity_launcher_search_view_ = search_view_ptr.get(); contents_view_->AddChildView( std::make_unique<SearchCardView>(std::move(search_view_ptr))); @@ -249,7 +251,8 @@ // productivity_launcher_index is not set as the feature is not enabled. search_result_list_view_ = AddSearchResultContainerView(std::make_unique<SearchResultListView>( - app_list_main_view, view_delegate, absl::nullopt)); + app_list_main_view, view_delegate, dialog_controller_.get(), + absl::nullopt)); search_result_list_view_->SetListType( SearchResultListView::SearchResultListType::kUnified); @@ -508,23 +511,6 @@ void SearchResultPageView::ShowAssistantChanged() {} -void SearchResultPageView::ShowAnchoredDialog( - std::unique_ptr<views::DialogDelegateView> dialog) { - ContentsView* const contents_view = AppListPage::contents_view(); - if (contents_view->GetActiveState() != AppListState::kStateSearchResults) - return; - - anchored_dialog_ = std::make_unique<SearchResultPageAnchoredDialog>( - std::move(dialog), contents_view, - base::BindOnce(&SearchResultPageView::OnAnchoredDialogClosed, - base::Unretained(this))); - const gfx::Rect anchor_bounds = - contents_view->GetSearchBoxBounds(AppListState::kStateSearchResults); - anchored_dialog_->UpdateBounds(anchor_bounds); - - anchored_dialog_->widget()->Show(); -} - SkColor SearchResultPageView::GetBackgroundColorForState( AppListState state) const { if (state == AppListState::kStateSearchResults) @@ -545,10 +531,6 @@ return search_result_list_view_; } -void SearchResultPageView::OnWillBeHidden() { - anchored_dialog_.reset(); -} - bool SearchResultPageView::ShouldShowSearchResultView() const { SearchModel* search_model = AppListModelProvider::Get()->search_model(); return (!features::IsProductivityLauncherEnabled() || @@ -562,6 +544,7 @@ // being moved onto suggested apps when zero state is enabled. AppListPage::OnHidden(); notify_a11y_results_changed_timer_.Stop(); + dialog_controller_->SetEnabled(false); SetVisible(false); for (auto* container_view : result_container_views_) { container_view->SetShown(false); @@ -574,6 +557,9 @@ void SearchResultPageView::OnShown() { AppListPage::OnShown(); + + dialog_controller_->SetEnabled(true); + for (auto* container_view : result_container_views_) { container_view->SetShown(ShouldShowSearchResultView()); } @@ -601,10 +587,12 @@ animator.Run(default_offset, layer()); animator.Run(default_offset, view_shadow_->shadow()->shadow_layer()); - if (anchored_dialog_) { + SearchResultPageAnchoredDialog* search_page_dialog = + dialog_controller_->dialog(); + if (search_page_dialog) { const float offset = - anchored_dialog_->AdjustVerticalTransformOffset(default_offset); - animator.Run(offset, anchored_dialog_->widget()->GetLayer()); + search_page_dialog->AdjustVerticalTransformOffset(default_offset); + animator.Run(offset, search_page_dialog->widget()->GetLayer()); } } @@ -614,16 +602,6 @@ layer()->SetOpacity(search_box_opacity); } -void SearchResultPageView::UpdatePageBoundsForState( - AppListState state, - const gfx::Rect& contents_bounds, - const gfx::Rect& search_box_bounds) { - AppListPage::UpdatePageBoundsForState(state, contents_bounds, - search_box_bounds); - if (anchored_dialog_) - anchored_dialog_->UpdateBounds(search_box_bounds); -} - gfx::Rect SearchResultPageView::GetPageBoundsForState( AppListState state, const gfx::Rect& contents_bounds, @@ -718,8 +696,4 @@ return size; } -void SearchResultPageView::OnAnchoredDialogClosed() { - anchored_dialog_.reset(); -} - } // namespace ash
diff --git a/ash/app_list/views/search_result_page_view.h b/ash/app_list/views/search_result_page_view.h index 62304c7..5f9d76079 100644 --- a/ash/app_list/views/search_result_page_view.h +++ b/ash/app_list/views/search_result_page_view.h
@@ -16,6 +16,7 @@ #include "ash/app_list/views/app_list_page.h" #include "ash/app_list/views/result_selection_controller.h" #include "ash/app_list/views/search_result_container_view.h" +#include "ash/app_list/views/search_result_page_dialog_controller.h" #include "ash/ash_export.h" #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" @@ -69,7 +70,6 @@ void OnThemeChanged() override; // AppListPage overrides: - void OnWillBeHidden() override; void OnHidden() override; void OnShown() override; void AnimateYPosition(AppListViewState target_view_state, @@ -78,9 +78,6 @@ void UpdatePageOpacityForState(AppListState state, float search_box_opacity, bool restore_opacity) override; - void UpdatePageBoundsForState(AppListState state, - const gfx::Rect& contents_bounds, - const gfx::Rect& search_box_bounds) override; gfx::Rect GetPageBoundsForState( AppListState state, const gfx::Rect& contents_bounds, @@ -119,8 +116,12 @@ return result_selection_controller_.get(); } - SearchResultPageAnchoredDialog* anchored_dialog_for_test() { - return anchored_dialog_.get(); + ProductivityLauncherSearchView* productivity_launcher_search_view_for_test() { + return productivity_launcher_search_view_; + } + + SearchResultPageAnchoredDialog* dialog_for_test() { + return dialog_controller_->dialog(); } // Returns background color for the given state. @@ -173,9 +174,6 @@ // selected search result view. void NotifySelectedResultChanged(); - // Called when the widget anchored in the search results page gets closed. - void OnAnchoredDialogClosed(); - template <typename T> T* AddSearchResultContainerView(std::unique_ptr<T> result_container) { auto* result = result_container.get(); @@ -225,8 +223,8 @@ std::unique_ptr<ViewShadow> view_shadow_; - // The dialog anchored within the search results page. - std::unique_ptr<SearchResultPageAnchoredDialog> anchored_dialog_; + // The controller that manages dialogs modal to the search results page. + std::unique_ptr<SearchResultPageDialogController> dialog_controller_; base::ScopedObservation<SearchBoxModel, SearchBoxModelObserver> search_box_observation_{this};
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc index c4f3830..4811c606 100644 --- a/ash/app_list/views/search_result_view.cc +++ b/ash/app_list/views/search_result_view.cc
@@ -115,11 +115,14 @@ SearchResult::IconShape shape_; }; -SearchResultView::SearchResultView(SearchResultListView* list_view, - AppListViewDelegate* view_delegate, - SearchResultViewType view_type) +SearchResultView::SearchResultView( + SearchResultListView* list_view, + AppListViewDelegate* view_delegate, + SearchResultPageDialogController* dialog_controller, + SearchResultViewType view_type) : list_view_(list_view), view_delegate_(view_delegate), + dialog_controller_(dialog_controller), view_type_(view_type) { SetFocusBehavior(FocusBehavior::ALWAYS); // TODO(crbug.com/1218186): Remove this, this is in place temporarily to be @@ -579,10 +582,7 @@ result()->title(), base::BindOnce(&SearchResultView::OnQueryRemovalAccepted, weak_ptr_factory_.GetWeakPtr())); - list_view_->app_list_main_view() - ->contents_view() - ->search_result_page_view() - ->ShowAnchoredDialog(std::move(dialog)); + dialog_controller_->Show(std::move(dialog)); break; } case SearchResultActionType::kAppend:
diff --git a/ash/app_list/views/search_result_view.h b/ash/app_list/views/search_result_view.h index 5143234..cd18df5d 100644 --- a/ash/app_list/views/search_result_view.h +++ b/ash/app_list/views/search_result_view.h
@@ -36,6 +36,7 @@ class MaskedImageView; class SearchResult; class SearchResultListView; +class SearchResultPageDialogController; // SearchResultView displays a SearchResult. class ASH_EXPORT SearchResultView : public SearchResultBaseView, @@ -58,6 +59,7 @@ SearchResultView(SearchResultListView* list_view, AppListViewDelegate* view_delegate, + SearchResultPageDialogController* dialog_controller, SearchResultViewType view_type); SearchResultView(const SearchResultView&) = delete; @@ -134,9 +136,11 @@ bool IsRichImage() const; // Parent list view. Owned by views hierarchy. - SearchResultListView* list_view_; + SearchResultListView* const list_view_; - AppListViewDelegate* view_delegate_; + AppListViewDelegate* const view_delegate_; + + SearchResultPageDialogController* const dialog_controller_; MaskedImageView* icon_ = nullptr; // Owned by views hierarchy. views::ImageView* badge_icon_ = nullptr; // Owned by views hierarchy.
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 37674ea..b8be117 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -3698,6 +3698,12 @@ <message name="IDS_ASH_VIRTUAL_DESKS_ALERT_WINDOW_MOVED_FROM_ACTIVE_DESK" desc="A window in active desk got be moved to another virtual desk."> Window <ph name="WINDOW_TITLE">$1<ex>Files</ex></ph> moved from Desk <ph name="ACTIVE_DESK">$2</ph> to Desk <ph name="TARGET_DESK">$3</ph> </message> + <message name="IDS_ASH_VIRTUAL_DESKS_ASSIGNED_TO_ALL_DESKS" desc="A window is assigned to all desks."> + Window <ph name="WINDOW_TITLE">$1<ex>Files</ex></ph> assigned to all desks. + </message> + <message name="IDS_ASH_VIRTUAL_DESKS_UNASSIGNED_FROM_ALL_DESKS" desc="A window is unassigned from all desks."> + Window <ph name="WINDOW_TITLE">$1<ex>Files</ex></ph> unassigned from all desks. + </message> <!-- Alt Tab --> <message name="IDS_ASH_ALT_TAB_ALL_DESKS_MODE" desc="Alt-tab shows windows from all desks.">
diff --git a/ash/ash_strings_grd/IDS_ASH_VIRTUAL_DESKS_ASSIGNED_TO_ALL_DESKS.png.sha1 b/ash/ash_strings_grd/IDS_ASH_VIRTUAL_DESKS_ASSIGNED_TO_ALL_DESKS.png.sha1 new file mode 100644 index 0000000..79978d2 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_VIRTUAL_DESKS_ASSIGNED_TO_ALL_DESKS.png.sha1
@@ -0,0 +1 @@ +8c49dac608aa13f0faeb8259aec37eff9f8b10d9 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_VIRTUAL_DESKS_UNASSIGNED_FROM_ALL_DESKS.png.sha1 b/ash/ash_strings_grd/IDS_ASH_VIRTUAL_DESKS_UNASSIGNED_FROM_ALL_DESKS.png.sha1 new file mode 100644 index 0000000..6d2434c --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_VIRTUAL_DESKS_UNASSIGNED_FROM_ALL_DESKS.png.sha1
@@ -0,0 +1 @@ +b76c52fc3fc71747d435989ece54ad73fc54207b \ No newline at end of file
diff --git a/ash/components/arc/BUILD.gn b/ash/components/arc/BUILD.gn index 071c221..ea812ea 100644 --- a/ash/components/arc/BUILD.gn +++ b/ash/components/arc/BUILD.gn
@@ -2,6 +2,126 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +static_library("arc") { + sources = [ + "appfuse/arc_appfuse_bridge.cc", + "appfuse/arc_appfuse_bridge.h", + "audio/arc_audio_bridge.cc", + "audio/arc_audio_bridge.h", + "bluetooth/bluetooth_type_converters.cc", + "bluetooth/bluetooth_type_converters.h", + "camera/arc_camera_bridge.cc", + "camera/arc_camera_bridge.h", + "clipboard/arc_clipboard_bridge.cc", + "clipboard/arc_clipboard_bridge.h", + "compat_mode/arc_resize_lock_manager.cc", + "compat_mode/arc_resize_lock_manager.h", + "compat_mode/arc_resize_lock_pref_delegate.h", + "compat_mode/arc_splash_screen_dialog_view.cc", + "compat_mode/arc_splash_screen_dialog_view.h", + "compat_mode/arc_window_property_util.cc", + "compat_mode/arc_window_property_util.h", + "compat_mode/compat_mode_button_controller.cc", + "compat_mode/compat_mode_button_controller.h", + "compat_mode/metrics.cc", + "compat_mode/metrics.h", + "compat_mode/overlay_dialog.cc", + "compat_mode/overlay_dialog.h", + "compat_mode/resize_confirmation_dialog_view.cc", + "compat_mode/resize_confirmation_dialog_view.h", + "compat_mode/resize_toggle_menu.cc", + "compat_mode/resize_toggle_menu.h", + "compat_mode/resize_util.cc", + "compat_mode/resize_util.h", + "compat_mode/style/arc_color_provider.cc", + "compat_mode/style/arc_color_provider.h", + "compat_mode/touch_mode_mouse_rewriter.cc", + "compat_mode/touch_mode_mouse_rewriter.h", + "crash_collector/arc_crash_collector_bridge.cc", + "crash_collector/arc_crash_collector_bridge.h", + "dark_theme/arc_dark_theme_bridge.cc", + "dark_theme/arc_dark_theme_bridge.h", + "disk_quota/arc_disk_quota_bridge.cc", + "disk_quota/arc_disk_quota_bridge.h", + ] + + public_deps = [ + ":arc_base", + ":arc_metrics_constants", + ":prefs", + ] + + deps = [ + "//ash", + "//ash/components/audio", + "//ash/constants", + "//ash/keyboard/ui", + "//ash/public/cpp", + "//base", + "//chromeos/components/sensors:sensors", + "//chromeos/cryptohome", + "//chromeos/dbus", + "//chromeos/dbus/cryptohome", + "//chromeos/dbus/permission_broker", + "//chromeos/dbus/power", + "//chromeos/dbus/power:power_manager_proto", + "//chromeos/dbus/resourced", + "//chromeos/dbus/session_manager", + "//chromeos/dbus/session_manager:login_manager_proto", + "//chromeos/dbus/upstart", + "//chromeos/dbus/userdataauth", + "//chromeos/dbus/userdataauth:userdataauth_proto", + "//chromeos/disks", + "//chromeos/login/login_state", + "//chromeos/network", + "//chromeos/ui/base", + "//chromeos/ui/frame", + "//components/account_id", + "//components/arc/enterprise", + "//components/arc/input_overlay/resources:resources_grit", + "//components/arc/vector_icons", + "//components/exo", + "//components/google/core/common", + "//components/guest_os", + "//components/keyed_service/core", + "//components/onc", + "//components/prefs", + "//components/strings:components_strings_grit", + + # TODO(crbug.com/853604): After fully migrating the intent picker to query + # directly from App Service, we will deprecated the match functionality + # in intent_filter and this dependency will be removed. + "//components/services/app_service/public/cpp:intents", + "//components/session_manager/core", + "//components/url_formatter", + "//components/user_manager", + "//components/user_prefs", + "//components/vector_icons", + "//content/public/browser", + "//content/public/common", + "//device/bluetooth", + "//google_apis", + "//media/capture:capture_lib", + "//services/device/public/mojom", + "//skia", + "//third_party/re2", + "//ui/aura", + "//ui/base", + "//ui/base/clipboard", + "//ui/base/ime", + "//ui/base/ime/ash", + "//ui/chromeos/strings", + "//ui/chromeos/styles:cros_styles_views_generator", + "//ui/display/manager", + "//ui/events", + "//ui/events:dom_keycode_converter", + "//ui/events/ozone", + "//ui/gfx", + "//ui/wm/public", + "//url", + ] +} + static_library("prefs") { sources = [ "arc_export.h", @@ -202,3 +322,125 @@ source_set("arc_metrics_constants") { sources = [ "metrics/arc_metrics_constants.h" ] } + +source_set("unit_tests") { + testonly = true + sources = [ + "appfuse/arc_appfuse_bridge_unittest.cc", + "arc_features_parser_unittest.cc", + "arc_util_unittest.cc", + "audio/arc_audio_bridge_unittest.cc", + "bluetooth/bluetooth_mojom_traits_unittest.cc", + "bluetooth/bluetooth_type_converters_unittest.cc", + "camera/arc_camera_bridge_unittest.cc", + "clipboard/arc_clipboard_bridge_unittest.cc", + "compat_mode/arc_resize_lock_manager_unittest.cc", + "compat_mode/arc_splash_screen_dialog_view_unittest.cc", + "compat_mode/compat_mode_button_controller_unittest.cc", + "compat_mode/overlay_dialog_unittest.cc", + "compat_mode/resize_confirmation_dialog_view_unittest.cc", + "compat_mode/resize_toggle_menu_unittest.cc", + "compat_mode/resize_util_unittest.cc", + "compat_mode/touch_mode_mouse_rewriter_unittest.cc", + "crash_collector/arc_crash_collector_bridge_unittest.cc", + "dark_theme/arc_dark_theme_bridge_unittest.cc", + "disk_quota/arc_disk_quota_bridge_unittest.cc", + "enterprise/arc_data_remove_requested_pref_handler_unittest.cc", + "enterprise/arc_data_snapshotd_bridge_unittest.cc", + "enterprise/arc_data_snapshotd_manager_unittest.cc", + "enterprise/snapshot_hours_policy_service_unittest.cc", + "enterprise/snapshot_reboot_controller_unittest.cc", + "enterprise/snapshot_session_controller_unittest.cc", + "ime/arc_ime_service_unittest.cc", + "ime/key_event_result_receiver_unittest.cc", + "input_overlay/actions/action_move_key_unittest.cc", + "input_overlay/actions/action_tap_key_unittest.cc", + "input_overlay/actions/dependent_position_unittest.cc", + "input_overlay/actions/position_unittest.cc", + "input_overlay/arc_input_overlay_manager_unittest.cc", + "input_overlay/resources/input_overlay_resources_util_unittest.cc", + "input_overlay/touch_id_manager_unittest.cc", + "input_overlay/touch_injector_unittest.cc", + "intent_helper/activity_icon_loader_unittest.cc", + "intent_helper/arc_intent_helper_bridge_unittest.cc", + "intent_helper/custom_tab_unittest.cc", + "intent_helper/intent_filter_unittest.cc", + "intent_helper/link_handler_model_unittest.cc", + "lock_screen/arc_lock_screen_bridge_unittest.cc", + "media_session/arc_media_session_bridge_unittest.cc", + "memory/arc_memory_bridge_unittest.cc", + "memory_pressure/arc_memory_pressure_bridge_unittest.cc", + "metrics/arc_metrics_service_unittest.cc", + "metrics/stability_metrics_manager_unittest.cc", + "midis/arc_midis_bridge_unittest.cc", + "net/always_on_vpn_manager_unittest.cc", + "net/arc_net_host_impl_unittest.cc", + "pay/arc_payment_app_bridge_unittest.cc", + "power/arc_power_bridge_unittest.cc", + "property/arc_property_bridge_unittest.cc", + "rotation_lock/arc_rotation_lock_bridge_unittest.cc", + "sensor/arc_iio_sensor_bridge_unittest.cc", + "storage_manager/arc_storage_manager_unittest.cc", + "timer/arc_timer_bridge_unittest.cc", + "usb/usb_host_bridge_unittest.cc", + "video_accelerator/arc_video_accelerator_util_unittest.cc", + "volume_mounter/arc_volume_mounter_bridge_unittest.cc", + "wake_lock/arc_wake_lock_bridge_unittest.cc", + ] + + deps = [ + "//ash/components/arc:arc_test_support", + "//ash/constants", + "//ash/keyboard/ui", + "//ash/public/cpp", + "//base", + "//base/test:test_support", + "//chromeos", + "//chromeos/policy", + "//chromeos/cryptohome:cryptohome", + "//chromeos/dbus:test_support", + "//chromeos/dbus/dlcservice", + "//chromeos/dbus/permission_broker", + "//chromeos/dbus/power", + "//chromeos/dbus/power:power_manager_proto", + "//chromeos/dbus/resourced:resourced", + "//chromeos/dbus/session_manager", + "//chromeos/dbus/session_manager:login_manager_proto", + "//chromeos/dbus/tpm_manager:tpm_manager", + "//chromeos/dbus/upstart", + "//chromeos/disks:test_support", + "//chromeos/network:test_support", + "//chromeos/ui/frame", + "//components/account_id", + "//components/arc/enterprise", + "//components/arc/media_session", + "//components/arc/video_accelerator:common", + "//components/exo", + "//components/exo:test_support", + "//components/keyed_service/content", + "//components/prefs:test_support", + "//components/session_manager/core:core", + "//components/user_manager", + "//components/user_manager:test_support", + "//content/public/common", + "//content/test:test_support", + "//device/bluetooth", + "//mojo/public/cpp/system:system", + "//services/device/public/cpp:test_support", + "//services/device/public/mojom", + "//testing/gmock", + "//testing/gtest", + "//ui/aura", + "//ui/aura:test_support", + "//ui/base:test_support", + "//ui/base/clipboard", + "//ui/base/ime", + "//ui/events", + "//ui/events:dom_keycode_converter", + "//ui/events:test_support", + "//ui/ozone", + "//ui/views", + "//ui/views:test_support", + "//url:url", + ] +}
diff --git a/ash/components/arc/DEPS b/ash/components/arc/DEPS index b4cf28c..948a87f 100644 --- a/ash/components/arc/DEPS +++ b/ash/components/arc/DEPS
@@ -57,4 +57,7 @@ ".*_unittest.cc": [ "+content/public/test/browser_task_environment.h" ], + "arc_volume_mounter_bridge_unittest.cc": [ + "+chromeos/disks", + ], }
diff --git a/components/arc/appfuse/OWNERS b/ash/components/arc/appfuse/OWNERS similarity index 100% rename from components/arc/appfuse/OWNERS rename to ash/components/arc/appfuse/OWNERS
diff --git a/components/arc/appfuse/arc_appfuse_bridge.cc b/ash/components/arc/appfuse/arc_appfuse_bridge.cc similarity index 98% rename from components/arc/appfuse/arc_appfuse_bridge.cc rename to ash/components/arc/appfuse/arc_appfuse_bridge.cc index e0a8066..8c62d87 100644 --- a/components/arc/appfuse/arc_appfuse_bridge.cc +++ b/ash/components/arc/appfuse/arc_appfuse_bridge.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/appfuse/arc_appfuse_bridge.h" +#include "ash/components/arc/appfuse/arc_appfuse_bridge.h" #include <sys/epoll.h>
diff --git a/components/arc/appfuse/arc_appfuse_bridge.h b/ash/components/arc/appfuse/arc_appfuse_bridge.h similarity index 90% rename from components/arc/appfuse/arc_appfuse_bridge.h rename to ash/components/arc/appfuse/arc_appfuse_bridge.h index a60ef3a0..34e1ee75 100644 --- a/components/arc/appfuse/arc_appfuse_bridge.h +++ b/ash/components/arc/appfuse/arc_appfuse_bridge.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_APPFUSE_ARC_APPFUSE_BRIDGE_H_ -#define COMPONENTS_ARC_APPFUSE_ARC_APPFUSE_BRIDGE_H_ +#ifndef ASH_COMPONENTS_ARC_APPFUSE_ARC_APPFUSE_BRIDGE_H_ +#define ASH_COMPONENTS_ARC_APPFUSE_ARC_APPFUSE_BRIDGE_H_ #include <stdint.h> @@ -53,4 +53,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_APPFUSE_ARC_APPFUSE_BRIDGE_H_ +#endif // ASH_COMPONENTS_ARC_APPFUSE_ARC_APPFUSE_BRIDGE_H_
diff --git a/components/arc/appfuse/arc_appfuse_bridge_unittest.cc b/ash/components/arc/appfuse/arc_appfuse_bridge_unittest.cc similarity index 94% rename from components/arc/appfuse/arc_appfuse_bridge_unittest.cc rename to ash/components/arc/appfuse/arc_appfuse_bridge_unittest.cc index 539ff47..531d2e5 100644 --- a/components/arc/appfuse/arc_appfuse_bridge_unittest.cc +++ b/ash/components/arc/appfuse/arc_appfuse_bridge_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/appfuse/arc_appfuse_bridge.h" +#include "ash/components/arc/appfuse/arc_appfuse_bridge.h" #include "ash/components/arc/test/test_browser_context.h" #include "components/arc/session/arc_service_manager.h"
diff --git a/components/arc/arc_features_parser_unittest.cc b/ash/components/arc/arc_features_parser_unittest.cc similarity index 100% rename from components/arc/arc_features_parser_unittest.cc rename to ash/components/arc/arc_features_parser_unittest.cc
diff --git a/components/arc/arc_util_unittest.cc b/ash/components/arc/arc_util_unittest.cc similarity index 100% rename from components/arc/arc_util_unittest.cc rename to ash/components/arc/arc_util_unittest.cc
diff --git a/components/arc/audio/DEPS b/ash/components/arc/audio/DEPS similarity index 100% rename from components/arc/audio/DEPS rename to ash/components/arc/audio/DEPS
diff --git a/components/arc/audio/arc_audio_bridge.cc b/ash/components/arc/audio/arc_audio_bridge.cc similarity index 98% rename from components/arc/audio/arc_audio_bridge.cc rename to ash/components/arc/audio/arc_audio_bridge.cc index 556c034..b0f343e 100644 --- a/components/arc/audio/arc_audio_bridge.cc +++ b/ash/components/arc/audio/arc_audio_bridge.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/audio/arc_audio_bridge.h" +#include "ash/components/arc/audio/arc_audio_bridge.h" #include <utility>
diff --git a/components/arc/audio/arc_audio_bridge.h b/ash/components/arc/audio/arc_audio_bridge.h similarity index 93% rename from components/arc/audio/arc_audio_bridge.h rename to ash/components/arc/audio/arc_audio_bridge.h index 8fa01533..8c9526d 100644 --- a/components/arc/audio/arc_audio_bridge.h +++ b/ash/components/arc/audio/arc_audio_bridge.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_AUDIO_ARC_AUDIO_BRIDGE_H_ -#define COMPONENTS_ARC_AUDIO_ARC_AUDIO_BRIDGE_H_ +#ifndef ASH_COMPONENTS_ARC_AUDIO_ARC_AUDIO_BRIDGE_H_ +#define ASH_COMPONENTS_ARC_AUDIO_ARC_AUDIO_BRIDGE_H_ #include "ash/components/audio/cras_audio_handler.h" #include "components/arc/mojom/audio.mojom.h" @@ -68,4 +68,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_AUDIO_ARC_AUDIO_BRIDGE_H_ +#endif // ASH_COMPONENTS_ARC_AUDIO_ARC_AUDIO_BRIDGE_H_
diff --git a/components/arc/audio/arc_audio_bridge_unittest.cc b/ash/components/arc/audio/arc_audio_bridge_unittest.cc similarity index 95% rename from components/arc/audio/arc_audio_bridge_unittest.cc rename to ash/components/arc/audio/arc_audio_bridge_unittest.cc index da731036..7cc6d5b 100644 --- a/components/arc/audio/arc_audio_bridge_unittest.cc +++ b/ash/components/arc/audio/arc_audio_bridge_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/audio/arc_audio_bridge.h" +#include "ash/components/arc/audio/arc_audio_bridge.h" #include "ash/components/arc/test/test_browser_context.h" #include "components/arc/session/arc_service_manager.h"
diff --git a/components/arc/bluetooth/DEPS b/ash/components/arc/bluetooth/DEPS similarity index 100% rename from components/arc/bluetooth/DEPS rename to ash/components/arc/bluetooth/DEPS
diff --git a/components/arc/bluetooth/OWNERS b/ash/components/arc/bluetooth/OWNERS similarity index 100% rename from components/arc/bluetooth/OWNERS rename to ash/components/arc/bluetooth/OWNERS
diff --git a/components/arc/bluetooth/bluetooth_mojom_traits.cc b/ash/components/arc/bluetooth/bluetooth_mojom_traits.cc similarity index 98% rename from components/arc/bluetooth/bluetooth_mojom_traits.cc rename to ash/components/arc/bluetooth/bluetooth_mojom_traits.cc index 05bb3c9c..6e54537 100644 --- a/components/arc/bluetooth/bluetooth_mojom_traits.cc +++ b/ash/components/arc/bluetooth/bluetooth_mojom_traits.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/bluetooth/bluetooth_mojom_traits.h" +#include "ash/components/arc/bluetooth/bluetooth_mojom_traits.h" #include <initializer_list> #include <map>
diff --git a/components/arc/bluetooth/bluetooth_mojom_traits.h b/ash/components/arc/bluetooth/bluetooth_mojom_traits.h similarity index 96% rename from components/arc/bluetooth/bluetooth_mojom_traits.h rename to ash/components/arc/bluetooth/bluetooth_mojom_traits.h index c696fc8..1f9a0a7 100644 --- a/components/arc/bluetooth/bluetooth_mojom_traits.h +++ b/ash/components/arc/bluetooth/bluetooth_mojom_traits.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_MOJOM_TRAITS_H_ -#define COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_MOJOM_TRAITS_H_ +#ifndef ASH_COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_MOJOM_TRAITS_H_ +#define ASH_COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_MOJOM_TRAITS_H_ #include <memory> #include <vector> @@ -133,4 +133,4 @@ } // namespace mojo -#endif // COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_MOJOM_TRAITS_H_ +#endif // ASH_COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_MOJOM_TRAITS_H_
diff --git a/components/arc/bluetooth/bluetooth_mojom_traits_unittest.cc b/ash/components/arc/bluetooth/bluetooth_mojom_traits_unittest.cc similarity index 98% rename from components/arc/bluetooth/bluetooth_mojom_traits_unittest.cc rename to ash/components/arc/bluetooth/bluetooth_mojom_traits_unittest.cc index 7c517224..90273ad 100644 --- a/components/arc/bluetooth/bluetooth_mojom_traits_unittest.cc +++ b/ash/components/arc/bluetooth/bluetooth_mojom_traits_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/bluetooth/bluetooth_mojom_traits.h" +#include "ash/components/arc/bluetooth/bluetooth_mojom_traits.h" #include <string> #include <utility>
diff --git a/components/arc/bluetooth/bluetooth_type_converters.cc b/ash/components/arc/bluetooth/bluetooth_type_converters.cc similarity index 98% rename from components/arc/bluetooth/bluetooth_type_converters.cc rename to ash/components/arc/bluetooth/bluetooth_type_converters.cc index ea5c86c..88724e7 100644 --- a/components/arc/bluetooth/bluetooth_type_converters.cc +++ b/ash/components/arc/bluetooth/bluetooth_type_converters.cc
@@ -10,10 +10,10 @@ #include <string> #include <vector> +#include "ash/components/arc/bluetooth/bluetooth_type_converters.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/strings/utf_string_conversions.h" -#include "components/arc/bluetooth/bluetooth_type_converters.h" #include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_gatt_service.h" #include "device/bluetooth/public/cpp/bluetooth_address.h" @@ -39,7 +39,6 @@ arc::mojom::BluetoothAddressPtr TypeConverter<arc::mojom::BluetoothAddressPtr, std::string>::Convert( const std::string& address) { - arc::mojom::BluetoothAddressPtr mojo_addr = arc::mojom::BluetoothAddress::New();
diff --git a/components/arc/bluetooth/bluetooth_type_converters.h b/ash/components/arc/bluetooth/bluetooth_type_converters.h similarity index 93% rename from components/arc/bluetooth/bluetooth_type_converters.h rename to ash/components/arc/bluetooth/bluetooth_type_converters.h index d9f18bc5..fe7a7142 100644 --- a/components/arc/bluetooth/bluetooth_type_converters.h +++ b/ash/components/arc/bluetooth/bluetooth_type_converters.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_TYPE_CONVERTERS_H_ -#define COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_TYPE_CONVERTERS_H_ +#ifndef ASH_COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_TYPE_CONVERTERS_H_ +#define ASH_COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_TYPE_CONVERTERS_H_ #include <bluetooth/bluetooth.h> #include <stddef.h> @@ -91,4 +91,4 @@ } // namespace mojo -#endif // COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_TYPE_CONVERTERS_H_ +#endif // ASH_COMPONENTS_ARC_BLUETOOTH_BLUETOOTH_TYPE_CONVERTERS_H_
diff --git a/components/arc/bluetooth/bluetooth_type_converters_unittest.cc b/ash/components/arc/bluetooth/bluetooth_type_converters_unittest.cc similarity index 99% rename from components/arc/bluetooth/bluetooth_type_converters_unittest.cc rename to ash/components/arc/bluetooth/bluetooth_type_converters_unittest.cc index d30d5c10..1b2fc8a 100644 --- a/components/arc/bluetooth/bluetooth_type_converters_unittest.cc +++ b/ash/components/arc/bluetooth/bluetooth_type_converters_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/bluetooth/bluetooth_type_converters.h" +#include "ash/components/arc/bluetooth/bluetooth_type_converters.h" #include <algorithm> #include <memory>
diff --git a/components/arc/camera/DEPS b/ash/components/arc/camera/DEPS similarity index 100% rename from components/arc/camera/DEPS rename to ash/components/arc/camera/DEPS
diff --git a/components/arc/camera/OWNERS b/ash/components/arc/camera/OWNERS similarity index 100% rename from components/arc/camera/OWNERS rename to ash/components/arc/camera/OWNERS
diff --git a/components/arc/camera/arc_camera_bridge.cc b/ash/components/arc/camera/arc_camera_bridge.cc similarity index 98% rename from components/arc/camera/arc_camera_bridge.cc rename to ash/components/arc/camera/arc_camera_bridge.cc index febe5d0..a78406c 100644 --- a/components/arc/camera/arc_camera_bridge.cc +++ b/ash/components/arc/camera/arc_camera_bridge.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/camera/arc_camera_bridge.h" +#include "ash/components/arc/camera/arc_camera_bridge.h" #include <utility>
diff --git a/components/arc/camera/arc_camera_bridge.h b/ash/components/arc/camera/arc_camera_bridge.h similarity index 91% rename from components/arc/camera/arc_camera_bridge.h rename to ash/components/arc/camera/arc_camera_bridge.h index a59c0205..669f452a 100644 --- a/components/arc/camera/arc_camera_bridge.h +++ b/ash/components/arc/camera/arc_camera_bridge.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_CAMERA_ARC_CAMERA_BRIDGE_H_ -#define COMPONENTS_ARC_CAMERA_ARC_CAMERA_BRIDGE_H_ +#ifndef ASH_COMPONENTS_ARC_CAMERA_ARC_CAMERA_BRIDGE_H_ +#define ASH_COMPONENTS_ARC_CAMERA_ARC_CAMERA_BRIDGE_H_ #include <map> #include <memory> @@ -58,4 +58,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_CAMERA_ARC_CAMERA_BRIDGE_H_ +#endif // ASH_COMPONENTS_ARC_CAMERA_ARC_CAMERA_BRIDGE_H_
diff --git a/components/arc/camera/arc_camera_bridge_unittest.cc b/ash/components/arc/camera/arc_camera_bridge_unittest.cc similarity index 94% rename from components/arc/camera/arc_camera_bridge_unittest.cc rename to ash/components/arc/camera/arc_camera_bridge_unittest.cc index 12c6d0c..a723921 100644 --- a/components/arc/camera/arc_camera_bridge_unittest.cc +++ b/ash/components/arc/camera/arc_camera_bridge_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/camera/arc_camera_bridge.h" +#include "ash/components/arc/camera/arc_camera_bridge.h" #include "ash/components/arc/test/test_browser_context.h" #include "components/arc/session/arc_service_manager.h"
diff --git a/components/arc/clipboard/DEPS b/ash/components/arc/clipboard/DEPS similarity index 100% rename from components/arc/clipboard/DEPS rename to ash/components/arc/clipboard/DEPS
diff --git a/components/arc/clipboard/arc_clipboard_bridge.cc b/ash/components/arc/clipboard/arc_clipboard_bridge.cc similarity index 98% rename from components/arc/clipboard/arc_clipboard_bridge.cc rename to ash/components/arc/clipboard/arc_clipboard_bridge.cc index 52e8407..d98b1f0 100644 --- a/components/arc/clipboard/arc_clipboard_bridge.cc +++ b/ash/components/arc/clipboard/arc_clipboard_bridge.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/clipboard/arc_clipboard_bridge.h" +#include "ash/components/arc/clipboard/arc_clipboard_bridge.h" #include <memory> #include <utility>
diff --git a/components/arc/clipboard/arc_clipboard_bridge.h b/ash/components/arc/clipboard/arc_clipboard_bridge.h similarity index 89% rename from components/arc/clipboard/arc_clipboard_bridge.h rename to ash/components/arc/clipboard/arc_clipboard_bridge.h index c0d3b563..03e0b1c1 100644 --- a/components/arc/clipboard/arc_clipboard_bridge.h +++ b/ash/components/arc/clipboard/arc_clipboard_bridge.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_CLIPBOARD_ARC_CLIPBOARD_BRIDGE_H_ -#define COMPONENTS_ARC_CLIPBOARD_ARC_CLIPBOARD_BRIDGE_H_ +#ifndef ASH_COMPONENTS_ARC_CLIPBOARD_ARC_CLIPBOARD_BRIDGE_H_ +#define ASH_COMPONENTS_ARC_CLIPBOARD_ARC_CLIPBOARD_BRIDGE_H_ #include "base/threading/thread_checker.h" #include "components/arc/mojom/clipboard.mojom.h" @@ -52,4 +52,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_CLIPBOARD_ARC_CLIPBOARD_BRIDGE_H_ +#endif // ASH_COMPONENTS_ARC_CLIPBOARD_ARC_CLIPBOARD_BRIDGE_H_
diff --git a/components/arc/clipboard/arc_clipboard_bridge_unittest.cc b/ash/components/arc/clipboard/arc_clipboard_bridge_unittest.cc similarity index 98% rename from components/arc/clipboard/arc_clipboard_bridge_unittest.cc rename to ash/components/arc/clipboard/arc_clipboard_bridge_unittest.cc index c0d831b..05483412 100644 --- a/components/arc/clipboard/arc_clipboard_bridge_unittest.cc +++ b/ash/components/arc/clipboard/arc_clipboard_bridge_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/clipboard/arc_clipboard_bridge.h" +#include "ash/components/arc/clipboard/arc_clipboard_bridge.h" #include <memory> #include <utility>
diff --git a/components/arc/compat_mode/DEPS b/ash/components/arc/compat_mode/DEPS similarity index 100% rename from components/arc/compat_mode/DEPS rename to ash/components/arc/compat_mode/DEPS
diff --git a/components/arc/compat_mode/arc_resize_lock_manager.cc b/ash/components/arc/compat_mode/arc_resize_lock_manager.cc similarity index 96% rename from components/arc/compat_mode/arc_resize_lock_manager.cc rename to ash/components/arc/compat_mode/arc_resize_lock_manager.cc index 4ab1f51..ff43f92 100644 --- a/components/arc/compat_mode/arc_resize_lock_manager.cc +++ b/ash/components/arc/compat_mode/arc_resize_lock_manager.cc
@@ -2,10 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/arc_resize_lock_manager.h" +#include "ash/components/arc/compat_mode/arc_resize_lock_manager.h" #include "ash/components/arc/arc_browser_context_keyed_service_factory_base.h" #include "ash/components/arc/arc_features.h" +#include "ash/components/arc/compat_mode/arc_splash_screen_dialog_view.h" +#include "ash/components/arc/compat_mode/arc_window_property_util.h" +#include "ash/components/arc/compat_mode/compat_mode_button_controller.h" +#include "ash/components/arc/compat_mode/metrics.h" +#include "ash/components/arc/compat_mode/touch_mode_mouse_rewriter.h" #include "ash/public/cpp/app_types_util.h" #include "ash/public/cpp/arc_resize_lock_type.h" #include "ash/public/cpp/resize_shadow_type.h" @@ -17,11 +22,6 @@ #include "base/memory/singleton.h" #include "base/memory/weak_ptr.h" #include "base/notreached.h" -#include "components/arc/compat_mode/arc_splash_screen_dialog_view.h" -#include "components/arc/compat_mode/arc_window_property_util.h" -#include "components/arc/compat_mode/compat_mode_button_controller.h" -#include "components/arc/compat_mode/metrics.h" -#include "components/arc/compat_mode/touch_mode_mouse_rewriter.h" #include "ui/aura/window_observer.h" #include "ui/aura/window_tree_host.h" #include "ui/wm/public/activation_client.h"
diff --git a/components/arc/compat_mode/arc_resize_lock_manager.h b/ash/components/arc/compat_mode/arc_resize_lock_manager.h similarity index 88% rename from components/arc/compat_mode/arc_resize_lock_manager.h rename to ash/components/arc/compat_mode/arc_resize_lock_manager.h index a0d7bfc..afd55c8 100644 --- a/components/arc/compat_mode/arc_resize_lock_manager.h +++ b/ash/components/arc/compat_mode/arc_resize_lock_manager.h
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_MANAGER_H_ -#define COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_MANAGER_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_MANAGER_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_MANAGER_H_ +#include "ash/components/arc/compat_mode/arc_resize_lock_pref_delegate.h" +#include "ash/components/arc/compat_mode/compat_mode_button_controller.h" #include "base/scoped_multi_source_observation.h" #include "base/scoped_observation.h" -#include "components/arc/compat_mode/arc_resize_lock_pref_delegate.h" -#include "components/arc/compat_mode/compat_mode_button_controller.h" #include "components/keyed_service/core/keyed_service.h" #include "ui/aura/env.h" #include "ui/aura/env_observer.h" @@ -83,4 +83,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_MANAGER_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_MANAGER_H_
diff --git a/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc b/ash/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc similarity index 99% rename from components/arc/compat_mode/arc_resize_lock_manager_unittest.cc rename to ash/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc index 4c90c547..2124051 100644 --- a/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc +++ b/ash/components/arc/compat_mode/arc_resize_lock_manager_unittest.cc
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/arc_resize_lock_manager.h" +#include "ash/components/arc/compat_mode/arc_resize_lock_manager.h" #include <memory> #include <string> +#include "ash/components/arc/compat_mode/metrics.h" #include "ash/components/arc/compat_mode/test/compat_mode_test_base.h" #include "ash/constants/app_types.h" #include "ash/public/cpp/arc_resize_lock_type.h" @@ -16,7 +17,6 @@ #include "base/callback_forward.h" #include "base/test/bind.h" #include "base/test/metrics/histogram_tester.h" -#include "components/arc/compat_mode/metrics.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h"
diff --git a/components/arc/compat_mode/arc_resize_lock_pref_delegate.h b/ash/components/arc/compat_mode/arc_resize_lock_pref_delegate.h similarity index 81% rename from components/arc/compat_mode/arc_resize_lock_pref_delegate.h rename to ash/components/arc/compat_mode/arc_resize_lock_pref_delegate.h index 204a1f2..6393447 100644 --- a/components/arc/compat_mode/arc_resize_lock_pref_delegate.h +++ b/ash/components/arc/compat_mode/arc_resize_lock_pref_delegate.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_PREF_DELEGATE_H_ -#define COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_PREF_DELEGATE_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_PREF_DELEGATE_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_PREF_DELEGATE_H_ #include <string> @@ -28,4 +28,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_PREF_DELEGATE_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_RESIZE_LOCK_PREF_DELEGATE_H_
diff --git a/components/arc/compat_mode/arc_splash_screen_dialog_view.cc b/ash/components/arc/compat_mode/arc_splash_screen_dialog_view.cc similarity index 98% rename from components/arc/compat_mode/arc_splash_screen_dialog_view.cc rename to ash/components/arc/compat_mode/arc_splash_screen_dialog_view.cc index 28370ae9..40d7118 100644 --- a/components/arc/compat_mode/arc_splash_screen_dialog_view.cc +++ b/ash/components/arc/compat_mode/arc_splash_screen_dialog_view.cc
@@ -2,18 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/arc_splash_screen_dialog_view.h" +#include "ash/components/arc/compat_mode/arc_splash_screen_dialog_view.h" #include <memory> +#include "ash/components/arc/compat_mode/overlay_dialog.h" +#include "ash/components/arc/compat_mode/style/arc_color_provider.h" #include "ash/frame/non_client_frame_view_ash.h" #include "base/auto_reset.h" #include "base/bind.h" #include "base/callback_helpers.h" #include "base/scoped_multi_source_observation.h" #include "chromeos/ui/frame/default_frame_header.h" -#include "components/arc/compat_mode/overlay_dialog.h" -#include "components/arc/compat_mode/style/arc_color_provider.h" #include "components/arc/vector_icons/vector_icons.h" #include "components/strings/grit/components_strings.h" #include "components/vector_icons/vector_icons.h"
diff --git a/components/arc/compat_mode/arc_splash_screen_dialog_view.h b/ash/components/arc/compat_mode/arc_splash_screen_dialog_view.h similarity index 92% rename from components/arc/compat_mode/arc_splash_screen_dialog_view.h rename to ash/components/arc/compat_mode/arc_splash_screen_dialog_view.h index 228fb93..267cee7 100644 --- a/components/arc/compat_mode/arc_splash_screen_dialog_view.h +++ b/ash/components/arc/compat_mode/arc_splash_screen_dialog_view.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_ARC_SPLASH_SCREEN_DIALOG_VIEW_H_ -#define COMPONENTS_ARC_COMPAT_MODE_ARC_SPLASH_SCREEN_DIALOG_VIEW_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_SPLASH_SCREEN_DIALOG_VIEW_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_SPLASH_SCREEN_DIALOG_VIEW_H_ #include "base/callback_forward.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" @@ -84,4 +84,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_ARC_SPLASH_SCREEN_DIALOG_VIEW_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_SPLASH_SCREEN_DIALOG_VIEW_H_
diff --git a/components/arc/compat_mode/arc_splash_screen_dialog_view_unittest.cc b/ash/components/arc/compat_mode/arc_splash_screen_dialog_view_unittest.cc similarity index 98% rename from components/arc/compat_mode/arc_splash_screen_dialog_view_unittest.cc rename to ash/components/arc/compat_mode/arc_splash_screen_dialog_view_unittest.cc index e68e944e..a21e192 100644 --- a/components/arc/compat_mode/arc_splash_screen_dialog_view_unittest.cc +++ b/ash/components/arc/compat_mode/arc_splash_screen_dialog_view_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/arc_splash_screen_dialog_view.h" +#include "ash/components/arc/compat_mode/arc_splash_screen_dialog_view.h" #include <memory>
diff --git a/components/arc/compat_mode/arc_window_property_util.cc b/ash/components/arc/compat_mode/arc_window_property_util.cc similarity index 90% rename from components/arc/compat_mode/arc_window_property_util.cc rename to ash/components/arc/compat_mode/arc_window_property_util.cc index 3c66eb9..627180c 100644 --- a/components/arc/compat_mode/arc_window_property_util.cc +++ b/ash/components/arc/compat_mode/arc_window_property_util.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/arc_window_property_util.h" +#include "ash/components/arc/compat_mode/arc_window_property_util.h" #include <string>
diff --git a/components/arc/compat_mode/arc_window_property_util.h b/ash/components/arc/compat_mode/arc_window_property_util.h similarity index 71% rename from components/arc/compat_mode/arc_window_property_util.h rename to ash/components/arc/compat_mode/arc_window_property_util.h index bfe4115..01cb528 100644 --- a/components/arc/compat_mode/arc_window_property_util.h +++ b/ash/components/arc/compat_mode/arc_window_property_util.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_ARC_WINDOW_PROPERTY_UTIL_H_ -#define COMPONENTS_ARC_COMPAT_MODE_ARC_WINDOW_PROPERTY_UTIL_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_WINDOW_PROPERTY_UTIL_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_WINDOW_PROPERTY_UTIL_H_ #include "third_party/abseil-cpp/absl/types/optional.h" @@ -22,4 +22,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_ARC_WINDOW_PROPERTY_UTIL_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_ARC_WINDOW_PROPERTY_UTIL_H_
diff --git a/components/arc/compat_mode/compat_mode_button_controller.cc b/ash/components/arc/compat_mode/compat_mode_button_controller.cc similarity index 95% rename from components/arc/compat_mode/compat_mode_button_controller.cc rename to ash/components/arc/compat_mode/compat_mode_button_controller.cc index f2245b4..d1bca09b 100644 --- a/components/arc/compat_mode/compat_mode_button_controller.cc +++ b/ash/components/arc/compat_mode/compat_mode_button_controller.cc
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/compat_mode_button_controller.h" +#include "ash/components/arc/compat_mode/compat_mode_button_controller.h" #include <string> +#include "ash/components/arc/compat_mode/arc_resize_lock_pref_delegate.h" +#include "ash/components/arc/compat_mode/arc_window_property_util.h" +#include "ash/components/arc/compat_mode/resize_util.h" #include "ash/frame/non_client_frame_view_ash.h" #include "ash/public/cpp/app_types_util.h" #include "ash/public/cpp/arc_resize_lock_type.h" @@ -14,9 +17,6 @@ #include "base/bind.h" #include "base/callback_forward.h" #include "chromeos/ui/frame/default_frame_header.h" -#include "components/arc/compat_mode/arc_resize_lock_pref_delegate.h" -#include "components/arc/compat_mode/arc_window_property_util.h" -#include "components/arc/compat_mode/resize_util.h" #include "components/arc/vector_icons/vector_icons.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/components/arc/compat_mode/compat_mode_button_controller.h b/ash/components/arc/compat_mode/compat_mode_button_controller.h similarity index 83% rename from components/arc/compat_mode/compat_mode_button_controller.h rename to ash/components/arc/compat_mode/compat_mode_button_controller.h index 81dad89..eaec83c 100644 --- a/components/arc/compat_mode/compat_mode_button_controller.h +++ b/ash/components/arc/compat_mode/compat_mode_button_controller.h
@@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_COMPAT_MODE_BUTTON_CONTROLLER_H_ -#define COMPONENTS_ARC_COMPAT_MODE_COMPAT_MODE_BUTTON_CONTROLLER_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_COMPAT_MODE_BUTTON_CONTROLLER_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_COMPAT_MODE_BUTTON_CONTROLLER_H_ #include <memory> +#include "ash/components/arc/compat_mode/resize_toggle_menu.h" #include "base/memory/weak_ptr.h" -#include "components/arc/compat_mode/resize_toggle_menu.h" namespace ash { enum class ArcResizeLockType; @@ -57,4 +57,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_COMPAT_MODE_BUTTON_CONTROLLER_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_COMPAT_MODE_BUTTON_CONTROLLER_H_
diff --git a/components/arc/compat_mode/compat_mode_button_controller_unittest.cc b/ash/components/arc/compat_mode/compat_mode_button_controller_unittest.cc similarity index 97% rename from components/arc/compat_mode/compat_mode_button_controller_unittest.cc rename to ash/components/arc/compat_mode/compat_mode_button_controller_unittest.cc index 8e77a8f..71dfa155 100644 --- a/components/arc/compat_mode/compat_mode_button_controller_unittest.cc +++ b/ash/components/arc/compat_mode/compat_mode_button_controller_unittest.cc
@@ -2,16 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/compat_mode_button_controller.h" +#include "ash/components/arc/compat_mode/compat_mode_button_controller.h" #include <memory> #include <string> +#include "ash/components/arc/compat_mode/resize_util.h" #include "ash/components/arc/compat_mode/test/compat_mode_test_base.h" #include "ash/constants/app_types.h" #include "ash/public/cpp/window_properties.h" #include "chromeos/ui/frame/default_frame_header.h" -#include "components/arc/compat_mode/resize_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/aura/client/aura_constants.h" #include "ui/gfx/color_palette.h"
diff --git a/components/arc/compat_mode/metrics.cc b/ash/components/arc/compat_mode/metrics.cc similarity index 96% rename from components/arc/compat_mode/metrics.cc rename to ash/components/arc/compat_mode/metrics.cc index 6dbabefc..4dbfa18 100644 --- a/components/arc/compat_mode/metrics.cc +++ b/ash/components/arc/compat_mode/metrics.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/metrics.h" +#include "ash/components/arc/compat_mode/metrics.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/user_metrics.h"
diff --git a/components/arc/compat_mode/metrics.h b/ash/components/arc/compat_mode/metrics.h similarity index 83% rename from components/arc/compat_mode/metrics.h rename to ash/components/arc/compat_mode/metrics.h index fe4f587..171be2f 100644 --- a/components/arc/compat_mode/metrics.h +++ b/ash/components/arc/compat_mode/metrics.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_METRICS_H_ -#define COMPONENTS_ARC_COMPAT_MODE_METRICS_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_METRICS_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_METRICS_H_ #include "components/arc/mojom/compatibility_mode.mojom.h" @@ -31,4 +31,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_METRICS_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_METRICS_H_
diff --git a/components/arc/compat_mode/overlay_dialog.cc b/ash/components/arc/compat_mode/overlay_dialog.cc similarity index 94% rename from components/arc/compat_mode/overlay_dialog.cc rename to ash/components/arc/compat_mode/overlay_dialog.cc index d55f40e..3693b3c 100644 --- a/components/arc/compat_mode/overlay_dialog.cc +++ b/ash/components/arc/compat_mode/overlay_dialog.cc
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/overlay_dialog.h" +#include "ash/components/arc/compat_mode/overlay_dialog.h" +#include "ash/components/arc/compat_mode/style/arc_color_provider.h" #include "base/bind.h" -#include "components/arc/compat_mode/style/arc_color_provider.h" #include "components/exo/shell_surface_base.h" #include "components/exo/shell_surface_util.h" #include "ui/base/metadata/metadata_impl_macros.h"
diff --git a/components/arc/compat_mode/overlay_dialog.h b/ash/components/arc/compat_mode/overlay_dialog.h similarity index 90% rename from components/arc/compat_mode/overlay_dialog.h rename to ash/components/arc/compat_mode/overlay_dialog.h index 8d9cd71..758b284 100644 --- a/components/arc/compat_mode/overlay_dialog.h +++ b/ash/components/arc/compat_mode/overlay_dialog.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_OVERLAY_DIALOG_H_ -#define COMPONENTS_ARC_COMPAT_MODE_OVERLAY_DIALOG_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_OVERLAY_DIALOG_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_OVERLAY_DIALOG_H_ #include <memory> @@ -59,4 +59,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_OVERLAY_DIALOG_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_OVERLAY_DIALOG_H_
diff --git a/components/arc/compat_mode/overlay_dialog_unittest.cc b/ash/components/arc/compat_mode/overlay_dialog_unittest.cc similarity index 95% rename from components/arc/compat_mode/overlay_dialog_unittest.cc rename to ash/components/arc/compat_mode/overlay_dialog_unittest.cc index f9916cb..b27c64e4 100644 --- a/components/arc/compat_mode/overlay_dialog_unittest.cc +++ b/ash/components/arc/compat_mode/overlay_dialog_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/overlay_dialog.h" +#include "ash/components/arc/compat_mode/overlay_dialog.h" #include <memory>
diff --git a/components/arc/compat_mode/resize_confirmation_dialog_view.cc b/ash/components/arc/compat_mode/resize_confirmation_dialog_view.cc similarity index 96% rename from components/arc/compat_mode/resize_confirmation_dialog_view.cc rename to ash/components/arc/compat_mode/resize_confirmation_dialog_view.cc index 5dc298a6..2d3afe8 100644 --- a/components/arc/compat_mode/resize_confirmation_dialog_view.cc +++ b/ash/components/arc/compat_mode/resize_confirmation_dialog_view.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/resize_confirmation_dialog_view.h" +#include "ash/components/arc/compat_mode/resize_confirmation_dialog_view.h" #include <memory> +#include "ash/components/arc/compat_mode/overlay_dialog.h" +#include "ash/components/arc/compat_mode/style/arc_color_provider.h" #include "base/bind.h" #include "base/callback_helpers.h" -#include "components/arc/compat_mode/overlay_dialog.h" -#include "components/arc/compat_mode/style/arc_color_provider.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/color/color_id.h"
diff --git a/components/arc/compat_mode/resize_confirmation_dialog_view.h b/ash/components/arc/compat_mode/resize_confirmation_dialog_view.h similarity index 90% rename from components/arc/compat_mode/resize_confirmation_dialog_view.h rename to ash/components/arc/compat_mode/resize_confirmation_dialog_view.h index bc9e1a49..863d057f 100644 --- a/components/arc/compat_mode/resize_confirmation_dialog_view.h +++ b/ash/components/arc/compat_mode/resize_confirmation_dialog_view.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_RESIZE_CONFIRMATION_DIALOG_VIEW_H_ -#define COMPONENTS_ARC_COMPAT_MODE_RESIZE_CONFIRMATION_DIALOG_VIEW_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_RESIZE_CONFIRMATION_DIALOG_VIEW_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_RESIZE_CONFIRMATION_DIALOG_VIEW_H_ #include "base/callback_forward.h" #include "ui/views/layout/box_layout_view.h" @@ -72,4 +72,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_RESIZE_CONFIRMATION_DIALOG_VIEW_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_RESIZE_CONFIRMATION_DIALOG_VIEW_H_
diff --git a/components/arc/compat_mode/resize_confirmation_dialog_view_unittest.cc b/ash/components/arc/compat_mode/resize_confirmation_dialog_view_unittest.cc similarity index 97% rename from components/arc/compat_mode/resize_confirmation_dialog_view_unittest.cc rename to ash/components/arc/compat_mode/resize_confirmation_dialog_view_unittest.cc index 8ac3e88d..2acf098d 100644 --- a/components/arc/compat_mode/resize_confirmation_dialog_view_unittest.cc +++ b/ash/components/arc/compat_mode/resize_confirmation_dialog_view_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/resize_confirmation_dialog_view.h" +#include "ash/components/arc/compat_mode/resize_confirmation_dialog_view.h" #include <memory>
diff --git a/components/arc/compat_mode/resize_toggle_menu.cc b/ash/components/arc/compat_mode/resize_toggle_menu.cc similarity index 98% rename from components/arc/compat_mode/resize_toggle_menu.cc rename to ash/components/arc/compat_mode/resize_toggle_menu.cc index 4ac223bf..cb1bf971 100644 --- a/components/arc/compat_mode/resize_toggle_menu.cc +++ b/ash/components/arc/compat_mode/resize_toggle_menu.cc
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/resize_toggle_menu.h" +#include "ash/components/arc/compat_mode/resize_toggle_menu.h" +#include "ash/components/arc/compat_mode/overlay_dialog.h" +#include "ash/components/arc/compat_mode/style/arc_color_provider.h" #include "ash/public/cpp/window_properties.h" #include "ash/resources/vector_icons/vector_icons.h" #include "base/bind.h" #include "base/check.h" #include "base/notreached.h" -#include "components/arc/compat_mode/overlay_dialog.h" -#include "components/arc/compat_mode/style/arc_color_provider.h" #include "components/arc/vector_icons/vector_icons.h" #include "components/strings/grit/components_strings.h" #include "ui/aura/client/aura_constants.h"
diff --git a/components/arc/compat_mode/resize_toggle_menu.h b/ash/components/arc/compat_mode/resize_toggle_menu.h similarity index 92% rename from components/arc/compat_mode/resize_toggle_menu.h rename to ash/components/arc/compat_mode/resize_toggle_menu.h index e22cc7c..b3eb77b 100644 --- a/components/arc/compat_mode/resize_toggle_menu.h +++ b/ash/components/arc/compat_mode/resize_toggle_menu.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_RESIZE_TOGGLE_MENU_H_ -#define COMPONENTS_ARC_COMPAT_MODE_RESIZE_TOGGLE_MENU_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_RESIZE_TOGGLE_MENU_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_RESIZE_TOGGLE_MENU_H_ #include <memory> +#include "ash/components/arc/compat_mode/resize_util.h" #include "base/callback_forward.h" #include "base/cancelable_callback.h" #include "base/scoped_multi_source_observation.h" -#include "components/arc/compat_mode/resize_util.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" #include "ui/views/controls/button/button.h" @@ -117,4 +117,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_RESIZE_TOGGLE_MENU_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_RESIZE_TOGGLE_MENU_H_
diff --git a/components/arc/compat_mode/resize_toggle_menu_unittest.cc b/ash/components/arc/compat_mode/resize_toggle_menu_unittest.cc similarity index 97% rename from components/arc/compat_mode/resize_toggle_menu_unittest.cc rename to ash/components/arc/compat_mode/resize_toggle_menu_unittest.cc index 22ca365..69ca134 100644 --- a/components/arc/compat_mode/resize_toggle_menu_unittest.cc +++ b/ash/components/arc/compat_mode/resize_toggle_menu_unittest.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/resize_toggle_menu.h" +#include "ash/components/arc/compat_mode/resize_toggle_menu.h" #include <memory> +#include "ash/components/arc/compat_mode/arc_resize_lock_pref_delegate.h" +#include "ash/components/arc/compat_mode/metrics.h" #include "ash/components/arc/compat_mode/test/compat_mode_test_base.h" #include "base/test/metrics/user_action_tester.h" -#include "components/arc/compat_mode/arc_resize_lock_pref_delegate.h" -#include "components/arc/compat_mode/metrics.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/controls/button/button.h"
diff --git a/components/arc/compat_mode/resize_util.cc b/ash/components/arc/compat_mode/resize_util.cc similarity index 95% rename from components/arc/compat_mode/resize_util.cc rename to ash/components/arc/compat_mode/resize_util.cc index c9c187f..b39ff627 100644 --- a/components/arc/compat_mode/resize_util.cc +++ b/ash/components/arc/compat_mode/resize_util.cc
@@ -2,10 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/resize_util.h" +#include "ash/components/arc/compat_mode/resize_util.h" #include <memory> +#include "ash/components/arc/compat_mode/arc_resize_lock_pref_delegate.h" +#include "ash/components/arc/compat_mode/arc_window_property_util.h" +#include "ash/components/arc/compat_mode/metrics.h" +#include "ash/components/arc/compat_mode/resize_confirmation_dialog_view.h" #include "ash/public/cpp/arc_resize_lock_type.h" #include "ash/public/cpp/toast_data.h" #include "ash/public/cpp/toast_manager.h" @@ -13,10 +17,6 @@ #include "base/callback_forward.h" #include "base/callback_helpers.h" #include "base/stl_util.h" -#include "components/arc/compat_mode/arc_resize_lock_pref_delegate.h" -#include "components/arc/compat_mode/arc_window_property_util.h" -#include "components/arc/compat_mode/metrics.h" -#include "components/arc/compat_mode/resize_confirmation_dialog_view.h" #include "components/exo/shell_surface_base.h" #include "components/exo/shell_surface_util.h" #include "components/strings/grit/components_strings.h"
diff --git a/components/arc/compat_mode/resize_util.h b/ash/components/arc/compat_mode/resize_util.h similarity index 86% rename from components/arc/compat_mode/resize_util.h rename to ash/components/arc/compat_mode/resize_util.h index b38ffd8..e8031c325 100644 --- a/components/arc/compat_mode/resize_util.h +++ b/ash/components/arc/compat_mode/resize_util.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_RESIZE_UTIL_H_ -#define COMPONENTS_ARC_COMPAT_MODE_RESIZE_UTIL_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_RESIZE_UTIL_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_RESIZE_UTIL_H_ #include "third_party/abseil-cpp/absl/types/optional.h" @@ -42,4 +42,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_RESIZE_UTIL_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_RESIZE_UTIL_H_
diff --git a/components/arc/compat_mode/resize_util_unittest.cc b/ash/components/arc/compat_mode/resize_util_unittest.cc similarity index 98% rename from components/arc/compat_mode/resize_util_unittest.cc rename to ash/components/arc/compat_mode/resize_util_unittest.cc index fd9cbb2..f83bd302b2 100644 --- a/components/arc/compat_mode/resize_util_unittest.cc +++ b/ash/components/arc/compat_mode/resize_util_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/resize_util.h" +#include "ash/components/arc/compat_mode/resize_util.h" #include <memory>
diff --git a/components/arc/compat_mode/style/arc_color_provider.cc b/ash/components/arc/compat_mode/style/arc_color_provider.cc similarity index 96% rename from components/arc/compat_mode/style/arc_color_provider.cc rename to ash/components/arc/compat_mode/style/arc_color_provider.cc index 2388950..bcfee87 100644 --- a/components/arc/compat_mode/style/arc_color_provider.cc +++ b/ash/components/arc/compat_mode/style/arc_color_provider.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/style/arc_color_provider.h" +#include "ash/components/arc/compat_mode/style/arc_color_provider.h" #include "ash/constants/ash_features.h" #include "ash/public/cpp/style/scoped_light_mode_as_default.h"
diff --git a/components/arc/compat_mode/style/arc_color_provider.h b/ash/components/arc/compat_mode/style/arc_color_provider.h similarity index 80% rename from components/arc/compat_mode/style/arc_color_provider.h rename to ash/components/arc/compat_mode/style/arc_color_provider.h index 3d0dbe8..81606cff 100644 --- a/components/arc/compat_mode/style/arc_color_provider.h +++ b/ash/components/arc/compat_mode/style/arc_color_provider.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_STYLE_ARC_COLOR_PROVIDER_H_ -#define COMPONENTS_ARC_COMPAT_MODE_STYLE_ARC_COLOR_PROVIDER_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_STYLE_ARC_COLOR_PROVIDER_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_STYLE_ARC_COLOR_PROVIDER_H_ #include "ash/public/cpp/style/color_provider.h" #include "ui/chromeos/styles/cros_styles.h" @@ -30,4 +30,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_STYLE_ARC_COLOR_PROVIDER_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_STYLE_ARC_COLOR_PROVIDER_H_
diff --git a/ash/components/arc/compat_mode/test/compat_mode_test_base.cc b/ash/components/arc/compat_mode/test/compat_mode_test_base.cc index 590767f1..bb75fb3 100644 --- a/ash/components/arc/compat_mode/test/compat_mode_test_base.cc +++ b/ash/components/arc/compat_mode/test/compat_mode_test_base.cc
@@ -4,10 +4,10 @@ #include "ash/components/arc/compat_mode/test/compat_mode_test_base.h" +#include "ash/components/arc/compat_mode/arc_window_property_util.h" #include "ash/constants/app_types.h" #include "ash/public/cpp/window_properties.h" #include "base/containers/flat_map.h" -#include "components/arc/compat_mode/arc_window_property_util.h" #include "ui/aura/client/aura_constants.h" #include "ui/events/base_event_utils.h" #include "ui/events/test/event_generator.h"
diff --git a/ash/components/arc/compat_mode/test/compat_mode_test_base.h b/ash/components/arc/compat_mode/test/compat_mode_test_base.h index 83525aa3..ebaedc1 100644 --- a/ash/components/arc/compat_mode/test/compat_mode_test_base.h +++ b/ash/components/arc/compat_mode/test/compat_mode_test_base.h
@@ -8,7 +8,7 @@ #include <memory> #include <string> -#include "components/arc/compat_mode/arc_resize_lock_pref_delegate.h" +#include "ash/components/arc/compat_mode/arc_resize_lock_pref_delegate.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/display/test/scoped_screen_override.h" #include "ui/display/test/test_screen.h"
diff --git a/components/arc/compat_mode/touch_mode_mouse_rewriter.cc b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.cc similarity index 98% rename from components/arc/compat_mode/touch_mode_mouse_rewriter.cc rename to ash/components/arc/compat_mode/touch_mode_mouse_rewriter.cc index 6e325323..3da596c 100644 --- a/components/arc/compat_mode/touch_mode_mouse_rewriter.cc +++ b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/touch_mode_mouse_rewriter.h" +#include "ash/components/arc/compat_mode/touch_mode_mouse_rewriter.h" #include "ash/components/arc/arc_features.h" #include "ash/shell.h"
diff --git a/components/arc/compat_mode/touch_mode_mouse_rewriter.h b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.h similarity index 92% rename from components/arc/compat_mode/touch_mode_mouse_rewriter.h rename to ash/components/arc/compat_mode/touch_mode_mouse_rewriter.h index 568018dd..2cf5f1c 100644 --- a/components/arc/compat_mode/touch_mode_mouse_rewriter.h +++ b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_COMPAT_MODE_TOUCH_MODE_MOUSE_REWRITER_H_ -#define COMPONENTS_ARC_COMPAT_MODE_TOUCH_MODE_MOUSE_REWRITER_H_ +#ifndef ASH_COMPONENTS_ARC_COMPAT_MODE_TOUCH_MODE_MOUSE_REWRITER_H_ +#define ASH_COMPONENTS_ARC_COMPAT_MODE_TOUCH_MODE_MOUSE_REWRITER_H_ #include <set> @@ -75,4 +75,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_COMPAT_MODE_TOUCH_MODE_MOUSE_REWRITER_H_ +#endif // ASH_COMPONENTS_ARC_COMPAT_MODE_TOUCH_MODE_MOUSE_REWRITER_H_
diff --git a/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc similarity index 99% rename from components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc rename to ash/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc index 0eb6d6b..01ad069 100644 --- a/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc +++ b/ash/components/arc/compat_mode/touch_mode_mouse_rewriter_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/compat_mode/touch_mode_mouse_rewriter.h" +#include "ash/components/arc/compat_mode/touch_mode_mouse_rewriter.h" #include "ash/components/arc/arc_features.h" #include "base/run_loop.h"
diff --git a/components/arc/crash_collector/arc_crash_collector_bridge.cc b/ash/components/arc/crash_collector/arc_crash_collector_bridge.cc similarity index 98% rename from components/arc/crash_collector/arc_crash_collector_bridge.cc rename to ash/components/arc/crash_collector/arc_crash_collector_bridge.cc index 64fb58a4..6ec1948 100644 --- a/components/arc/crash_collector/arc_crash_collector_bridge.cc +++ b/ash/components/arc/crash_collector/arc_crash_collector_bridge.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/crash_collector/arc_crash_collector_bridge.h" +#include "ash/components/arc/crash_collector/arc_crash_collector_bridge.h" #include <inttypes.h> #include <sysexits.h>
diff --git a/components/arc/crash_collector/arc_crash_collector_bridge.h b/ash/components/arc/crash_collector/arc_crash_collector_bridge.h similarity index 85% rename from components/arc/crash_collector/arc_crash_collector_bridge.h rename to ash/components/arc/crash_collector/arc_crash_collector_bridge.h index 5f70ac6..2abde18 100644 --- a/components/arc/crash_collector/arc_crash_collector_bridge.h +++ b/ash/components/arc/crash_collector/arc_crash_collector_bridge.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_CRASH_COLLECTOR_ARC_CRASH_COLLECTOR_BRIDGE_H_ -#define COMPONENTS_ARC_CRASH_COLLECTOR_ARC_CRASH_COLLECTOR_BRIDGE_H_ +#ifndef ASH_COMPONENTS_ARC_CRASH_COLLECTOR_ARC_CRASH_COLLECTOR_BRIDGE_H_ +#define ASH_COMPONENTS_ARC_CRASH_COLLECTOR_ARC_CRASH_COLLECTOR_BRIDGE_H_ #include <string> @@ -20,9 +20,8 @@ class ArcBridgeService; // Relays dumps for non-native ARC crashes to the crash reporter in Chrome OS. -class ArcCrashCollectorBridge - : public KeyedService, - public mojom::CrashCollectorHost { +class ArcCrashCollectorBridge : public KeyedService, + public mojom::CrashCollectorHost { public: // Returns singleton instance for the given BrowserContext, // or nullptr if the browser |context| is not allowed to use ARC. @@ -67,4 +66,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_CRASH_COLLECTOR_ARC_CRASH_COLLECTOR_BRIDGE_H_ +#endif // ASH_COMPONENTS_ARC_CRASH_COLLECTOR_ARC_CRASH_COLLECTOR_BRIDGE_H_
diff --git a/components/arc/crash_collector/arc_crash_collector_bridge_unittest.cc b/ash/components/arc/crash_collector/arc_crash_collector_bridge_unittest.cc similarity index 97% rename from components/arc/crash_collector/arc_crash_collector_bridge_unittest.cc rename to ash/components/arc/crash_collector/arc_crash_collector_bridge_unittest.cc index 7a83ce5..5127b687 100644 --- a/components/arc/crash_collector/arc_crash_collector_bridge_unittest.cc +++ b/ash/components/arc/crash_collector/arc_crash_collector_bridge_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/crash_collector/arc_crash_collector_bridge.h" +#include "ash/components/arc/crash_collector/arc_crash_collector_bridge.h" #include <unistd.h>
diff --git a/components/arc/dark_theme/arc_dark_theme_bridge.cc b/ash/components/arc/dark_theme/arc_dark_theme_bridge.cc similarity index 98% rename from components/arc/dark_theme/arc_dark_theme_bridge.cc rename to ash/components/arc/dark_theme/arc_dark_theme_bridge.cc index bf835618..3714de4 100644 --- a/components/arc/dark_theme/arc_dark_theme_bridge.cc +++ b/ash/components/arc/dark_theme/arc_dark_theme_bridge.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/dark_theme/arc_dark_theme_bridge.h" +#include "ash/components/arc/dark_theme/arc_dark_theme_bridge.h" #include "ash/components/arc/arc_browser_context_keyed_service_factory_base.h" #include "ash/constants/ash_features.h"
diff --git a/components/arc/dark_theme/arc_dark_theme_bridge.h b/ash/components/arc/dark_theme/arc_dark_theme_bridge.h similarity index 91% rename from components/arc/dark_theme/arc_dark_theme_bridge.h rename to ash/components/arc/dark_theme/arc_dark_theme_bridge.h index fdf7a23..9d592c7 100644 --- a/components/arc/dark_theme/arc_dark_theme_bridge.h +++ b/ash/components/arc/dark_theme/arc_dark_theme_bridge.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_DARK_THEME_ARC_DARK_THEME_BRIDGE_H_ -#define COMPONENTS_ARC_DARK_THEME_ARC_DARK_THEME_BRIDGE_H_ +#ifndef ASH_COMPONENTS_ARC_DARK_THEME_ARC_DARK_THEME_BRIDGE_H_ +#define ASH_COMPONENTS_ARC_DARK_THEME_ARC_DARK_THEME_BRIDGE_H_ #include "ash/public/cpp/style/color_mode_observer.h" #include "base/threading/thread_checker.h" @@ -59,4 +59,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_DARK_THEME_ARC_DARK_THEME_BRIDGE_H_ +#endif // ASH_COMPONENTS_ARC_DARK_THEME_ARC_DARK_THEME_BRIDGE_H_
diff --git a/components/arc/dark_theme/arc_dark_theme_bridge_unittest.cc b/ash/components/arc/dark_theme/arc_dark_theme_bridge_unittest.cc similarity index 96% rename from components/arc/dark_theme/arc_dark_theme_bridge_unittest.cc rename to ash/components/arc/dark_theme/arc_dark_theme_bridge_unittest.cc index cfb594f0..d1adcba 100644 --- a/components/arc/dark_theme/arc_dark_theme_bridge_unittest.cc +++ b/ash/components/arc/dark_theme/arc_dark_theme_bridge_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/dark_theme/arc_dark_theme_bridge.h" +#include "ash/components/arc/dark_theme/arc_dark_theme_bridge.h" #include <memory>
diff --git a/components/arc/disk_quota/DEPS b/ash/components/arc/disk_quota/DEPS similarity index 100% rename from components/arc/disk_quota/DEPS rename to ash/components/arc/disk_quota/DEPS
diff --git a/components/arc/disk_quota/OWNERS b/ash/components/arc/disk_quota/OWNERS similarity index 100% rename from components/arc/disk_quota/OWNERS rename to ash/components/arc/disk_quota/OWNERS
diff --git a/components/arc/disk_quota/arc_disk_quota_bridge.cc b/ash/components/arc/disk_quota/arc_disk_quota_bridge.cc similarity index 98% rename from components/arc/disk_quota/arc_disk_quota_bridge.cc rename to ash/components/arc/disk_quota/arc_disk_quota_bridge.cc index abe527b3..f64fee7 100644 --- a/components/arc/disk_quota/arc_disk_quota_bridge.cc +++ b/ash/components/arc/disk_quota/arc_disk_quota_bridge.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/disk_quota/arc_disk_quota_bridge.h" +#include "ash/components/arc/disk_quota/arc_disk_quota_bridge.h" #include <utility>
diff --git a/components/arc/disk_quota/arc_disk_quota_bridge.h b/ash/components/arc/disk_quota/arc_disk_quota_bridge.h similarity index 92% rename from components/arc/disk_quota/arc_disk_quota_bridge.h rename to ash/components/arc/disk_quota/arc_disk_quota_bridge.h index e77c3df..a03ab239 100644 --- a/components/arc/disk_quota/arc_disk_quota_bridge.h +++ b/ash/components/arc/disk_quota/arc_disk_quota_bridge.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_ARC_DISK_QUOTA_ARC_DISK_QUOTA_BRIDGE_H_ -#define COMPONENTS_ARC_DISK_QUOTA_ARC_DISK_QUOTA_BRIDGE_H_ +#ifndef ASH_COMPONENTS_ARC_DISK_QUOTA_ARC_DISK_QUOTA_BRIDGE_H_ +#define ASH_COMPONENTS_ARC_DISK_QUOTA_ARC_DISK_QUOTA_BRIDGE_H_ #include "base/files/file_path.h" #include "chromeos/dbus/cryptohome/UserDataAuth.pb.h" @@ -72,4 +72,4 @@ } // namespace arc -#endif // COMPONENTS_ARC_DISK_QUOTA_ARC_DISK_QUOTA_BRIDGE_H_ +#endif // ASH_COMPONENTS_ARC_DISK_QUOTA_ARC_DISK_QUOTA_BRIDGE_H_
diff --git a/components/arc/disk_quota/arc_disk_quota_bridge_unittest.cc b/ash/components/arc/disk_quota/arc_disk_quota_bridge_unittest.cc similarity index 95% rename from components/arc/disk_quota/arc_disk_quota_bridge_unittest.cc rename to ash/components/arc/disk_quota/arc_disk_quota_bridge_unittest.cc index 03c3ed4..bb4d152 100644 --- a/components/arc/disk_quota/arc_disk_quota_bridge_unittest.cc +++ b/ash/components/arc/disk_quota/arc_disk_quota_bridge_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/arc/disk_quota/arc_disk_quota_bridge.h" +#include "ash/components/arc/disk_quota/arc_disk_quota_bridge.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/arc/enterprise/arc_data_remove_requested_pref_handler_unittest.cc b/ash/components/arc/enterprise/arc_data_remove_requested_pref_handler_unittest.cc similarity index 100% rename from components/arc/enterprise/arc_data_remove_requested_pref_handler_unittest.cc rename to ash/components/arc/enterprise/arc_data_remove_requested_pref_handler_unittest.cc
diff --git a/components/arc/enterprise/arc_data_snapshotd_bridge_unittest.cc b/ash/components/arc/enterprise/arc_data_snapshotd_bridge_unittest.cc similarity index 100% rename from components/arc/enterprise/arc_data_snapshotd_bridge_unittest.cc rename to ash/components/arc/enterprise/arc_data_snapshotd_bridge_unittest.cc
diff --git a/components/arc/enterprise/arc_data_snapshotd_manager_unittest.cc b/ash/components/arc/enterprise/arc_data_snapshotd_manager_unittest.cc similarity index 100% rename from components/arc/enterprise/arc_data_snapshotd_manager_unittest.cc rename to ash/components/arc/enterprise/arc_data_snapshotd_manager_unittest.cc
diff --git a/components/arc/enterprise/snapshot_hours_policy_service_unittest.cc b/ash/components/arc/enterprise/snapshot_hours_policy_service_unittest.cc similarity index 100% rename from components/arc/enterprise/snapshot_hours_policy_service_unittest.cc rename to ash/components/arc/enterprise/snapshot_hours_policy_service_unittest.cc
diff --git a/components/arc/enterprise/snapshot_reboot_controller_unittest.cc b/ash/components/arc/enterprise/snapshot_reboot_controller_unittest.cc similarity index 99% rename from components/arc/enterprise/snapshot_reboot_controller_unittest.cc rename to ash/components/arc/enterprise/snapshot_reboot_controller_unittest.cc index f689914..0dd99a4 100644 --- a/components/arc/enterprise/snapshot_reboot_controller_unittest.cc +++ b/ash/components/arc/enterprise/snapshot_reboot_controller_unittest.cc
@@ -63,6 +63,7 @@ } user_manager::FakeUserManager* user_manager() { return fake_user_manager_; } + private: base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME};
diff --git a/components/arc/enterprise/snapshot_session_controller_unittest.cc b/ash/components/arc/enterprise/snapshot_session_controller_unittest.cc similarity index 100% rename from components/arc/enterprise/snapshot_session_controller_unittest.cc rename to ash/components/arc/enterprise/snapshot_session_controller_unittest.cc
diff --git a/components/arc/ime/arc_ime_service_unittest.cc b/ash/components/arc/ime/arc_ime_service_unittest.cc similarity index 98% rename from components/arc/ime/arc_ime_service_unittest.cc rename to ash/components/arc/ime/arc_ime_service_unittest.cc index 349e20a..a17e6f0 100644 --- a/components/arc/ime/arc_ime_service_unittest.cc +++ b/ash/components/arc/ime/arc_ime_service_unittest.cc
@@ -40,8 +40,7 @@ void SendSetCompositionText(const ui::CompositionText& composition) override { } - void SendConfirmCompositionText() override { - } + void SendConfirmCompositionText() override {} void SendSelectionRange(const gfx::Range& selection_range) override { selection_range_ = selection_range; } @@ -49,8 +48,7 @@ int new_cursor_position) override { count_send_insert_text_++; } - void SendExtendSelectionAndDelete(size_t before, size_t after) override { - } + void SendExtendSelectionAndDelete(size_t before, size_t after) override {} void SendOnKeyboardAppearanceChanging(const gfx::Rect& new_bounds, bool is_available) override { last_keyboard_bounds_ = new_bounds; @@ -94,9 +92,7 @@ client_ = client; } - ui::TextInputClient* GetTextInputClient() const override { - return client_; - } + ui::TextInputClient* GetTextInputClient() const override { return client_; } void ShowVirtualKeyboardIfEnabled() override { count_show_ime_if_needed_++; } @@ -123,13 +119,9 @@ return ui::EventDispatchDetails(); } - int count_show_ime_if_needed() const { - return count_show_ime_if_needed_; - } + int count_show_ime_if_needed() const { return count_show_ime_if_needed_; } - int count_cancel_composition() const { - return count_cancel_composition_; - } + int count_cancel_composition() const { return count_cancel_composition_; } int count_set_focused_text_input_client() const { return count_set_focused_text_input_client_;
diff --git a/components/arc/ime/key_event_result_receiver_unittest.cc b/ash/components/arc/ime/key_event_result_receiver_unittest.cc similarity index 100% rename from components/arc/ime/key_event_result_receiver_unittest.cc rename to ash/components/arc/ime/key_event_result_receiver_unittest.cc
diff --git a/components/arc/input_overlay/actions/action_move_key_unittest.cc b/ash/components/arc/input_overlay/actions/action_move_key_unittest.cc similarity index 100% rename from components/arc/input_overlay/actions/action_move_key_unittest.cc rename to ash/components/arc/input_overlay/actions/action_move_key_unittest.cc
diff --git a/components/arc/input_overlay/actions/action_tap_key_unittest.cc b/ash/components/arc/input_overlay/actions/action_tap_key_unittest.cc similarity index 100% rename from components/arc/input_overlay/actions/action_tap_key_unittest.cc rename to ash/components/arc/input_overlay/actions/action_tap_key_unittest.cc
diff --git a/components/arc/input_overlay/actions/dependent_position_unittest.cc b/ash/components/arc/input_overlay/actions/dependent_position_unittest.cc similarity index 100% rename from components/arc/input_overlay/actions/dependent_position_unittest.cc rename to ash/components/arc/input_overlay/actions/dependent_position_unittest.cc
diff --git a/components/arc/input_overlay/actions/position_unittest.cc b/ash/components/arc/input_overlay/actions/position_unittest.cc similarity index 100% rename from components/arc/input_overlay/actions/position_unittest.cc rename to ash/components/arc/input_overlay/actions/position_unittest.cc
diff --git a/components/arc/input_overlay/arc_input_overlay_manager_unittest.cc b/ash/components/arc/input_overlay/arc_input_overlay_manager_unittest.cc similarity index 100% rename from components/arc/input_overlay/arc_input_overlay_manager_unittest.cc rename to ash/components/arc/input_overlay/arc_input_overlay_manager_unittest.cc
diff --git a/components/arc/input_overlay/resources/input_overlay_resources_util_unittest.cc b/ash/components/arc/input_overlay/resources/input_overlay_resources_util_unittest.cc similarity index 100% rename from components/arc/input_overlay/resources/input_overlay_resources_util_unittest.cc rename to ash/components/arc/input_overlay/resources/input_overlay_resources_util_unittest.cc
diff --git a/components/arc/input_overlay/touch_id_manager_unittest.cc b/ash/components/arc/input_overlay/touch_id_manager_unittest.cc similarity index 100% rename from components/arc/input_overlay/touch_id_manager_unittest.cc rename to ash/components/arc/input_overlay/touch_id_manager_unittest.cc
diff --git a/components/arc/input_overlay/touch_injector_unittest.cc b/ash/components/arc/input_overlay/touch_injector_unittest.cc similarity index 100% rename from components/arc/input_overlay/touch_injector_unittest.cc rename to ash/components/arc/input_overlay/touch_injector_unittest.cc
diff --git a/components/arc/intent_helper/activity_icon_loader_unittest.cc b/ash/components/arc/intent_helper/activity_icon_loader_unittest.cc similarity index 100% rename from components/arc/intent_helper/activity_icon_loader_unittest.cc rename to ash/components/arc/intent_helper/activity_icon_loader_unittest.cc
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc b/ash/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc similarity index 100% rename from components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc rename to ash/components/arc/intent_helper/arc_intent_helper_bridge_unittest.cc
diff --git a/components/arc/intent_helper/custom_tab_unittest.cc b/ash/components/arc/intent_helper/custom_tab_unittest.cc similarity index 100% rename from components/arc/intent_helper/custom_tab_unittest.cc rename to ash/components/arc/intent_helper/custom_tab_unittest.cc
diff --git a/components/arc/intent_helper/intent_filter_unittest.cc b/ash/components/arc/intent_helper/intent_filter_unittest.cc similarity index 86% rename from components/arc/intent_helper/intent_filter_unittest.cc rename to ash/components/arc/intent_helper/intent_filter_unittest.cc index 7ac86df..386bd04 100644 --- a/components/arc/intent_helper/intent_filter_unittest.cc +++ b/ash/components/arc/intent_helper/intent_filter_unittest.cc
@@ -58,22 +58,20 @@ TEST(IntentFilterTest, TestAuthorityEntry_empty) { // Empty URL shouldn't match a filter with an authority. - IntentFilter filter = IntentFilterBuilder() - .authority("authority1"); + IntentFilter filter = IntentFilterBuilder().authority("authority1"); EXPECT_FALSE(filter.Match(GURL())); // Empty URL shouldn't match a filter with an authority and port. - IntentFilter filter_port_100 = IntentFilterBuilder() - .authority("authority1", 100); + IntentFilter filter_port_100 = + IntentFilterBuilder().authority("authority1", 100); EXPECT_FALSE(filter_port_100.Match(GURL())); } TEST(IntentFilterTest, TestAuthorityEntry_simple) { // URL authority should match the filter authority. - IntentFilter filter = IntentFilterBuilder() - .authority("authority1"); + IntentFilter filter = IntentFilterBuilder().authority("authority1"); EXPECT_FALSE(filter.Match(GURL("http://authority2"))); EXPECT_FALSE(filter.Match(GURL("https://authority2"))); @@ -97,8 +95,7 @@ TEST(IntentFilterTest, TestAuthorityEntry_no_port) { // A filter with no port should accept matching authority URLs with any port. - IntentFilter filter_no_port = IntentFilterBuilder() - .authority("authority1"); + IntentFilter filter_no_port = IntentFilterBuilder().authority("authority1"); EXPECT_TRUE(filter_no_port.Match(GURL("http://authority1:0"))); EXPECT_TRUE(filter_no_port.Match(GURL("https://authority1:0"))); @@ -125,8 +122,8 @@ TEST(IntentFilterTest, TestAuthorityEntry_with_port) { // A filter with a specified port should only match URLs with that port. - IntentFilter filter_port_100 = IntentFilterBuilder() - .authority("authority1", 100); + IntentFilter filter_port_100 = + IntentFilterBuilder().authority("authority1", 100); EXPECT_FALSE(filter_port_100.Match(GURL("http://authority1"))); EXPECT_FALSE(filter_port_100.Match(GURL("https://authority1"))); @@ -148,8 +145,8 @@ // explicit ports. This diverges from android's intent filter behaviour. See // the IntentFilter::AuthorityEntry::match code for details. IntentFilter filter_default_port = IntentFilterBuilder() - .authority("authority1", 80) - .authority("authority1", 443); + .authority("authority1", 80) + .authority("authority1", 443); EXPECT_TRUE(filter_default_port.Match(GURL("http://authority1"))); EXPECT_TRUE(filter_default_port.Match(GURL("https://authority1"))); @@ -161,8 +158,8 @@ // A filter with multiple authorities should match URLs that match any of // those authorities. IntentFilter filter = IntentFilterBuilder() - .authority("authority1", 100) - .authority("authority2"); + .authority("authority1", 100) + .authority("authority2"); EXPECT_FALSE(filter.Match(GURL("http://authority1"))); EXPECT_FALSE(filter.Match(GURL("http://authority3"))); @@ -173,8 +170,7 @@ TEST(IntentFilterTest, TestAuthorityEntry_substring) { // Make sure substrings don't match in non-wildcard cases. - IntentFilter filter = IntentFilterBuilder() - .authority("authority1"); + IntentFilter filter = IntentFilterBuilder().authority("authority1"); EXPECT_FALSE(filter.Match(GURL("http://authority"))); EXPECT_FALSE(filter.Match(GURL("http://authority12"))); @@ -182,8 +178,7 @@ TEST(IntentFilterTest, TestAuthorityEntry_wild) { // Make sure wildcards work - IntentFilter filter = IntentFilterBuilder() - .authority("*.authority1"); + IntentFilter filter = IntentFilterBuilder().authority("*.authority1"); EXPECT_FALSE(filter.Match(GURL("http://.authority"))); EXPECT_FALSE(filter.Match(GURL("http://.authority12"))); @@ -196,9 +191,10 @@ } TEST(IntentFilterTest, TestDataPath_literal) { - IntentFilter filter = IntentFilterBuilder() - .authority("host.com") - .path("/path1", mojom::PatternType::PATTERN_LITERAL); + IntentFilter filter = + IntentFilterBuilder() + .authority("host.com") + .path("/path1", mojom::PatternType::PATTERN_LITERAL); // Empty paths, prefix-, and substring-matches should fail. EXPECT_FALSE(filter.Match(GURL())); @@ -223,8 +219,8 @@ TEST(IntentFilterTest, TestDataPath_prefix) { IntentFilter filter = IntentFilterBuilder() - .authority("host.com") - .path("/path1", mojom::PatternType::PATTERN_PREFIX); + .authority("host.com") + .path("/path1", mojom::PatternType::PATTERN_PREFIX); // Empty paths and substring-matches should fail. EXPECT_FALSE(filter.Match(GURL())); @@ -238,9 +234,10 @@ // Glob tests based loosely on android's CTS IntentFilterTest#testPaths. TEST(IntentFilterTest, TestDataPath_globSuffix) { - IntentFilter filter = IntentFilterBuilder() - .authority("host.com") - .path("/path1.*", mojom::PatternType::PATTERN_SIMPLE_GLOB); + IntentFilter filter = + IntentFilterBuilder() + .authority("host.com") + .path("/path1.*", mojom::PatternType::PATTERN_SIMPLE_GLOB); // Empty paths and substring-matches should fail. EXPECT_FALSE(filter.Match(GURL())); @@ -259,9 +256,10 @@ // Glob tests based loosely on android's CTS IntentFilterTest#testPaths. TEST(IntentFilterTest, TestDataPath_globInfix) { - IntentFilter filter = IntentFilterBuilder() - .authority("host.com") - .path("/a.*b", mojom::PatternType::PATTERN_SIMPLE_GLOB); + IntentFilter filter = + IntentFilterBuilder() + .authority("host.com") + .path("/a.*b", mojom::PatternType::PATTERN_SIMPLE_GLOB); // Empty paths and substring-matches should fail. EXPECT_FALSE(filter.Match(GURL())); @@ -293,9 +291,10 @@ // Glob tests based loosely on android's CTS IntentFilterTest#testPaths. TEST(IntentFilterTest, TestDataPath_globOnly) { - IntentFilter filter = IntentFilterBuilder() - .authority("host.com") - .path("/.*", mojom::PatternType::PATTERN_SIMPLE_GLOB); + IntentFilter filter = + IntentFilterBuilder() + .authority("host.com") + .path("/.*", mojom::PatternType::PATTERN_SIMPLE_GLOB); // Empty URLs should fail. EXPECT_FALSE(filter.Match(GURL())); @@ -311,9 +310,10 @@ // Glob tests based loosely on android's CTS IntentFilterTest#testPaths. TEST(IntentFilterTest, TestDataPath_globSingleChar) { - IntentFilter filter = IntentFilterBuilder() - .authority("host.com") - .path("/a1*b", mojom::PatternType::PATTERN_SIMPLE_GLOB); + IntentFilter filter = + IntentFilterBuilder() + .authority("host.com") + .path("/a1*b", mojom::PatternType::PATTERN_SIMPLE_GLOB); EXPECT_FALSE(filter.Match(GURL())); EXPECT_FALSE(filter.Match(GURL("http://host.com"))); @@ -329,9 +329,10 @@ // Glob tests based loosely on android's CTS IntentFilterTest#testPaths. TEST(IntentFilterTest, TestDataPath_globEscapedChar) { - IntentFilter filter = IntentFilterBuilder() - .authority("host.com") - .path("/a\\.*b", mojom::PatternType::PATTERN_SIMPLE_GLOB); + IntentFilter filter = + IntentFilterBuilder() + .authority("host.com") + .path("/a\\.*b", mojom::PatternType::PATTERN_SIMPLE_GLOB); EXPECT_FALSE(filter.Match(GURL())); EXPECT_FALSE(filter.Match(GURL("http://host.com"))); @@ -350,9 +351,10 @@ // Glob tests based loosely on android's CTS IntentFilterTest#testPaths. TEST(IntentFilterTest, TestDataPath_globEscapedStar) { - IntentFilter filter = IntentFilterBuilder() - .authority("host.com") - .path("/a.\\*b", mojom::PatternType::PATTERN_SIMPLE_GLOB); + IntentFilter filter = + IntentFilterBuilder() + .authority("host.com") + .path("/a.\\*b", mojom::PatternType::PATTERN_SIMPLE_GLOB); EXPECT_FALSE(filter.Match(GURL())); EXPECT_FALSE(filter.Match(GURL("http://host.com")));
diff --git a/components/arc/intent_helper/link_handler_model_unittest.cc b/ash/components/arc/intent_helper/link_handler_model_unittest.cc similarity index 100% rename from components/arc/intent_helper/link_handler_model_unittest.cc rename to ash/components/arc/intent_helper/link_handler_model_unittest.cc
diff --git a/components/arc/lock_screen/arc_lock_screen_bridge_unittest.cc b/ash/components/arc/lock_screen/arc_lock_screen_bridge_unittest.cc similarity index 100% rename from components/arc/lock_screen/arc_lock_screen_bridge_unittest.cc rename to ash/components/arc/lock_screen/arc_lock_screen_bridge_unittest.cc
diff --git a/components/arc/media_session/arc_media_session_bridge_unittest.cc b/ash/components/arc/media_session/arc_media_session_bridge_unittest.cc similarity index 100% rename from components/arc/media_session/arc_media_session_bridge_unittest.cc rename to ash/components/arc/media_session/arc_media_session_bridge_unittest.cc
diff --git a/components/arc/memory/arc_memory_bridge_unittest.cc b/ash/components/arc/memory/arc_memory_bridge_unittest.cc similarity index 100% rename from components/arc/memory/arc_memory_bridge_unittest.cc rename to ash/components/arc/memory/arc_memory_bridge_unittest.cc
diff --git a/components/arc/memory_pressure/arc_memory_pressure_bridge_unittest.cc b/ash/components/arc/memory_pressure/arc_memory_pressure_bridge_unittest.cc similarity index 100% rename from components/arc/memory_pressure/arc_memory_pressure_bridge_unittest.cc rename to ash/components/arc/memory_pressure/arc_memory_pressure_bridge_unittest.cc
diff --git a/components/arc/metrics/arc_metrics_service_unittest.cc b/ash/components/arc/metrics/arc_metrics_service_unittest.cc similarity index 100% rename from components/arc/metrics/arc_metrics_service_unittest.cc rename to ash/components/arc/metrics/arc_metrics_service_unittest.cc
diff --git a/components/arc/metrics/stability_metrics_manager_unittest.cc b/ash/components/arc/metrics/stability_metrics_manager_unittest.cc similarity index 100% rename from components/arc/metrics/stability_metrics_manager_unittest.cc rename to ash/components/arc/metrics/stability_metrics_manager_unittest.cc
diff --git a/components/arc/midis/arc_midis_bridge_unittest.cc b/ash/components/arc/midis/arc_midis_bridge_unittest.cc similarity index 100% rename from components/arc/midis/arc_midis_bridge_unittest.cc rename to ash/components/arc/midis/arc_midis_bridge_unittest.cc
diff --git a/components/arc/net/always_on_vpn_manager_unittest.cc b/ash/components/arc/net/always_on_vpn_manager_unittest.cc similarity index 100% rename from components/arc/net/always_on_vpn_manager_unittest.cc rename to ash/components/arc/net/always_on_vpn_manager_unittest.cc
diff --git a/components/arc/net/arc_net_host_impl_unittest.cc b/ash/components/arc/net/arc_net_host_impl_unittest.cc similarity index 100% rename from components/arc/net/arc_net_host_impl_unittest.cc rename to ash/components/arc/net/arc_net_host_impl_unittest.cc
diff --git a/components/arc/pay/arc_payment_app_bridge_unittest.cc b/ash/components/arc/pay/arc_payment_app_bridge_unittest.cc similarity index 100% rename from components/arc/pay/arc_payment_app_bridge_unittest.cc rename to ash/components/arc/pay/arc_payment_app_bridge_unittest.cc
diff --git a/components/arc/power/arc_power_bridge_unittest.cc b/ash/components/arc/power/arc_power_bridge_unittest.cc similarity index 100% rename from components/arc/power/arc_power_bridge_unittest.cc rename to ash/components/arc/power/arc_power_bridge_unittest.cc
diff --git a/components/arc/property/arc_property_bridge_unittest.cc b/ash/components/arc/property/arc_property_bridge_unittest.cc similarity index 100% rename from components/arc/property/arc_property_bridge_unittest.cc rename to ash/components/arc/property/arc_property_bridge_unittest.cc
diff --git a/components/arc/rotation_lock/arc_rotation_lock_bridge_unittest.cc b/ash/components/arc/rotation_lock/arc_rotation_lock_bridge_unittest.cc similarity index 100% rename from components/arc/rotation_lock/arc_rotation_lock_bridge_unittest.cc rename to ash/components/arc/rotation_lock/arc_rotation_lock_bridge_unittest.cc
diff --git a/components/arc/sensor/arc_iio_sensor_bridge_unittest.cc b/ash/components/arc/sensor/arc_iio_sensor_bridge_unittest.cc similarity index 100% rename from components/arc/sensor/arc_iio_sensor_bridge_unittest.cc rename to ash/components/arc/sensor/arc_iio_sensor_bridge_unittest.cc
diff --git a/components/arc/storage_manager/arc_storage_manager_unittest.cc b/ash/components/arc/storage_manager/arc_storage_manager_unittest.cc similarity index 100% rename from components/arc/storage_manager/arc_storage_manager_unittest.cc rename to ash/components/arc/storage_manager/arc_storage_manager_unittest.cc
diff --git a/components/arc/timer/arc_timer_bridge_unittest.cc b/ash/components/arc/timer/arc_timer_bridge_unittest.cc similarity index 100% rename from components/arc/timer/arc_timer_bridge_unittest.cc rename to ash/components/arc/timer/arc_timer_bridge_unittest.cc
diff --git a/components/arc/usb/usb_host_bridge_unittest.cc b/ash/components/arc/usb/usb_host_bridge_unittest.cc similarity index 100% rename from components/arc/usb/usb_host_bridge_unittest.cc rename to ash/components/arc/usb/usb_host_bridge_unittest.cc
diff --git a/components/arc/video_accelerator/arc_video_accelerator_util_unittest.cc b/ash/components/arc/video_accelerator/arc_video_accelerator_util_unittest.cc similarity index 100% rename from components/arc/video_accelerator/arc_video_accelerator_util_unittest.cc rename to ash/components/arc/video_accelerator/arc_video_accelerator_util_unittest.cc
diff --git a/components/arc/volume_mounter/arc_volume_mounter_bridge_unittest.cc b/ash/components/arc/volume_mounter/arc_volume_mounter_bridge_unittest.cc similarity index 100% rename from components/arc/volume_mounter/arc_volume_mounter_bridge_unittest.cc rename to ash/components/arc/volume_mounter/arc_volume_mounter_bridge_unittest.cc
diff --git a/components/arc/wake_lock/arc_wake_lock_bridge_unittest.cc b/ash/components/arc/wake_lock/arc_wake_lock_bridge_unittest.cc similarity index 100% rename from components/arc/wake_lock/arc_wake_lock_bridge_unittest.cc rename to ash/components/arc/wake_lock/arc_wake_lock_bridge_unittest.cc
diff --git a/ash/components/fwupd/firmware_update_manager.cc b/ash/components/fwupd/firmware_update_manager.cc index bdf60e0..6d18b3e 100644 --- a/ash/components/fwupd/firmware_update_manager.cc +++ b/ash/components/fwupd/firmware_update_manager.cc
@@ -22,7 +22,6 @@ DCHECK_EQ(nullptr, g_instance); g_instance = this; - g_instance->RequestDevices(); } FirmwareUpdateManager::~FirmwareUpdateManager() {
diff --git a/ash/components/fwupd/firmware_update_manager.h b/ash/components/fwupd/firmware_update_manager.h index 622e08f..78d2a84b 100644 --- a/ash/components/fwupd/firmware_update_manager.h +++ b/ash/components/fwupd/firmware_update_manager.h
@@ -9,7 +9,6 @@ #include "chromeos/dbus/fwupd/fwupd_client.h" #include "chromeos/dbus/fwupd/fwupd_device.h" #include "chromeos/dbus/fwupd/fwupd_update.h" -#include "dbus/message.h" namespace ash { // FirmwareUpdateManager contains all logic that runs the firmware update SWA. @@ -18,6 +17,7 @@ public: // Query the fwupd DBus client for currently connected devices. void RequestDevices(); + // Query the fwupd DBus client for updates for a certain device. void RequestUpdates(const std::string& device_id);
diff --git a/ash/components/fwupd/firmware_update_manager_unittest.cc b/ash/components/fwupd/firmware_update_manager_unittest.cc index 12bae41b..284c3c18 100644 --- a/ash/components/fwupd/firmware_update_manager_unittest.cc +++ b/ash/components/fwupd/firmware_update_manager_unittest.cc
@@ -40,9 +40,9 @@ // TODO(swifton): Rewrite this test with an observer. TEST_F(FirmwareUpdateManagerTest, RequestDeviceList) { // FirmwareUpdateManager requests devices when it is created. - EXPECT_EQ(1, GetOnDevicesResponseCallbackCallCountForTesting()); + EXPECT_EQ(0, GetOnDevicesResponseCallbackCallCountForTesting()); firmware_update_manager_.RequestDevices(); - EXPECT_EQ(2, GetOnDevicesResponseCallbackCallCountForTesting()); + EXPECT_EQ(1, GetOnDevicesResponseCallbackCallCountForTesting()); } // TODO(swifton): Rewrite this test with an observer.
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 463a998d..7b2e5528 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -769,7 +769,7 @@ // Enables or disables the second language settings update. const base::Feature kLanguageSettingsUpdate2{"LanguageSettingsUpdate2", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; // Enables or disables sorting app icons shown on the launcher. const base::Feature kLauncherAppSort{"LauncherAppSort", @@ -961,7 +961,7 @@ // Enables animation in the productivity launcher. const base::Feature kProductivityLauncherAnimation{ - "ProductivityLauncherAnimation", base::FEATURE_DISABLED_BY_DEFAULT}; + "ProductivityLauncherAnimation", base::FEATURE_ENABLED_BY_DEFAULT}; // Controls whether to enable Projector. const base::Feature kProjector{"Projector", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ash/constants/ash_pref_names.cc b/ash/constants/ash_pref_names.cc index 88b4557..fe50efca 100644 --- a/ash/constants/ash_pref_names.cc +++ b/ash/constants/ash_pref_names.cc
@@ -879,8 +879,13 @@ const char kChromadToCloudMigrationEnabled[] = "ash.chromad_to_cloud_migration_enabled"; -// NOTE: New prefs should start with the "ash." prefix. Existing prefs moved -// into this file should not be renamed, since they may be synced. +// A string pref that tracks the language installed for the Projector creation +// flow. +const char kProjectorCreationFlowLanguage[] = + "ash.projector.projectorCreationFlowLanguage"; + +// NOTE: New prefs should start with the "ash." prefix. Existing prefs +// moved into this file should not be renamed, since they may be synced. } // namespace prefs } // namespace ash
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h index d68cd7c..8273144 100644 --- a/ash/constants/ash_pref_names.h +++ b/ash/constants/ash_pref_names.h
@@ -400,6 +400,10 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kChromadToCloudMigrationEnabled[]; + +COMPONENT_EXPORT(ASH_CONSTANTS) +extern const char kProjectorCreationFlowLanguage[]; + } // namespace prefs } // namespace ash
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn index 0d7994e..18a701f 100644 --- a/ash/public/cpp/BUILD.gn +++ b/ash/public/cpp/BUILD.gn
@@ -226,6 +226,7 @@ "privacy_screen_dlp_helper.h", "projector/projector_annotator_controller.cc", "projector/projector_annotator_controller.h", + "projector/projector_client.cc", "projector/projector_client.h", "projector/projector_controller.cc", "projector/projector_controller.h",
diff --git a/ash/public/cpp/app_list/app_list_client.h b/ash/public/cpp/app_list/app_list_client.h index e70ff5e..6c25c69 100644 --- a/ash/public/cpp/app_list/app_list_client.h +++ b/ash/public/cpp/app_list/app_list_client.h
@@ -93,11 +93,16 @@ const std::string& id, int event_flags) = 0; // Returns the context menu model for the item with |id|, or an empty array if - // there is currently no menu for the item (e.g. during install). + // there is currently no menu for the item (e.g. during install). Requests + // adding sort options that can sort the app list in the menu model if + // `add_sort_options` is true, where the value of `add_sort_options` is + // determined by the context of the AppListItemView and if the app list sort + // feature is enabled. using GetContextMenuModelCallback = base::OnceCallback<void(std::unique_ptr<ui::SimpleMenuModel>)>; virtual void GetContextMenuModel(int profile_id, const std::string& id, + bool add_sort_options, GetContextMenuModelCallback callback) = 0; // Invoked when a "quick setting" is changed. virtual void OnQuickSettingsChanged(
diff --git a/ash/public/cpp/app_list/app_list_features.cc b/ash/public/cpp/app_list/app_list_features.cc index ea587e0a..cbdae59 100644 --- a/ash/public/cpp/app_list/app_list_features.cc +++ b/ash/public/cpp/app_list/app_list_features.cc
@@ -42,8 +42,6 @@ "EnableExactMatchForNonLatinLocale", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kEnableAggregatedMlSearchRanking{ "EnableAggregatedMlSearchRanking", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kNewDragSpecInLauncher{"NewDragSpecInLauncher", - base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kEnableLauncherSearchNormalization{ "EnableLauncherSearchNormalization", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kCategoricalSearch{"CategoricalSearch", @@ -99,10 +97,6 @@ return base::FeatureList::IsEnabled(kEnableAggregatedMlSearchRanking); } -bool IsNewDragSpecInLauncherEnabled() { - return base::FeatureList::IsEnabled(kNewDragSpecInLauncher); -} - bool IsLauncherSearchNormalizationEnabled() { return base::FeatureList::IsEnabled(kEnableLauncherSearchNormalization); }
diff --git a/ash/public/cpp/app_list/app_list_metrics.cc b/ash/public/cpp/app_list/app_list_metrics.cc index a91e4ad8..1e8e306 100644 --- a/ash/public/cpp/app_list/app_list_metrics.cc +++ b/ash/public/cpp/app_list/app_list_metrics.cc
@@ -82,7 +82,8 @@ break; case AppListLaunchedFrom::kLaunchedFromShelf: case AppListLaunchedFrom::kLaunchedFromGrid: - // Search results don't live in the shelf or the app grid. + case AppListLaunchedFrom::kLaunchedFromRecentApps: + // Search results don't live in the shelf, the app grid or recent apps. NOTREACHED(); break; }
diff --git a/ash/public/cpp/app_list/app_list_types.h b/ash/public/cpp/app_list/app_list_types.h index 9f469ed..9962986 100644 --- a/ash/public/cpp/app_list/app_list_types.h +++ b/ash/public/cpp/app_list/app_list_types.h
@@ -163,7 +163,8 @@ kLaunchedFromSuggestionChip = 2, kLaunchedFromShelf = 3, kLaunchedFromSearchBox = 4, - kMaxValue = kLaunchedFromSearchBox, + kLaunchedFromRecentApps = 5, + kMaxValue = kLaunchedFromRecentApps, }; // The UI representation of the search result. Currently all search results
diff --git a/ash/public/cpp/app_menu_constants.h b/ash/public/cpp/app_menu_constants.h index c760d98..17909ebc 100644 --- a/ash/public/cpp/app_menu_constants.h +++ b/ash/public/cpp/app_menu_constants.h
@@ -59,6 +59,10 @@ USE_LAUNCH_TYPE_WINDOW = 203, USE_LAUNCH_TYPE_TABBED_WINDOW = 204, USE_LAUNCH_TYPE_COMMAND_END, + // The reorder submenu options used by AppServiceContextMenu. + REORDER_SUBMENU = 300, + REORDER_BY_NAME_ALPHABETICAL = 301, + REORDER_BY_NAME_REVERSE_ALPHABETICAL = 302, // Range of command ids reserved for launching app shortcuts from context // menu for Android app. Used by AppContextMenu and ShelfContextMenu.
diff --git a/ash/public/cpp/desks_templates_delegate.h b/ash/public/cpp/desks_templates_delegate.h index 9be3131..3b315f60 100644 --- a/ash/public/cpp/desks_templates_delegate.h +++ b/ash/public/cpp/desks_templates_delegate.h
@@ -7,7 +7,7 @@ #include "ash/public/cpp/ash_public_export.h" #include "components/favicon_base/favicon_callback.h" -#include "components/services/app_service/public/mojom/app_service.mojom.h" +#include "components/services/app_service/public/cpp/icon_types.h" namespace app_restore { struct AppLaunchInfo; @@ -59,7 +59,7 @@ virtual void GetIconForAppId( const std::string& app_id, int desired_icon_size, - base::OnceCallback<void(apps::mojom::IconValuePtr icon_value)> callback) + base::OnceCallback<void(apps::IconValuePtr icon_value)> callback) const = 0; // Launches apps into the active desk. Ran immediately after a desk is created
diff --git a/ash/public/cpp/projector/projector_client.cc b/ash/public/cpp/projector/projector_client.cc new file mode 100644 index 0000000..899eee9 --- /dev/null +++ b/ash/public/cpp/projector/projector_client.cc
@@ -0,0 +1,30 @@ +// 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/public/cpp/projector/projector_client.h" + +#include "base/check_op.h" + +namespace ash { + +namespace { +ProjectorClient* g_instance_ = nullptr; +} + +// static +ProjectorClient* ProjectorClient::Get() { + return g_instance_; +} + +ProjectorClient::ProjectorClient() { + DCHECK_EQ(g_instance_, nullptr); + g_instance_ = this; +} + +ProjectorClient::~ProjectorClient() { + DCHECK_EQ(g_instance_, this); + g_instance_ = nullptr; +} + +} // namespace ash
diff --git a/ash/public/cpp/projector/projector_client.h b/ash/public/cpp/projector/projector_client.h index c776c66..40155d5 100644 --- a/ash/public/cpp/projector/projector_client.h +++ b/ash/public/cpp/projector/projector_client.h
@@ -17,10 +17,12 @@ // ProjectorControllerImpl. class ASH_PUBLIC_EXPORT ProjectorClient { public: - ProjectorClient() = default; + static ProjectorClient* Get(); + + ProjectorClient(); ProjectorClient(const ProjectorClient&) = delete; ProjectorClient& operator=(const ProjectorClient&) = delete; - virtual ~ProjectorClient() = default; + virtual ~ProjectorClient(); virtual void StartSpeechRecognition() = 0; virtual void StopSpeechRecognition() = 0;
diff --git a/ash/public/cpp/projector/projector_controller.cc b/ash/public/cpp/projector/projector_controller.cc index f1fcabf05..1b9ab26 100644 --- a/ash/public/cpp/projector/projector_controller.cc +++ b/ash/public/cpp/projector/projector_controller.cc
@@ -40,15 +40,4 @@ return command_line->HasSwitch(kExtendedProjectorFeaturesDisabled); } -ProjectorController::ScopedInstanceResetterForTest:: - ScopedInstanceResetterForTest() - : controller_(g_instance) { - g_instance = nullptr; -} - -ProjectorController::ScopedInstanceResetterForTest:: - ~ScopedInstanceResetterForTest() { - g_instance = controller_; -} - } // namespace ash
diff --git a/ash/public/cpp/projector/projector_controller.h b/ash/public/cpp/projector/projector_controller.h index 05099e31..d7ca767 100644 --- a/ash/public/cpp/projector/projector_controller.h +++ b/ash/public/cpp/projector/projector_controller.h
@@ -22,19 +22,6 @@ // Interface to control projector in ash. class ASH_PUBLIC_EXPORT ProjectorController { public: - class ScopedInstanceResetterForTest { - public: - ScopedInstanceResetterForTest(); - ScopedInstanceResetterForTest(const ScopedInstanceResetterForTest&) = - delete; - ScopedInstanceResetterForTest& operator=( - const ScopedInstanceResetterForTest&) = delete; - ~ScopedInstanceResetterForTest(); - - private: - ProjectorController* const controller_; - }; - ProjectorController(); ProjectorController(const ProjectorController&) = delete; ProjectorController& operator=(const ProjectorController&) = delete;
diff --git a/ash/public/cpp/resources/ash_public_unscaled_resources.grd b/ash/public/cpp/resources/ash_public_unscaled_resources.grd index 83f60c5c..7e18e26 100644 --- a/ash/public/cpp/resources/ash_public_unscaled_resources.grd +++ b/ash/public/cpp/resources/ash_public_unscaled_resources.grd
@@ -17,9 +17,6 @@ <!-- CrOS internal apps images --> <include name="IDR_SHORTCUT_VIEWER_LOGO_192" file="unscaled_resources/shortcut_viewer_logo_192.png" type="BINDATA" /> <include name="IDR_SETTINGS_LOGO_192" file="unscaled_resources/settings_logo_192.png" type="BINDATA" /> - <include name="IDR_PHONE_HUB_ONBOARDING_IMAGE" file="unscaled_resources/phone_hub_onboarding_image.png" type="BINDATA" /> - <include name="IDR_PHONE_HUB_CONNECTING_IMAGE" file="unscaled_resources/phone_hub_connecting_image.png" type="BINDATA" /> - <include name="IDR_PHONE_HUB_ERROR_STATE_IMAGE" file="unscaled_resources/phone_hub_error_state_image.png" type="BINDATA" /> <include name="IDR_OS_FLAGS_APP_ICONS_48_PNG" file="unscaled_resources/os_flags_app_icon_48.png" type="BINDATA" /> <include name="IDR_OS_FLAGS_APP_ICONS_128_PNG" file="unscaled_resources/os_flags_app_icon_128.png" type="BINDATA" /> <include name="IDR_OS_FLAGS_APP_ICONS_192_PNG" file="unscaled_resources/os_flags_app_icon_192.png" type="BINDATA" /> @@ -27,5 +24,10 @@ <include name="IDR_OS_URL_HANDLER_APP_ICONS_128_PNG" file="unscaled_resources/os_url_handler_app_icon_128.png" type="BINDATA" /> <include name="IDR_OS_URL_HANDLER_APP_ICONS_192_PNG" file="unscaled_resources/os_url_handler_app_icon_192.png" type="BINDATA" /> </includes> + <structures> + <structure type="lottie" name="IDR_PHONE_HUB_ONBOARDING_IMAGE" file="unscaled_resources/phone_hub_onboarding_image.json" compress="gzip" /> + <structure type="lottie" name="IDR_PHONE_HUB_CONNECTING_IMAGE" file="unscaled_resources/phone_hub_connecting_image.json" compress="gzip" /> + <structure type="lottie" name="IDR_PHONE_HUB_ERROR_STATE_IMAGE" file="unscaled_resources/phone_hub_error_state_image.json" compress="gzip" /> + </structures> </release> </grit>
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.json b/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.json new file mode 100644 index 0000000..d43b92a --- /dev/null +++ b/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.json
@@ -0,0 +1 @@ +{"v":"5.6.6","ip":0,"op":1,"fr":60,"w":256,"h":256,"layers":[{"ind":252,"nm":"surface1514","ao":0,"ip":0,"op":60,"st":0,"ty":4,"ks":{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[133.33,133.33]},"sk":{"k":0},"sa":{"k":0}},"shapes":[{"ty":"gr","hd":false,"nm":"surface1514","it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.18,0.48],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[-0.52,0.01],[0,0],[0,0],[0,0]],"v":[[21.26,74.22],[33.82,117.03],[77.22,116.51],[77.25,118.96],[32.92,119.49],[32.92,119.49],[31.76,118.69],[31.73,118.61],[18.91,74.91]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-2.43,-4.46],[5.09,-2.76],[0.71,-0.22]],"o":[[4.69,-1.47],[2.76,5.09],[-0.65,0.36],[0,0]],"v":[[26.14,92.29],[38.48,97.28],[34.28,111.5],[32.22,112.36]],"c":false}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.97,0.51,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-3.21,-0.34],[0,0],[0.51,2.6]],"o":[[0,0],[0.7,3.25],[0,0],[-2.57,-0.13],[0,0]],"v":[[59.57,79.42],[57.72,79.92],[64.36,85.9],[64.86,84.02],[59.57,79.42]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.82,0.89,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,-1.02],[4.13,-0.57],[-0.06,-0.07],[0,0],[0,0],[-0.14,-0.12],[0,0],[-0.05,-0.05],[-0.02,-0.02],[-0.33,-0.19],[0,4.69],[0.14,0.68],[0,0],[0,0],[0.25,0.11],[0.33,0.09],[0,0],[0,0],[0,0],[0.13,0.03],[0.02,0]],"o":[[0,0],[0.33,0.91],[0,4.29],[0.06,0.07],[0,0],[0,0],[0.12,0.14],[0,0],[0.05,0.05],[0.02,0.02],[0.3,0.25],[4.27,-1.29],[0,-0.72],[0,0],[0,0],[-0.22,-0.14],[-0.31,-0.14],[0,0],[0,0],[0,0],[-0.12,-0.04],[-0.02,0],[0,0]],"v":[[131.05,80.09],[131.08,80.17],[131.59,83.08],[124.28,91.48],[124.46,91.69],[124.48,91.7],[124.48,91.71],[124.88,92.11],[124.94,92.17],[125.1,92.31],[125.17,92.37],[126.11,93.03],[133.5,83.08],[133.29,80.97],[133.2,80.92],[133.2,80.92],[132.5,80.55],[131.54,80.21],[131.5,80.2],[131.49,80.2],[131.49,80.19],[131.11,80.1],[131.05,80.09]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.68,0.8,0.98,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.25,-0.1],[-2.46,4.23],[5.14,2.59],[0,0],[1.36,0.08],[0.76,-0.12],[0,0],[0,0]],"o":[[0.23,0.12],[4.56,1.77],[2.94,-5.04],[0,0],[-1.21,-0.61],[-0.79,-0.05],[0,0],[0,0],[0,0]],"v":[[142.54,104.7],[143.27,105.03],[155.56,100.75],[151.41,86.7],[151.41,86.71],[147.5,85.67],[145.17,85.79],[142.69,85.95],[142.54,85.95]],"c":false}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-5.73],[-5.73,0],[0,5.73],[5.73,0]],"o":[[-5.73,0],[0,5.73],[5.73,0],[0,-5.73],[0,0]],"v":[[123.12,72.7],[112.73,83.08],[123.12,93.46],[133.5,83.08],[123.12,72.7]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-4.68],[4.68,0],[0,4.68],[-4.68,0]],"o":[[4.68,0],[0,4.68],[-4.68,0],[0,-4.68],[0,0]],"v":[[123.12,74.61],[131.59,83.08],[123.12,91.55],[114.64,83.08],[123.12,74.61]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.02,-0.27],[0.27,-0.04],[0,0],[0,0],[0.02,0.27],[-0.27,0.04],[0,0]],"o":[[0.27,0],[0.02,0.27],[0,0],[0,0],[-0.27,0],[-0.02,-0.27],[0,0],[0,0]],"v":[[158.7,68.54],[159.21,69.03],[158.77,69.59],[158.7,69.59],[153.78,69.59],[153.26,69.1],[153.71,68.55],[153.78,68.54]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0.35],[0.35,0],[0,-0.35],[-0.35,0]],"o":[[0.35,0],[0,-0.35],[-0.35,0],[0,0.35],[0,0]],"v":[[151.06,69.7],[151.7,69.07],[151.06,68.43],[150.43,69.07],[151.06,69.7]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[1.62,1.45],[0,0],[0,0],[0.32,0.26],[0.25,0.13],[1.72,-3.45],[-3.45,-1.72],[-0.28,-0.1],[0,0],[-0.05,0],[0,0],[-1.22,-1.83],[0,0],[0,0],[-0.48,-0.61],[-1.28,-0.61]],"o":[[-2.16,0.08],[0,0],[0,0],[-0.32,-0.27],[-0.25,-0.15],[-3.47,-1.75],[-1.75,3.47],[0.28,0.12],[0,0],[0,0],[0,0],[2.16,0.46],[0,0],[0,0],[0.36,0.69],[0.91,1.09],[0,0]],"v":[[142.53,85.92],[136.65,83.82],[134.55,81.94],[134.55,81.95],[133.59,81.16],[132.82,80.7],[123.39,83.82],[126.51,93.25],[127.32,93.6],[127.35,93.6],[128.54,93.91],[131.3,94.49],[136.57,98.06],[137.94,100.14],[137.95,100.14],[139.21,102.09],[142.53,104.68]],"c":false}}},{"ty":"fl","o":{"k":60},"c":{"k":[0.13,0.44,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.05,-0.18],[-0.14,-0.13],[0,0],[-0.1,0.41],[0,0],[0,0],[0.13,0.13],[0.18,-0.05]],"o":[[0,0],[-0.19,0.05],[-0.05,0.19],[0,0],[0.3,0.28],[0,0],[0,0],[0.05,-0.19],[-0.14,-0.14],[0,0]],"v":[[65.68,77.76],[44.21,83.59],[43.83,83.96],[43.98,84.48],[59.78,100.14],[60.66,99.89],[66.34,78.42],[66.34,78.42],[66.2,77.9],[65.68,77.76]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.99,0.79,0.2,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.54,0.53],[0,0.75],[0.54,0.53],[0.76,-0.01],[0,-1.54],[-1.54,-0.03]],"o":[[0.76,0.01],[0.54,-0.53],[0,-0.76],[-0.54,-0.53],[-1.54,0.03],[0,1.54],[0,0]],"v":[[102.69,73.05],[104.71,72.24],[105.55,70.23],[104.71,68.23],[102.69,67.42],[99.92,70.23],[102.69,73.05]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.36,0.73,0.45,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.64,-4.15],[-4.14,0.64],[0,0],[0.64,4.15],[4.15,-0.64]],"o":[[0,0],[-4.16,0.64],[0.64,4.15],[0,0],[4.16,-0.64],[-0.64,-4.16],[0,0]],"v":[[79.4,68.43],[64.02,70.81],[57.64,79.48],[66.31,85.85],[81.7,83.47],[88.07,74.8],[79.4,68.43]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[3.12,-0.48],[0,0],[0.48,3.11],[-3.12,0.48],[0,0],[-0.48,-3.12]],"o":[[0.48,3.11],[0,0],[-3.1,0.48],[-0.48,-3.11],[0,0],[3.11,-0.48],[0,0]],"v":[[86.18,75.09],[81.41,81.58],[66.02,83.96],[59.53,79.19],[64.31,72.7],[79.7,70.32],[86.18,75.09]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.93,0.4,0.36,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0.95],[0,0],[-0.95,0],[0,0],[0,-0.95],[0,0],[0.94,0]],"o":[[0,0],[-0.95,0],[0,0],[0,-0.95],[0,0],[0.95,0],[0,0],[0,0.96],[0,0]],"v":[[166.79,118.11],[144.28,118.11],[142.56,116.39],[142.56,67.72],[144.28,66],[166.79,66],[168.52,67.72],[168.52,116.36],[166.79,118.11]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.82,0.89,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]}]}],"meta":{"g":"LF SVG to Lottie"}} \ No newline at end of file
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.png b/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.png deleted file mode 100644 index de1f0f73..0000000 --- a/ash/public/cpp/resources/unscaled_resources/phone_hub_connecting_image.png +++ /dev/null Binary files differ
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.json b/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.json new file mode 100644 index 0000000..0f248df --- /dev/null +++ b/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.json
@@ -0,0 +1 @@ +{"v":"5.6.6","ip":0,"op":1,"fr":60,"w":256,"h":256,"layers":[{"ind":326,"nm":"surface1408","ao":0,"ip":0,"op":60,"st":0,"ty":4,"ks":{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[133.33,133.33]},"sk":{"k":0},"sa":{"k":0}},"shapes":[{"ty":"gr","hd":false,"nm":"surface1408","it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.16,-0.35],[0.35,-0.16],[0.48,-0.36],[0,0],[0.14,0.02],[0.08,0.11],[-0.02,0.14],[-0.11,0.08],[-0.59,0.34]],"o":[[0.29,-0.12],[0.12,0.29],[-0.53,0.29],[0,0],[-0.11,0.08],[-0.14,-0.02],[-0.09,-0.11],[0.02,-0.14],[0.5,-0.46],[0,0]],"v":[[139.86,31.05],[140.62,31.34],[140.34,32.1],[138.8,33.04],[138.8,33.04],[138.41,33.13],[138.07,32.92],[137.96,32.53],[138.18,32.18],[139.86,31.05]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.05,-0.31],[0.32,0.05],[0.55,-0.12],[0.05,0.33],[-0.33,0.05],[-0.64,0.01]],"o":[[0.27,-0.01],[0.01,0.27],[-0.6,0.07],[-0.33,0.05],[-0.05,-0.33],[0.66,-0.11],[0,0]],"v":[[144.75,29.73],[145.31,30.25],[144.79,30.81],[143.03,31.07],[142.35,30.64],[142.78,29.96],[144.75,29.73]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.09,-0.25],[0.25,0.09],[0.63,0.1],[0,0],[-0.05,0.32],[-0.32,-0.05],[-0.61,-0.2]],"o":[[0.25,0.09],[-0.09,0.25],[-0.55,-0.25],[0,0],[-0.32,-0.05],[0.05,-0.32],[0.66,0.27],[0,0]],"v":[[149.79,30.43],[150.11,31.12],[149.42,31.44],[147.67,30.95],[147.67,30.95],[147.18,30.28],[147.85,29.8],[149.79,30.43]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.2,-0.23],[0.24,0.2],[0.48,0.4],[-0.09,0.25],[-0.25,-0.09],[-0.41,-0.44]],"o":[[0.24,0.2],[-0.2,0.24],[-0.41,-0.44],[-0.24,-0.2],[0.09,-0.25],[0.58,0.41],[0,0]],"v":[[154.04,33.09],[154.07,33.89],[153.26,33.93],[151.88,32.79],[151.68,32.01],[152.46,31.81],[154.04,33.08]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.29,-0.12],[0.12,0.29],[0,0],[0.34,0.47],[-0.24,0.18],[-0.18,-0.24],[-0.23,-0.57]],"o":[[0.12,0.29],[-0.29,0.12],[0,0],[-0.21,-0.54],[-0.18,-0.24],[0.24,-0.18],[0.41,0.44],[0,0]],"v":[[156.98,37.26],[156.7,38.02],[155.94,37.74],[155.93,37.73],[155.1,36.21],[155.28,35.43],[156.05,35.61],[156.98,37.25]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.27,-0.01],[0.01,0.27],[0,0],[0.13,0.57],[-0.33,0.05],[-0.05,-0.33],[0,-0.64]],"o":[[0.01,0.27],[-0.27,0.01],[0,0],[0.03,-0.58],[-0.05,-0.33],[0.33,-0.05],[0.12,0.55],[0,0]],"v":[[158.02,42.25],[157.5,42.82],[156.93,42.3],[156.93,42.29],[156.78,40.55],[157.25,39.93],[157.88,40.4],[158.01,42.25]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.3,0.16],[-0.16,0.3],[-0.14,0.57],[-0.31,-0.05],[0.05,-0.31],[0.27,-0.66]],"o":[[-0.16,0.3],[-0.3,-0.16],[0.25,-0.55],[0.05,-0.31],[0.31,0.05],[-0.2,0.61],[0,0]],"v":[[157.01,47.25],[156.27,47.51],[156.01,46.77],[156.55,45.08],[157.26,44.66],[157.68,45.37],[157.01,47.25]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.18,0.24],[-0.24,0.18],[-0.34,0.43],[-0.23,-0.2],[0.2,-0.23],[0.44,-0.41]],"o":[[-0.2,0.24],[-0.24,-0.2],[0.44,-0.41],[0.2,-0.24],[0.24,0.2],[-0.4,0.47],[0,0]],"v":[[154.11,51.3],[153.36,51.29],[153.37,50.54],[154.55,49.22],[155.31,49.13],[155.41,49.89],[154.11,51.3]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.11,0.29],[-0.29,0.11],[-0.53,0.29],[-0.12,-0.29],[0.29,-0.12],[0.57,-0.23]],"o":[[-0.29,0.12],[-0.12,-0.29],[0.57,-0.23],[0.29,-0.12],[0.12,0.29],[-0.53,0.29],[0,0]],"v":[[149.76,54],[149.06,53.67],[149.39,52.97],[151,52.26],[151.72,52.48],[151.5,53.2],[149.76,54]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0.38],[-0.38,0],[-0.54,0.02],[-0.01,-0.27],[0.27,-0.01],[0.69,0.06]],"o":[[-0.31,-0.05],[0.05,-0.32],[0.59,0.04],[0.33,-0.05],[0.05,0.33],[-0.66,0.11],[0,0]],"v":[[144.71,54.7],[144.16,54.07],[144.79,53.53],[146.56,53.54],[147.18,54.01],[146.71,54.64],[144.71,54.7]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.09,0.25],[-0.25,-0.09],[-0.51,-0.19],[0.15,-0.3],[0.3,0.15],[0.55,0.25]],"o":[[-0.3,-0.16],[0.16,-0.3],[0.55,0.25],[0.25,0.09],[-0.09,0.25],[-0.57,-0.14],[0,0]],"v":[[139.83,53.34],[139.57,52.6],[140.31,52.34],[141.92,53.02],[142.24,53.72],[141.54,54.04],[139.83,53.34]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.24,0.18],[-0.18,-0.24],[-0.37,-0.38],[0.2,-0.23],[0.24,0.2],[0,0],[0.43,0.46]],"o":[[-0.18,-0.24],[0.24,-0.18],[0.35,0.48],[0.24,0.2],[-0.2,0.24],[0,0],[-0.43,-0.46],[0,0]],"v":[[135.87,50.19],[135.94,49.39],[136.73,49.46],[137.93,50.73],[137.96,51.54],[137.15,51.57],[137.15,51.57],[135.87,50.18]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.33,0.05],[-0.05,-0.33],[-0.29,-0.53],[0.29,-0.12],[0.12,0.29],[0.17,0.62]],"o":[[-0.12,-0.29],[0.33,-0.05],[0.12,0.56],[0.12,0.29],[-0.29,0.12],[-0.32,-0.7],[0,0]],"v":[[133.52,45.68],[133.95,45],[134.64,45.43],[135.29,47.09],[135,47.85],[134.24,47.57],[133.52,45.68]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.32,-0.05],[0.05,-0.32],[0,0],[0.27,-0.01],[0.01,0.27],[-0.06,0.69]],"o":[[0,0],[0.05,-0.32],[0.31,0.05],[0,0],[0.01,0.27],[-0.27,0.01],[-0.11,-0.66],[0,0]],"v":[[133.15,40.57],[133.15,40.57],[133.82,40.08],[134.3,40.75],[134.18,42.5],[133.66,43.07],[133.1,42.55],[133.15,40.57]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.3,-0.15],[0.15,-0.3],[0.25,-0.55],[0.25,0.09],[-0.09,0.25],[-0.36,0.54]],"o":[[0.16,-0.3],[0.3,0.16],[-0.29,0.49],[-0.09,0.25],[-0.25,-0.09],[0.16,-0.67],[0,0]],"v":[[134.81,35.84],[135.59,35.64],[135.79,36.43],[135,38.02],[134.31,38.34],[133.99,37.64],[134.81,35.84]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.14,-0.02],[-0.08,-0.11],[0.02,-0.14],[0.12,-0.08],[0.44,-0.41],[0.23,0.2],[-0.2,0.23],[-0.49,0.35]],"o":[[0,0],[0.11,-0.09],[0.14,0.02],[0.09,0.11],[-0.02,0.14],[-0.48,0.35],[-0.2,0.24],[-0.24,-0.2],[0.61,-0.44],[0,0]],"v":[[138.14,32.13],[138.14,32.12],[138.53,32.02],[138.87,32.24],[138.97,32.63],[138.75,32.97],[137.45,34.11],[136.64,34.14],[136.61,33.33],[138.14,32.12]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.11,0.36],[-0.35,0.54],[-0.19,0.51],[0.14,0.62],[0.52,0.46],[0.67,0.16],[0.78,-0.2],[0.45,-0.79],[0.03,-0.86],[0,0],[-0.23,0.45],[0,0],[-0.5,0.11],[-0.45,-0.23],[-0.14,-0.45],[0,0],[0.11,-0.37],[0.34,-0.43],[0.08,-0.52],[-0.17,-0.62],[0,0],[0,0]],"o":[[0,0],[-0.14,-0.45],[0.11,-0.36],[0.37,-0.64],[0.16,-0.61],[-0.21,-0.68],[-0.52,-0.46],[-0.67,-0.16],[-1.01,0.27],[-0.49,0.73],[0,0],[0.08,-0.52],[0,0],[0.3,-0.42],[0.62,-0.17],[0.45,0.23],[0,0],[0.1,0.37],[-0.11,0.36],[-0.49,0.73],[-0.12,0.46],[0,0],[0,0],[0,0]],"v":[[147.91,44.3],[147.79,43.75],[147.76,42.56],[148.39,41.27],[149.26,39.52],[149.29,37.65],[148.27,35.98],[146.52,35.12],[144.36,35.2],[142.07,36.77],[141.21,39.16],[143.27,39.43],[143.71,38],[143.7,38],[144.96,37.18],[146.5,37.26],[147.36,38.3],[147.36,38.31],[147.34,39.43],[146.66,40.67],[145.78,42.52],[145.85,44.14],[146.05,44.92],[147.92,44.3]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.2,0.33],[0.1,0.39],[0,0],[0.34,0.2],[0.39,-0.1],[0.2,-0.33],[-0.1,-0.39],[-0.34,-0.21],[-0.39,0.1]],"o":[[0.38,-0.09],[0.21,-0.34],[0,0],[-0.09,-0.38],[-0.34,-0.21],[-0.38,0.09],[-0.21,0.34],[0.1,0.39],[0.4,0.17],[0,0]],"v":[[147.98,48.98],[148.89,48.32],[149.01,47.21],[149.01,47.21],[148.35,46.3],[147.24,46.18],[146.33,46.84],[146.21,47.95],[146.87,48.86],[147.98,48.98]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.99,0.79,0.2,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[-0.15,-0.22],[0,0],[0,0],[0,0],[-0.3,-0.07],[0,0],[0,0],[0,0],[-0.23,0.22],[0,0],[0,0],[0,0],[0,0.38],[0,0],[0,0],[0,0],[0.3,0.15],[0,0],[0,0],[0,0],[0.3,-0.08],[0,0],[0,0],[0.07,-0.3],[0,0]],"o":[[0,0],[0,0],[-0.3,-0.07],[0,0],[0,0],[0,0],[-0.23,0.23],[0,0],[0,0],[0,0],[0,0.3],[0,0],[0,0],[0,0],[0.23,0.15],[0,0],[0,0],[0,0],[0.3,-0.07],[0,0],[0,0],[0,0],[0.15,-0.3],[0,0],[0,0],[-0.15,-0.3],[0,0],[0,0]],"v":[[121.23,42.63],[120.11,42.26],[120.04,42.26],[119.66,42.78],[120.26,43.83],[119.29,44.51],[119.14,44.51],[119.36,45.18],[120.56,45.33],[120.49,46.53],[120.49,46.61],[121.09,46.83],[121.99,46.01],[122.89,46.83],[122.89,46.91],[123.49,46.53],[123.41,45.33],[124.61,45.18],[124.69,45.18],[124.76,44.51],[123.79,43.83],[124.39,42.78],[124.39,42.71],[123.94,42.18],[122.81,42.56],[122.36,41.43],[121.69,41.43],[121.24,42.63]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[-0.15,0.08],[0,0],[0,0],[0,0],[-0.15,-0.07],[0,0],[0,0],[0,0],[-0.07,-0.15],[0,0],[0,0],[0,0],[0.15,-0.15],[0,0],[0,0],[0,0],[0.15,0],[0,0],[0,0],[0,0],[0.07,0.15],[0,0],[0,0],[-0.07,0.23],[0,0]],"o":[[0,0],[0,0],[0.07,0.15],[0,0],[0,0],[0,0],[-0.07,0.15],[0,0],[0,0],[0,0],[-0.15,0.07],[0,0],[0,0],[0,0],[-0.15,-0.07],[0,0],[0,0],[0,0],[0,-0.15],[0,0],[0,0],[0,0],[0.15,-0.15],[0,0],[0,0],[0.23,0.07],[0,0],[0,0]],"v":[[121.98,42.63],[122.21,43.23],[122.21,43.31],[122.66,43.46],[123.18,43.23],[122.88,43.75],[122.88,43.83],[123.03,44.28],[123.48,44.58],[122.88,44.65],[122.8,44.65],[122.58,45.03],[122.65,45.63],[122.2,45.25],[122.13,45.18],[121.68,45.25],[121.23,45.63],[121.38,45.03],[121.38,44.95],[121.08,44.65],[120.48,44.58],[120.93,44.28],[121,44.2],[121.07,43.75],[120.77,43.23],[121.3,43.38],[121.75,43.15],[121.97,42.63]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.68,0.8,0.98,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[129.71,80.66],[130.39,77.05],[131.59,80.66],[133.91,78.86],[133.31,81.48],[136.16,82.23],[132.94,82.98],[134.06,86.05],[131.59,83.95],[129.34,86.8],[129.79,83.5],[126.56,83.2],[128.81,81.93],[126.41,78.7],[129.71,80.65]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[52.76,38.88],[53.29,36.18],[54.18,38.88],[55.98,37.46],[55.54,39.48],[57.71,40.08],[55.23,40.68],[56.13,43.08],[54.26,41.43],[52.46,43.61],[52.83,41.06],[50.36,40.83],[52.08,39.86],[50.21,37.38],[52.76,38.88]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.68,0.8,0.98,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[127.98,107.88],[128.66,104.28],[129.79,107.88],[132.18,106.08],[131.51,108.71],[134.36,109.46],[131.21,110.21],[132.34,113.28],[129.86,111.18],[127.54,114.03],[127.98,110.73],[124.76,110.43],[127.01,109.16],[124.61,105.93],[127.98,107.88]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0.83],[0.83,0],[0,-0.83],[-0.83,0]],"o":[[0.83,0],[0,-0.83],[-0.83,0],[0,0.83],[0,0]],"v":[[60.86,60.26],[62.36,58.76],[60.86,57.26],[59.36,58.76],[60.86,60.26]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,1.24],[1.25,0],[0,-1.24],[-1.24,0]],"o":[[1.25,0],[0,-1.24],[-1.24,0],[0,1.24],[0,0]],"v":[[52.61,82.68],[54.86,80.43],[52.61,78.18],[50.36,80.43],[52.61,82.68]],"c":true}}},{"ty":"fl","o":{"k":60},"c":{"k":[0.1,0.45,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,1.1],[1.1,0],[0,-1.1],[-1.1,0]],"o":[[1.1,0],[0,-1.1],[-1.1,0],[0,1.1],[0,0]],"v":[[193.15,84.34],[195.15,82.34],[193.15,80.34],[191.15,82.34],[193.15,84.34]],"c":true}}},{"ty":"st","lc":1,"lj":1,"ml":4,"o":{"k":100},"w":{"k":1},"c":{"k":[0.68,0.8,0.98,1]},"hd":false},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[75,75]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.22],[0.3,0],[0,0],[0,0.22],[-0.3,0]],"o":[[0.3,0],[0,0.23],[0,0],[-0.3,0],[0,-0.23],[0,0]],"v":[[168.49,165.78],[169.01,166.23],[168.56,166.68],[23.74,166.68],[23.21,166.23],[23.66,165.78]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.15,-7.35],[0,0],[0,0],[0,0],[-0.07,-2.55],[0,0],[0.3,0],[0,0.22],[2.1,0.3],[0,0],[0,0],[0,0],[0,0],[6.82,-0.22],[0,0.22],[-0.23,0]],"o":[[7.35,-0.23],[0,0],[0,0],[0,0],[2.55,0.3],[0,0],[0,0.3],[-0.3,0],[0,-2.1],[0,0],[0,0],[0,0],[0,0],[-0.23,-6.75],[-0.3,0],[0,-0.23],[0,0]],"v":[[67.95,127.38],[81.6,140.28],[81.6,140.43],[81.68,158.8],[94.2,160.38],[98.77,165.4],[98.77,165.55],[98.25,166],[97.73,165.55],[94.12,161.35],[93.98,161.35],[80.62,159.7],[80.55,140.57],[80.55,140.27],[67.88,128.35],[67.35,127.9],[67.95,127.38]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.07,-0.15],[0.15,-0.07],[0,0],[0,0],[0.07,0.15],[-0.15,0.07],[0,0]],"o":[[0.23,-0.07],[0.07,0.15],[0,0],[0,0],[-0.23,0.07],[-0.07,-0.15],[0,0],[0,0]],"v":[[94.5,83.05],[94.95,83.28],[94.8,83.73],[94.73,83.73],[86.93,86.21],[86.48,85.98],[86.62,85.53],[86.7,85.53]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.15,-0.15],[0.15,-0.07],[0,0],[0,0],[0.15,0.15],[-0.15,0.07],[0,0]],"o":[[0.15,-0.07],[0.07,0.15],[0,0],[0,0],[-0.15,0.07],[-0.07,-0.15],[0,0],[0,0]],"v":[[95.18,84.55],[95.7,84.63],[95.62,85.08],[95.55,85.15],[89.18,89.28],[88.65,89.2],[88.73,88.75],[88.8,88.68]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.07,-1.05],[0,0],[1.05,0.07],[0,0],[-0.07,1.05],[0,0],[-1.05,-0.08]],"o":[[0,0],[1.05,0.07],[0,0],[-0.07,1.05],[0,0],[-1.05,-0.07],[0,0],[0.07,-0.98],[0,0]],"v":[[76.12,97.68],[96.07,99.41],[97.8,101.43],[97.73,102.11],[95.7,103.83],[75.75,102.03],[74.03,100.01],[74.1,99.33],[76.12,97.68]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[1.35,-0.3],[0.3,-0.15]],"o":[[0,0],[0,0],[-0.3,-1.35],[-0.23,0],[0,0]],"v":[[95.33,82.15],[99.08,84.18],[99,83.88],[96.08,81.93],[95.33,82.15]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.06,-0.97],[0,0]],"o":[[0,0],[0.61,-0.75],[0,0],[0,0]],"v":[[113.31,103.36],[117.85,97.79],[119.62,98.48],[119.04,108.72]],"c":false}}},{"ty":"st","lc":3,"lj":2,"ml":4,"o":{"k":100},"w":{"k":1.3},"c":{"k":[0.4,0.62,0.96,1]},"hd":false},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[75,75]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0.83],[0.83,0],[0,-0.83],[-0.83,0]],"o":[[0.83,0],[0,-0.83],[-0.83,0],[0,0.83],[0,0]],"v":[[126.15,32.62],[127.65,31.12],[126.15,29.62],[124.65,31.12],[126.15,32.62]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0.15,-0.3],[0,0],[-1.88,-4.2],[0,0],[2.18,-1.05],[0.3,-0.07],[2.48,-7.35],[0,0],[0,0],[0,0],[0,0],[-12.38,-3.9],[-2.4,0],[0,0],[0,0.53],[0,0],[2.55,0.07],[0,0],[0.08,1.5],[0,0],[0,0],[-0.15,1.05],[0,0],[0,0],[0.6,4.65],[0,0],[0,0],[-0.38,2.85],[1.12,3.15],[0,0],[1.5,-0.23],[0,0],[0,0],[0.82,-0.38],[0,0]],"o":[[-0.3,0.15],[0,0],[-2.02,4.12],[0,0],[1.05,2.18],[-0.23,0.07],[-8.18,2.25],[0,0],[0,0],[0,0],[0,0],[-3.9,12.38],[2.32,0.75],[0,0],[0.52,0],[0,0],[0,-2.62],[0,0],[-1.5,0],[0,0],[0,0],[0,-1.05],[0,0],[0,0],[0.9,-4.57],[0,0],[0,0],[2.32,-2.48],[0.38,-2.48],[0,0],[-0.6,-1.35],[0,0],[0,0],[-0.38,-0.82],[0,0],[0,0]],"v":[[80.1,72.38],[79.35,73.12],[75.08,81.9],[74.85,95.1],[75,95.4],[72.9,101.25],[72.15,101.55],[56.1,115.95],[54.97,119.32],[53.7,123.3],[51.75,129.38],[49.65,135.9],[64.95,165.38],[72.07,166.5],[102.15,166.5],[103.12,165.52],[103.12,164.1],[98.48,159.3],[98.33,159.3],[95.48,156.6],[95.48,156.45],[95.62,127.72],[95.93,124.57],[97.05,119.1],[97.2,118.5],[97.65,104.47],[96.97,99],[97.2,98.77],[101.32,90.82],[100.2,82.34],[100.12,82.2],[96.68,80.25],[86.78,81.67],[82.43,73.12],[80.25,72.3],[80.1,72.37]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.23,-0.3],[0,0],[0,0],[0,0],[-0.3,-1.05],[0.38,-2.32],[2.32,-2.4],[0,0],[0,0],[0.9,-4.58],[0,0],[0,0],[0.07,-0.98],[0,0],[0,0],[-2.03,-0.07],[0,0],[-0.07,-2.03],[0,0],[0,0],[2.25,0.68],[-3.75,11.85],[0,0],[0,0],[0,0],[0,0],[0,0],[-7.88,2.18],[-0.3,0.07],[1.27,2.62],[-1.8,3.9],[0,0],[0,0],[-0.15,0.07]],"o":[[0.38,-0.15],[0,0],[0,0],[0,0],[1.05,-0.15],[1.05,3],[-0.38,2.7],[0,0],[0,0],[0.6,4.57],[0,0],[0,0],[-0.23,0.98],[0,0],[0,0],[0,2.02],[0,0],[2.1,0],[0,0],[0,0],[-2.32,0],[-11.85,-3.75],[0,0],[0,0],[0,0],[0,0],[0,0],[2.32,-7.12],[0.3,-0.07],[2.7,-1.27],[-1.88,-3.9],[0,0],[0,0],[0.07,-0.15],[0,0]],"v":[[80.55,73.2],[81.53,73.43],[81.6,73.5],[86.25,82.73],[96.9,81.23],[99.3,82.73],[100.35,90.68],[96.22,98.32],[95.92,98.62],[96.67,104.62],[96.22,118.35],[96.07,118.95],[94.95,124.43],[94.57,127.36],[94.57,127.8],[94.43,156.61],[98.1,160.43],[98.25,160.43],[102.07,164.11],[102.07,165.68],[72,165.68],[65.18,164.63],[50.55,136.36],[52.95,128.78],[54.6,123.68],[55.8,120.08],[56.85,116.93],[57.07,116.33],[72.38,102.45],[73.27,102.15],[75.82,95.03],[75.75,82.65],[75.9,82.35],[80.25,73.58],[80.55,73.2]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.65,1.35],[-1.05,3.68],[1.35,0.75],[0.45,-0.3],[1.05,-2.4],[-0.98,-0.75]],"o":[[1.05,0.9],[2.77,-2.32],[0.45,-1.57],[-0.45,-0.23],[-3.45,2.02],[-2.62,6.07],[0,0]],"v":[[54.37,123.97],[60,121.72],[64.64,112.72],[65.17,105.37],[63.67,105.75],[57.37,114.14],[54.37,123.97]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.82,0.89,0.99,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[6.52,-4.8],[0.3,-0.07],[0.38,1.42],[-3.82,2.18],[-0.75,1.88],[0.38,4.73],[-0.9,1.95]],"o":[[0,0],[4.43,6.82],[-2.93,2.18],[-3.75,0.82],[-0.38,-1.57],[5.1,-2.85],[1.05,-2.62],[-0.23,-3.45],[0,0]],"v":[[75.6,81.15],[79.35,86.92],[75.6,107.7],[68.85,111],[59.85,110.1],[68.25,103.5],[75.75,98.77],[73.95,89.47],[75.6,81.14]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.68,0.8,0.98,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-5.85,-10.43],[-2.25,-1.05],[1.73,5.55],[0.45,0.6],[2.18,0.6]],"o":[[-0.6,1.27],[3.52,6.3],[3.52,-7.2],[-0.9,-2.85],[-3.98,-5.62],[0,0]],"v":[[51.45,132.07],[52.12,154.57],[63.38,164.7],[66.07,145.57],[63.38,140.18],[51.45,132.07]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-15.7],[15.7,0],[1.5,0.2],[-0.1,0.3],[-1.5,0],[0,15.1],[15.2,0],[0.9,-14.2],[0,0],[-14.8,0]],"o":[[15.7,0],[0,15.7],[-1.5,0],[0.1,-0.3],[1.4,0.2],[15.2,0],[0,-15.1],[-14.6,0],[0,0],[1.3,-14.3],[0,0]],"v":[[119.18,79.84],[147.68,108.24],[119.18,136.64],[114.68,136.34],[114.88,135.34],[119.18,135.64],[146.68,108.24],[119.18,80.84],[91.78,106.34],[90.88,105.44],[119.18,79.84]],"c":true}}},{"ty":"st","lc":1,"lj":1,"ml":4,"o":{"k":100},"w":{"k":1.2},"c":{"k":[0.68,0.8,0.98,1]},"hd":false},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[75,75]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.23],[-2.7,-3.15],[0.22,-0.15],[0.15,0.15],[0,4.43],[-0.23,0]],"o":[[0.23,0],[0,4.2],[0.15,0.15],[-0.23,0.15],[-2.77,-3.3],[0,-0.15],[0,0]],"v":[[71.55,80.63],[71.92,81.01],[76.12,92.41],[76.05,92.93],[75.52,92.86],[71.17,81],[71.55,80.63]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.23],[0.23,0],[2.47,-1.2],[0.15,0.15],[-0.15,0.15],[-2.92,0]],"o":[[0.23,0],[0,0.23],[-2.85,0],[-0.15,0.07],[-0.07,-0.15],[2.62,-1.27],[0,0]],"v":[[89.55,62.71],[89.92,63.08],[89.55,63.46],[81.52,65.33],[81,65.18],[81.15,64.66],[89.55,62.71]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.23],[6.82,-2.85],[2.48,0],[0,0.23],[-0.23,0],[-2.18,0.9],[0,7.2],[-0.23,0]],"o":[[0.23,0],[0,7.5],[-2.25,0.9],[-0.23,0],[0,-0.23],[2.4,0],[6.52,-2.7],[0,-0.15],[0,0]],"v":[[107.62,80.63],[108,81.01],[96.68,97.96],[89.55,99.38],[89.18,99.01],[89.55,98.63],[96.38,97.28],[107.25,81.01],[107.62,80.63]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.23],[0.23,0],[2.47,-1.2],[0.15,0.15],[-0.15,0.15],[-2.92,0]],"o":[[0.23,0],[0,0.23],[-2.85,0],[-0.15,0.07],[-0.07,-0.15],[2.62,-1.27],[0,0]],"v":[[89.55,62.71],[89.93,63.08],[89.55,63.46],[81.53,65.33],[81,65.18],[81.15,64.66],[89.55,62.71]],"c":true}}},{"ty":"fl","o":{"k":60},"c":{"k":[0.1,0.45,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-12],[-12,0],[0,12],[12,0]],"o":[[-12,0],[0,12],[12,0],[0,-12],[0,0]],"v":[[89.4,59.49],[67.65,81.17],[89.4,102.84],[111.15,81.17],[89.4,59.49]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-11.18],[11.18,0],[0,11.18],[-11.18,0]],"o":[[11.18,0],[0,11.18],[-11.18,0],[0,-11.18],[0,0]],"v":[[89.4,60.99],[109.65,81.17],[89.4,101.34],[69.15,81.17],[89.4,60.99]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,11.35],[11.39,0],[0,-11.35],[-11.39,0]],"o":[[11.39,0],[0,-11.35],[-11.39,0],[0,11.35],[0,0]],"v":[[89.4,101.72],[110.02,81.17],[89.4,60.62],[68.77,81.17],[89.4,101.72]],"c":true}}},{"ty":"fl","o":{"k":60},"c":{"k":[0.1,0.45,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[10.65,-7.8],[0,0],[0.45,-0.45],[0,0],[0.9,-0.97],[0,0],[0,0],[0.38,-4.57],[0,0],[0.07,-1.2],[0,0],[0,-0.07],[0,0],[0.23,-1.42],[0,0],[0,0],[1.5,-2.48],[0,0],[0,0],[10.65,7.65],[0,0],[-0.07,0.3],[0,0],[0,0],[0.6,4.58],[0,0],[0,9.23],[11.62,0],[0.9,-10.72],[5.93,-2.25],[0,0],[0,0],[0,0],[-1.2,9.52],[-9.52,0.82],[-2.55,-0.82],[0,0],[0,0],[-1.72,-1.12],[-1.88,-0.75],[0,0],[-1.28,-0.45],[-4.57,1.95],[0,0],[0,0],[-0.23,0.15],[0,0],[-1.72,0.53],[-3.15,-0.45],[-2.33,-1.35],[-3.38,0.9],[0,0],[-6.23,-11.85]],"o":[[6.15,11.7],[0,0],[-0.45,0.45],[0,0],[-0.98,0.9],[0,0],[0,0],[-3.07,3.38],[0,0],[0,0.23],[0,0],[-0.07,1.27],[0,0],[0.07,1.43],[0,0],[0,0],[-0.52,2.7],[0,0],[0,0],[-7.27,10.65],[0,0],[0.07,-0.3],[0,0],[0,0],[0.9,-4.5],[0,0],[8.25,-2.85],[0,-11.55],[-11.02,0],[-4.35,-4.27],[0,0],[0,0],[0,0],[-7.5,-6.23],[1.2,-9.52],[5.4,-0.45],[0,0],[0,0],[2.02,0.75],[1.88,0.52],[0,0],[1.2,0.52],[4.57,1.57],[0,0],[0,0],[1.05,-0.45],[0,0],[1.57,-0.9],[2.93,-0.82],[2.77,0.45],[2.77,-1.88],[0,0],[12.98,-3.68],[0,0]],"v":[[163.72,39.9],[155.92,73.8],[143.25,83.02],[141.89,84.3],[141.45,84.75],[138.67,87.45],[138.15,87.97],[137.92,88.27],[132.45,100.2],[132.45,100.64],[132.3,103.27],[132.3,103.64],[132.15,106.27],[132.15,106.79],[131.92,111.07],[131.85,111.59],[131.77,112.04],[128.7,119.84],[128.4,120.21],[128.17,120.52],[95.47,126.14],[95.25,125.91],[95.39,125.09],[96.52,119.61],[96.67,119.01],[97.12,105.29],[96.67,101.61],[110.84,81.81],[89.84,60.88],[68.92,80.08],[52.04,76.56],[51.74,76.63],[51.29,76.86],[41.99,68.68],[32.09,43.41],[50.54,25.71],[62.47,26.23],[62.7,26.31],[63.14,26.46],[68.84,29.23],[74.47,31.33],[75.07,31.56],[78.75,32.98],[92.55,32.76],[95.1,31.71],[95.47,31.56],[97.72,30.58],[97.8,30.58],[102.75,28.48],[111.97,27.88],[119.7,30.58],[128.85,26.38],[130.8,25.86],[163.72,39.88]],"c":true}}},{"ty":"fl","o":{"k":60},"c":{"k":[0.1,0.45,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.45,-0.6],[4.57,-6.75],[0,0],[0,0],[-5.55,-3.9],[0,0],[-1.43,-0.38],[0,0],[-1.27,-0.15],[0,0],[0,0],[-2.62,-0.82],[-1.35,-0.22],[0.23,0],[0,0],[1.43,0.15],[0,0],[0,0],[0,0],[2.1,1.2],[0.45,0.38],[-5.25,7.57],[0,0],[0,0],[3.68,5.18],[0.38,0.38],[3.08,-3],[0,0],[0,0],[0.82,0.82],[-0.75,0.9],[0,0],[0,0],[-4.95,-4.8]],"o":[[0.52,0.52],[4.73,6.68],[0,0],[0,0],[-3.98,5.55],[0,0],[0.9,0.52],[0,0],[0.98,0.23],[0,0],[0,0],[2.02,1.57],[1.27,0.45],[-0.23,0.07],[0,0],[-1.57,0],[0,0],[0,0],[0,0],[-3.75,-0.45],[-0.52,-0.3],[-7.5,-5.32],[0,0],[0,0],[3.68,-5.18],[-0.3,-0.38],[-3.07,-3],[0,0],[0,0],[-0.9,0.9],[-0.82,-0.82],[0,0],[0,0],[4.73,-4.95],[0,0]],"v":[[45.82,113.55],[47.32,115.28],[47.55,137.55],[47.32,137.85],[45.22,140.85],[48.15,158.03],[49.27,158.7],[52.88,160.05],[53.4,160.2],[56.77,160.73],[58.12,160.88],[58.27,160.88],[65.25,164.55],[69.23,165.45],[68.48,165.6],[63,165.6],[58.57,165.38],[57.75,165.3],[57.38,165.3],[55.88,165.15],[47.1,162.68],[45.6,161.7],[41.48,138.45],[41.62,138.22],[43.73,135.22],[43.73,117.9],[42.75,116.77],[31.65,116.77],[31.5,116.92],[29.55,118.95],[26.4,119.02],[26.25,115.95],[26.33,115.87],[28.28,113.85],[45.83,113.55]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]}]}],"meta":{"g":"LF SVG to Lottie"}} \ No newline at end of file
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.png b/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.png deleted file mode 100644 index 6ba6c2e0a..0000000 --- a/ash/public/cpp/resources/unscaled_resources/phone_hub_error_state_image.png +++ /dev/null Binary files differ
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.json b/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.json new file mode 100644 index 0000000..416e3d7 --- /dev/null +++ b/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.json
@@ -0,0 +1 @@ +{"v":"5.6.6","ip":0,"op":1,"fr":60,"w":256,"h":256,"layers":[{"ind":299,"nm":"surface1330","ao":0,"ip":0,"op":60,"st":0,"ty":4,"ks":{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[133.33,133.33]},"sk":{"k":0},"sa":{"k":0}},"shapes":[{"ty":"gr","hd":false,"nm":"surface1330","it":[{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[1.05,0],[0.22,0.15],[-1.05,0.23],[0,0]],"o":[[0,0],[0,1.05],[-0.38,0],[0.52,-0.98],[0,0],[0,0]],"v":[[98.62,80.14],[98.62,80.44],[96.75,82.31],[95.85,82.09],[98.33,80.29],[98.48,80.29]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.81,0.89,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,1.04],[1.04,0],[0,-1.04],[-1.04,0]],"o":[[1.04,0],[0,-1.04],[-1.04,0],[0,1.04],[0,0]],"v":[[96.75,82.31],[98.62,80.43],[96.75,78.56],[94.88,80.43],[96.75,82.31]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.97,0.51,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.08],[0.82,0.22],[-0.07,0.82],[-0.15,0],[0,0]],"o":[[0.07,0],[-0.3,0.75],[-0.82,-0.15],[0,-0.07],[0,0],[0,0]],"v":[[99.45,89.81],[99.6,90.04],[97.65,91.09],[96.3,89.29],[96.53,89.14],[99.45,89.81]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0.07,-0.68],[0,0],[0,0],[0.23,-1.57],[0,0],[0,0],[0,0],[0.07,-0.53],[0,0],[0,0],[0.22,0],[0,0],[0,0],[0,0.22],[0,0],[0,0],[-0.6,0.15],[0,0],[0,0],[-1.5,0.3],[0,0],[0,0],[-0.6,-0.08],[0,0],[0,0]],"o":[[0.68,0.15],[0,0],[0,0],[1.27,0.82],[0,0],[0,0],[0,0],[0.52,0.3],[0,0],[0,0],[-0.07,0.23],[0,0],[0,0],[-0.23,-0.07],[0,0],[0,0],[0.15,-0.6],[0,0],[0,0],[0.38,-1.65],[0,0],[0,0],[0.15,-0.6],[0,0],[0,0],[0,0]],"v":[[100.13,79.16],[101.18,80.59],[101.18,80.66],[101.33,80.81],[102.98,84.63],[102.98,84.93],[102.68,86.43],[102.75,86.43],[103.5,87.86],[103.5,88.16],[103.43,88.61],[102.9,88.98],[102.83,88.98],[93.83,87.26],[93.45,86.73],[93.45,86.66],[93.53,86.21],[94.73,85.01],[94.95,85.01],[95.25,83.51],[98.25,80.36],[98.55,80.36],[98.55,80.21],[99.91,79.32],[100.05,79.32],[100.13,79.17]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.99,0.79,0.2,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[-6.9,-0.52],[0,0],[0,0],[0,0],[0,0],[0.15,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[7.43,0.15],[0,0],[0,0],[0,0],[0,0],[-0.07,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[117.3,162.34],[110.93,151.61],[111.82,151.61],[133.27,152.74],[134.62,152.89],[136.12,153.04],[134.77,153.86],[134.25,154.16],[133.95,154.31],[133.35,154.61],[132.75,154.98],[130.72,156.11],[129.22,156.86],[128.02,157.46],[126.75,158.06],[125.7,158.59],[122.7,156.79],[123.3,159.86],[117.3,162.34]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.23,0.07],[0,0],[0,0],[0,0],[0,0],[5.77,0.23],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.3,-0.15],[0,0],[0,0],[0,0],[0,0],[-5.48,-0.45],[0,0],[0,0],[0,0]],"v":[[112.65,152.59],[117.68,161.07],[122.03,159.12],[121.13,154.69],[125.63,157.39],[126.75,156.87],[128.55,155.97],[130.2,155.07],[130.95,154.7],[131.7,154.32],[132.38,153.95],[132.9,153.64],[131.7,153.57],[114.82,152.59],[113.25,152.52],[112.65,152.59]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[5.47,-0.9],[3.45,2.4],[0,0],[0,0],[0,0],[-0.82,0.23],[0,0],[-0.23,0.08],[0,0],[-0.3,0],[0,0],[-0.22,0],[0,0],[-0.15,0],[0,0],[-0.3,0.07],[0,0],[-0.3,0.07],[0,0],[-0.38,0.07],[0,0],[0,0],[0,0],[0,0],[-0.23,0.07],[0,0],[0,0],[0,0]],"o":[[0,0],[-4.12,3.38],[-5.32,0.9],[0,0],[0,0],[0,0],[0.75,-0.23],[0,0],[0.23,-0.07],[0,0],[0.3,-0.07],[0,0],[0.3,-0.07],[0,0],[0.15,0],[0,0],[0.3,-0.07],[0,0],[0.3,-0.07],[0,0],[0.38,-0.07],[0,0],[0,0],[0,0],[0,0],[0.23,0],[0,0],[0,0],[0,0],[0,0]],"v":[[83.93,151.84],[82.73,152.82],[68.33,159.19],[55.2,156.94],[54.98,156.79],[54.23,156.27],[55.12,155.97],[57.52,155.22],[58.27,154.99],[59.02,154.77],[59.77,154.62],[60.6,154.47],[61.42,154.32],[62.25,154.17],[64.04,153.88],[64.49,153.8],[65.47,153.65],[66.45,153.5],[67.42,153.36],[68.4,153.21],[69.45,153.06],[70.5,152.91],[71.55,152.76],[72.68,152.61],[74.93,152.46],[77.32,152.32],[77.93,152.24],[79.12,152.17],[81.67,152.02],[83.92,151.87]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0.23,-0.07],[0,0],[0.23,-0.07],[0,0],[0,0],[0,0],[0,0],[0.15,0],[0,0],[0.45,-0.08],[0,0],[0.3,-0.07],[0,0],[0.68,-0.15],[0,0],[0.52,-0.15],[0,0],[0,0],[0,0],[0,0],[-4.28,0.6],[0,0],[-3.52,2.48],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[-0.23,0],[0,0],[-0.23,0],[0,0],[0,0],[0,0],[0,0],[-0.15,0],[0,0],[-0.52,0.07],[0,0],[-0.3,0.07],[0,0],[-0.75,0.15],[0,0],[-0.52,0.15],[0,0],[0,0],[0,0],[0,0],[2.93,1.73],[0,0],[4.5,-0.75],[0,0],[0,0]],"v":[[80.55,153.19],[80.85,152.96],[79.88,153.04],[78.6,153.11],[76.2,153.26],[75.6,153.34],[74.4,153.48],[73.8,153.56],[72.68,153.63],[71.62,153.78],[70.5,153.93],[68.4,154.23],[67.88,154.3],[66.9,154.45],[65.47,154.68],[64.5,154.82],[63.6,154.97],[62.7,155.12],[60.6,155.57],[59.77,155.72],[58.2,156.09],[57.45,156.32],[56.77,156.55],[56.4,156.62],[56.55,156.7],[67.35,158.42],[68.1,158.27],[80.1,153.47],[80.55,153.17]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-1.65,-4.8],[-1.43,-6.9],[0,0],[0,0],[0,0],[2.18,1.2],[1.88,4.95],[-3.97,6.38],[-0.9,0.98],[0,0],[0,0]],"o":[[0,0],[2.25,3.9],[2.4,6.98],[0,0],[0,0],[0,0],[-2.85,0.07],[-3.23,-1.8],[-2.48,-6.38],[0.6,-0.98],[0,0],[0,0],[0,0]],"v":[[35.25,103.77],[35.55,104.37],[41.32,117.42],[46.95,138.19],[47.18,139.39],[47.25,139.99],[46.65,139.99],[39.07,138.27],[30.22,127.09],[32.17,107.59],[34.42,104.66],[34.72,104.29],[35.25,103.77]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.45,-0.82],[-2.32,-6.08],[-3,-1.65],[-2.18,-0.07],[0,0],[0,0],[2.03,6.07],[0,0],[1.88,3.53]],"o":[[0,0],[-0.68,0.75],[-3.82,6.15],[1.88,4.8],[1.73,0.98],[0,0],[0,0],[-1.2,-6],[0,0],[-1.43,-4.12],[0,0]],"v":[[35.02,105.34],[34.88,105.57],[33.07,107.96],[31.2,126.57],[39.6,137.21],[45.52,138.79],[46.05,138.79],[45.9,138.19],[41.1,120.04],[40.35,117.64],[35.4,106.16]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.68,0.8,0.98,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[3.6,-1.65],[0,0],[0,0],[0,0],[0,0],[0,0],[-7.28,-0.67]],"o":[[0,0],[-2.02,1.2],[0,0],[0,0],[0,0],[0,0],[0,0],[7.88,0.15],[0,0]],"v":[[134.55,153.41],[134.48,153.49],[126.08,157.84],[125.63,157.99],[121.88,155.74],[122.63,159.49],[117.53,161.74],[111.83,152.14],[134.55,153.41]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[3.38,2.4],[-12.15,0.68],[5.4,-0.9]],"o":[[-5.32,0.9],[6,-2.02],[-4.05,3.3],[0,0]],"v":[[68.25,158.74],[55.27,156.41],[82.42,152.44],[68.25,158.74]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.43,-7.27],[2.18,1.2],[-8.62,13.8],[-1.05,1.05],[-1.57,-4.73]],"o":[[2.48,7.35],[-2.77,0.07],[-5.48,-3],[0.68,-1.12],[2.18,3.9],[0,0]],"v":[[40.88,117.49],[46.73,139.39],[39.38,137.74],[32.62,107.74],[35.18,104.51],[40.88,117.49]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.09,0.35,0.74,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.2,-2.78],[-0.68,-13.8],[-27,0.15],[-18.75,-4.12],[0,-2.18],[2.1,0],[0,0],[0.15,17.25],[0,0],[-3.97,0],[-1.34,-1.89],[-0.23,-0.71]],"o":[[1.2,3.38],[4.8,14.18],[6,-4.8],[25.27,-0.15],[2.18,0.45],[0,2.1],[0,0],[-17.25,-0.07],[0,0],[0,-3.98],[2.4,-0.06],[0.41,0.59],[0,0]],"v":[[36.6,107.22],[40.88,116.45],[49.12,159.2],[98.62,151.7],[164.7,157.62],[168.38,161.45],[164.62,165.2],[54.82,164.89],[23.4,133.62],[23.25,109.55],[29.64,101.44],[35.25,103.77],[36.6,107.22]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.09,0.35,0.74,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.1,0.03],[0,0],[-0.1,0.03],[0,0],[0,0],[0,0],[-0.04,0.07],[0,0],[-0.04,0.07],[0,0],[-0.04,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.04,0.07],[-0.19,-0.27],[0.27,-0.19],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.04,-0.07],[0,0],[0.14,-0.09],[0,0],[0.1,-0.03],[0,0],[0.07,-0.13],[0,0],[0.1,-0.03],[0,0],[0.1,-0.03],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.11,-0.2],[0,0],[0,0],[0.84,-0.9],[0,0],[0.04,-0.07],[0.12,0.24],[-0.17,0.16],[-1.21,1.73],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.04,-0.07],[0,0],[0.04,-0.07],[0,0],[0,0],[0,0],[0.04,-0.07],[0,0],[0.04,-0.07],[0,0],[0.04,-0.07],[0,0],[0,0],[0,0],[0.04,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.04,-0.07],[0.18,-0.16],[0.16,0.18],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.04,0.07],[0,0],[-0.14,0.09],[0,0],[-0.04,0.07],[0,0],[-0.07,0.13],[0,0],[-0.04,0.07],[0,0],[-0.04,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.11,0.2],[0,0],[0,0],[-0.77,0.96],[0,0],[-0.04,0.07],[-0.21,0.23],[-0.12,-0.24],[1.19,-1.23],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[119.52,81.59],[120.17,80.58],[121.61,78.29],[122.04,77.67],[122.65,76.72],[123.04,76.17],[123.44,75.61],[124.5,74.15],[124.69,73.65],[125.01,73.23],[125.19,73.07],[125.83,72.23],[126,72.07],[126.29,71.71],[126.92,71.03],[127.21,70.67],[127.38,70.51],[127.73,70.19],[127.91,70.03],[128.6,69.39],[128.78,69.23],[129.12,68.91],[130.38,67.89],[130.58,67.84],[130.72,67.74],[131.03,67.49],[131.41,67.27],[132.64,66.58],[133.61,66.09],[135.74,64.87],[136.39,64.46],[137.01,64.11],[137.77,63.68],[138.08,63.42],[139.19,62.66],[139.61,62.37],[139.75,62.28],[140.45,62.41],[140.32,63.11],[140.04,63.3],[139.8,63.42],[138.69,64.19],[138.17,64.5],[137.41,64.94],[136.52,65.47],[134.14,66.81],[133.35,67.32],[132.12,68],[131.74,68.22],[131.22,68.54],[130.95,68.73],[130.73,68.95],[130.18,69.34],[129.87,69.59],[129.69,69.75],[129,70.39],[128.82,70.55],[128.12,71.19],[127.78,71.51],[127.43,71.83],[127.25,71.99],[126.97,72.35],[126.68,72.71],[126.4,73.06],[126.22,73.22],[125.94,73.58],[125.76,73.74],[124.8,75],[124.45,75.49],[124.29,75.92],[123.75,76.74],[123.36,77.29],[122.79,78.18],[122.18,79.12],[121.02,81.05],[120.55,81.74],[120.37,82.07],[119.51,83.31],[119.33,83.64],[118.96,84.29],[118.57,84.85],[118.18,85.4],[117.82,85.89],[117.83,85.89],[115.43,88.67],[115.04,89.06],[114.87,89.22],[114.2,89.19],[114.22,88.52],[117.8,84.24],[118.19,83.68],[118.58,83.13],[118.91,82.54],[119.34,81.92],[119.52,81.59]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.68,0.8,0.98,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-6.04,1.62],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-2.17,2.83],[-0.3,1.46],[-0.23,-0.04],[0.04,-0.23],[1.14,-1.6],[4.41,-1.15],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.17,0.01],[0,0],[0,0],[0.07,0.04],[0,0],[0.1,-0.03],[0,0],[0.04,-0.07],[0,0],[0.04,-0.07],[0,0],[1.34,-5.52],[0.23,0.04],[-0.04,0.23]],"o":[[1.39,-5.91],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[4.21,-1.1],[1.07,-1.46],[0.04,-0.23],[0.23,0.04],[-0.37,1.6],[-2.31,3.09],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.27,0.02],[0,0],[0,0],[-0.1,0.03],[0,0],[-0.1,0.03],[0,0],[-0.1,0.03],[0,0],[-0.1,0.03],[0,0],[-5.7,1.47],[-0.08,0.3],[-0.23,-0.04],[0,0]],"v":[[114.72,85.62],[126.92,73.34],[127.73,73.11],[129.22,72.91],[129.62,72.79],[130.3,72.65],[131.04,72.55],[131.58,72.5],[132.76,72.39],[135.05,72.11],[136.17,71.96],[136.91,71.86],[137.38,71.77],[138.87,71.57],[139.44,71.46],[139.95,71.32],[140.32,71.27],[150.11,65.37],[152.27,61],[152.83,60.62],[153.21,61.18],[150.93,65.91],[140.59,72.19],[140.05,72.23],[139.3,72.33],[138.96,72.48],[138.22,72.59],[137.81,72.7],[137.17,72.78],[135.69,72.98],[134.51,73.1],[132.55,73.38],[131.97,73.49],[131.33,73.57],[130.69,73.64],[130.12,73.75],[129.85,73.77],[129.38,73.86],[129.11,73.88],[128.63,73.96],[128.43,74.02],[127.86,74.13],[127.65,74.19],[127.18,74.27],[115.64,85.8],[115.09,86.18],[114.71,85.62]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.27,0.51,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.02,-0.08],[-0.11,-0.21],[0,0],[0,0],[-0.2,-0.12],[0,0],[-0.02,0.07],[0.38,0]],"o":[[0,0],[0.01,0.09],[0.05,0.24],[0,0],[0,0],[0.17,0.17],[0,0],[0.02,-0.07],[0.08,-0.37],[0,0]],"v":[[133.73,51.21],[132.48,51.23],[132.52,51.49],[132.78,52.16],[133.53,52.16],[133.21,52.74],[133.77,53.17],[134.28,52.25],[134.33,52.03],[133.73,51.21]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.68,0.8,0.98,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.37,0.32],[0,0],[0.32,1.37],[1.37,-0.32],[0,0],[0.2,-0.96],[-0.08,-0.32]],"o":[[0.32,1.37],[0,0],[1.37,-0.32],[-0.32,-1.37],[0,0],[-1.03,0.16],[-0.08,0.37],[0,0]],"v":[[132.52,51.49],[135.56,53.44],[141.36,52.14],[143.3,49.11],[140.27,47.16],[134.46,48.53],[132.52,50.42],[132.52,51.5]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.27,-0.52],[0,0],[-0.25,0.48],[0,0],[0.53,0.04]],"o":[[0,0],[-0.54,0.04],[0,0],[0.29,0.45],[0,0],[0.33,-0.47],[0,0]],"v":[[133.85,51.01],[129.94,51.02],[129.32,52.12],[131.19,55.58],[132.43,55.54],[134.38,52.12],[133.85,51.01]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.97,0.51,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.23,-0.38],[0,0],[-0.23,-0.38],[0,0],[-0.45,0],[0,0],[-0.23,0.38],[0,0],[0.23,0.38],[0,0],[0.38,0]],"o":[[0,0],[-0.45,0],[0,0],[-0.23,0.38],[0,0],[0.23,0.38],[0,0],[0.45,0],[0,0],[0.23,-0.38],[0,0],[-0.23,-0.38],[0,0]],"v":[[176.48,39.04],[172.35,39.04],[171.3,39.64],[169.2,43.09],[169.2,44.29],[171.3,47.74],[172.35,48.34],[176.48,48.34],[177.53,47.74],[179.63,44.29],[179.63,43.09],[177.53,39.64],[176.48,39.04]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.08,-0.07],[0,0],[0,0],[0,0],[0.08,0],[0,0],[0.08,0.07],[0,0],[0,0],[0,0],[-0.08,0]],"o":[[0,0],[0.07,0],[0,0],[0,0],[0,0],[-0.07,0.07],[0,0],[-0.07,0],[0,0],[0,0],[0,0],[0.07,-0.07],[0,0]],"v":[[172.28,40.02],[176.4,40.02],[176.63,40.16],[178.73,43.61],[178.73,43.84],[176.63,47.29],[176.4,47.44],[172.28,47.44],[172.05,47.29],[169.95,43.84],[169.95,43.61],[172.05,40.16],[172.28,40.02]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.27,0.51,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.39,-1.71],[0,0],[-1.64,-0.4],[0,0],[0,0],[-0.14,0.7],[0,0],[0,0],[-0.4,1.64],[0,0],[0,0],[0.41,0.73],[0.8,0.2]],"o":[[0,0],[-1.64,-0.4],[0,0],[-0.4,1.64],[0,0],[0,0],[0.37,0.56],[0,0],[0,0],[1.64,0.4],[0,0],[0,0],[0.26,-0.79],[-0.4,-0.72],[0,0]],"v":[[118.27,64.14],[101.37,60.02],[97.65,62.36],[95.66,70.77],[97.93,74.49],[106.65,76.59],[110.64,83.21],[111.97,82.97],[113.12,78.22],[114.69,78.63],[118.41,76.36],[120.41,67.96],[120.4,67.96],[120.17,65.58],[118.27,64.14]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.36,0.73,0.45,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0.05,-0.3],[0,0],[-0.29,0.1],[0,0],[0.24,0.2]],"o":[[0,0],[-0.24,-0.2],[0,0],[-0.05,0.3],[0,0],[0.3,-0.03],[0,0]],"v":[[159.35,49.43],[154.7,45.32],[154.11,45.53],[152.92,51.66],[153.41,52.07],[159.25,50.05],[159.35,49.44]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.91,0.94,1,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-4.35,1.06],[0,0],[-1.07,-4.42],[4.35,-1.06],[0,0],[1.07,4.42]],"o":[[-1.06,-4.43],[0,0],[4.42,-1.07],[1.07,4.43],[0,0],[-4.35,1.06],[0,0]],"v":[[147.61,51.21],[153.59,41.28],[153.74,41.27],[163.61,47.33],[157.63,57.27],[157.48,57.28],[147.61,51.21]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.93,0.4,0.36,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.15,0.15],[0,0],[0.07,0.15],[0,0],[0.15,0],[0,0],[0.15,-0.15],[0,0],[0,-0.15],[0,0],[-0.15,0]],"o":[[0.15,0],[0,0],[0.07,-0.15],[0,0],[-0.07,-0.15],[0,0],[-0.15,0],[0,0],[-0.07,0.15],[0,0],[0.07,0.15],[0,0]],"v":[[125.4,61.99],[125.85,61.84],[127.8,59.52],[127.87,59.07],[126.89,56.14],[126.52,55.84],[123.59,55.24],[123.14,55.39],[121.2,57.71],[121.12,58.16],[122.1,61.09],[122.47,61.39]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.99,0.79,0.2,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,-0.45],[0.45,0],[0,0],[0,0.45],[-0.45,0]],"o":[[0,0],[0.45,0],[0,0.45],[0,0],[-0.45,0],[0,-0.45],[0,0]],"v":[[81.38,115.24],[115.88,115.24],[116.62,115.99],[115.88,116.74],[81.38,116.74],[80.62,115.99],[81.38,115.24]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,-0.82],[0.07,-0.15],[0,0],[0.68,0],[0,0],[0,0.82],[-0.07,0.15],[0,0],[-0.68,0]],"o":[[0,0],[0.82,0],[0,0.15],[0,0],[-0.15,0.68],[0,0],[-0.82,0],[0,-0.15],[0,0],[0.15,-0.68],[0,0]],"v":[[92.25,92.74],[121.8,92.74],[123.3,94.24],[123.23,94.62],[117.68,115.62],[116.25,116.74],[86.7,116.74],[85.2,115.24],[85.27,114.87],[90.82,93.87],[92.25,92.74]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.35,-1.2],[-0.23,-0.3],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.35,0],[0.68,0.52],[0,0],[0,0],[0.07,0.15],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,0],[0.3,0.82],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.15,0.15],[0.9,-0.82],[0,0],[0,0]],"o":[[1.27,-1.35],[0.23,0.23],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.52,1.35],[-0.38,0],[0,0],[0,0],[-0.07,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.07,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.23,0.15],[0.45,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.15,-0.23],[-0.9,-0.82],[0,0],[0,0],[0,0]],"v":[[80.25,107.66],[84.98,107.43],[85.65,108.26],[86.48,109.76],[86.93,110.58],[87.3,111.26],[87.53,111.63],[87.6,111.86],[87.68,112.01],[86.55,114.63],[84.98,113.81],[84.75,113.58],[84.38,113.28],[84.07,112.98],[83.47,112.38],[83.17,112],[82.42,111.25],[82.05,110.8],[81.82,110.58],[82.57,109.98],[83.02,110.5],[83.77,111.4],[84.14,111.77],[84.29,111.85],[85.2,112.75],[85.34,112.82],[85.57,113.05],[85.8,113.2],[86.02,113.42],[86.39,113.57],[86.62,112.3],[86.62,112.22],[86.55,112.07],[86.4,111.77],[86.1,111.1],[85.72,110.35],[84.82,108.77],[84.38,108.17],[81.15,108.17],[81.07,108.25],[80.25,107.64]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-0.98],[1.2,-0.6],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.67,-0.68],[1.5,0.3],[-0.07,0.3],[-0.3,-0.07],[-2.55,2.32],[-0.98,0.6],[-0.15,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0.3],[0.6,0],[1.73,-0.68],[0.08,0.3],[-0.3,0.08],[-0.98,0]],"o":[[1.12,0],[0,0.82],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.9,0.52],[-2.7,2.55],[-0.3,-0.07],[0.07,-0.3],[1.12,0.23],[0.75,-0.75],[0.07,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.75,-0.38],[0,-0.38],[-0.82,0],[-0.23,0.07],[-0.07,-0.23],[1.65,-0.75],[0,0]],"v":[[83.85,114.71],[85.65,116.21],[83.85,118.23],[83.03,118.61],[81.68,119.21],[80.78,119.59],[80.1,119.89],[79.2,120.34],[78.75,120.64],[76.35,122.44],[70.05,125.81],[69.68,125.21],[70.28,124.84],[75.75,121.69],[78.38,119.74],[78.68,119.59],[79.05,119.44],[79.43,119.21],[79.88,118.99],[80.55,118.69],[81.68,118.16],[82.5,117.79],[83.55,117.34],[83.7,117.27],[84.75,116.21],[83.93,115.69],[80.18,116.67],[79.58,116.37],[79.88,115.77],[83.86,114.71]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.97,-1.12],[-0.08,-0.45],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.2,0.23],[0.45,0.97],[0,0],[0,0],[-0.3,-0.07],[0.15,0.82],[0,0],[0,0],[0,0],[0,0],[0,0],[0.15,0.23],[0.75,-0.6],[0,0],[0,0]],"o":[[1.12,-1.05],[0.3,0.3],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.23,1.43],[-0.68,-0.15],[0,0],[0,0],[0.38,0.82],[0.3,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,-0.3],[-0.6,-0.68],[0,0],[0,0],[0,0]],"v":[[78.08,108.04],[81.98,108.26],[82.58,109.39],[82.88,110.51],[83.25,111.86],[83.4,112.54],[83.48,112.99],[83.55,113.21],[83.55,113.36],[82.12,115.69],[80.4,114.04],[80.32,113.89],[81.22,113.52],[82.27,114.79],[82.57,113.59],[82.5,113.36],[82.35,112.84],[82.12,112.02],[81.9,111.12],[81.6,109.62],[81.22,108.87],[78.82,108.72],[78.75,108.79],[78.07,108.04]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.2,-0.98],[-0.22,-0.45],[0,0],[0,0],[0,0],[0,0],[0,0],[1.28,0],[0.6,0.9],[0,0],[0,0],[-0.38,0],[0.23,0.82],[0,0],[0,0],[0,0],[0,0],[0.07,0.08],[0.22,0.15],[0.68,-0.75],[0,0],[0,0]],"o":[[0.98,-1.2],[0.38,0.3],[0,0],[0,0],[0,0],[0,0],[0,0],[0.45,1.35],[-0.75,0],[0,0],[0,0],[0.52,0.75],[0.3,0],[0,0],[0,0],[0,0],[0,0],[-0.07,-0.07],[-0.15,-0.23],[-0.75,-0.6],[0,0],[0,0],[0,0]],"v":[[74.62,108.86],[78.52,108.41],[79.35,109.46],[80.25,111.48],[80.85,112.76],[81.07,113.36],[81.22,113.73],[81.3,113.81],[80.25,116.43],[78.22,115.08],[78.07,114.93],[78.9,114.41],[80.25,115.46],[80.4,114.19],[80.32,113.96],[80.1,113.51],[79.65,112.54],[78.52,110.06],[78.38,109.83],[77.85,109.16],[75.38,109.38],[75.38,109.46],[74.62,108.86]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.43,-2.7],[-0.3,-0.75],[0,0],[0,0],[0,0],[1.57,0.45],[0.98,1.43],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.07,-0.38],[0,0],[2.25,-0.53],[0.08,0.3],[-0.3,0.08],[-0.38,1.05],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.22,-0.45],[0,0],[-0.07,-0.08],[0,0],[0,0],[-0.38,-0.15],[0.22,0.68],[0,0],[0,0],[0.07,0.3],[0.3,0.68],[1.27,-0.3],[1.27,-2.03],[0,0],[0,0],[0.15,-0.3],[0,0],[0,0],[0,0],[0,0],[0,0],[0.07,-0.07],[0.3,0.15],[-0.15,0.3],[0,0],[0,0],[0,0],[0,0],[-1.65,0.38]],"o":[[1.8,-0.38],[0.38,0.68],[0,0],[0,0],[0,0],[0.52,1.57],[-0.68,-0.23],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,0.52],[0,0],[-0.52,1.43],[-0.3,0.07],[-0.07,-0.3],[1.95,-0.45],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,-0.52],[0,0],[0.07,0.07],[0,0],[0,0],[0.68,0.9],[0.9,0.23],[0,0],[0,0],[-0.07,-0.3],[-0.3,-0.75],[-1.2,-2.4],[-0.98,0.23],[0,0],[0,0],[-0.15,0.23],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,0.07],[-0.15,0.23],[-0.3,-0.15],[0,0],[0,0],[0,0],[0,0],[1.95,-3.75],[0,0]],"v":[[73.2,108.41],[78,112.31],[78.98,114.48],[79.12,114.93],[79.35,115.54],[79.5,115.91],[77.32,117.86],[74.85,115.38],[74.7,115.16],[74.62,115.91],[74.55,116.58],[74.4,117.79],[74.25,118.83],[74.25,119.06],[74.11,119.96],[73.8,121.31],[73.73,121.46],[69.61,124.38],[69,124.01],[69.38,123.41],[72.83,121.16],[72.9,121.01],[72.98,120.78],[72.98,120.63],[73.12,120.26],[73.12,120.11],[73.27,119.36],[73.5,118.01],[73.64,116.96],[73.87,115.16],[74.02,113.81],[74.02,113.43],[74.91,113.21],[75.37,114.11],[75.52,114.33],[75.97,115.08],[76.2,115.38],[77.77,116.96],[78.75,116.36],[78.67,116.05],[78.37,115.68],[78.07,114.86],[77.17,112.75],[73.42,109.38],[70.05,112.68],[69.75,113.13],[69.45,113.65],[69,114.48],[68.7,115.08],[68.47,115.45],[68.17,116.13],[67.57,117.4],[66.96,118.6],[66.82,118.9],[66.14,119.13],[65.91,118.45],[66.81,116.65],[67.41,115.45],[67.71,114.85],[67.86,114.55],[73.19,108.4]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.15,-0.23],[-0.15,-0.45],[0.98,0],[2.17,2.55],[0,0],[0,-0.38],[0.82,0.15],[0.3,0.68],[0,0],[0.9,0],[0,0],[0,0],[0,-1.27],[3.9,-3.6],[1.35,0.22],[0,0],[0,0],[-0.38,0.75],[-1.58,0.3],[-0.6,-0.38],[0,0],[-0.98,-0.75],[-0.07,-0.15],[0,0],[-0.75,-0.38],[-1.2,-1.05]],"o":[[0.23,0.23],[1.12,2.02],[0.38,0.9],[-0.68,0],[0,0],[0.52,1.88],[0.15,0.98],[-0.45,-0.07],[0,0],[0.3,0.9],[0,0],[0,0],[3.45,-1.27],[0,1.95],[-2.55,2.4],[0,0],[0,0],[0.9,-1.8],[1.88,-3.6],[0.6,-0.15],[0,0],[0.82,-0.98],[0.07,0.07],[0,0],[0.68,-0.6],[0.98,-1.27],[0,0]],"v":[[84.68,107.81],[85.2,108.48],[87.15,112.16],[86.47,114.11],[82.2,110.29],[82.12,110.06],[82.95,113.43],[82.05,115.23],[80.85,114.11],[80.85,114.04],[80.25,115.98],[80.02,115.98],[79.88,116.21],[85.12,116.21],[75.98,122.06],[70.12,125.36],[68.62,122.36],[66.38,118.69],[68.25,114.79],[73.35,108.94],[75.15,109.39],[75.08,109.24],[78.3,108.86],[78.61,109.16],[78.3,108.49],[80.7,108.11],[84.68,107.81]],"c":true}}},{"ty":"fl","o":{"k":30},"c":{"k":[0.13,0.44,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[3.15,-0.6],[3.52,2.93],[0,0],[0,0],[-2.85,0.52],[-1.05,3.6],[0,0]],"o":[[0,0],[-1.12,4.12],[-3.07,0.6],[0,0],[0,0],[3.45,3],[2.7,-0.52],[0,0],[0,0]],"v":[[59.15,95.62],[60.12,95.84],[53.75,102.97],[43.85,99.37],[43.55,99.14],[44.15,98.39],[53.53,102.07],[59.08,95.92],[59.15,95.62]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.15,-0.22],[-0.3,0],[-0.07,0.22],[0,0],[-0.22,-0.07],[0.07,-0.22],[0.68,-0.08],[0.45,0.45],[-0.22,0.23]],"o":[[0.23,-0.15],[0.23,0.23],[0.23,-0.07],[0,0],[0.07,-0.3],[0.3,0.07],[-0.07,0.68],[-0.52,0.07],[-0.15,-0.23],[0,0]],"v":[[53.32,88.24],[54,88.32],[54.82,88.69],[55.35,88.24],[55.35,88.17],[55.87,87.79],[56.25,88.32],[54.89,89.67],[53.25,88.99],[53.32,88.24]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.07,-0.23],[0.23,-0.07],[2.47,-3.9],[-2.32,-6.08],[-3,-1.65],[-9.45,4.95],[0,0],[-0.15,0.08],[0,0],[-0.15,0.08],[0,0],[0,0],[0,0],[-0.3,0.15],[0,0],[-0.15,0.15],[0,0],[0,0],[0,0],[0.15,0.15],[0,0],[0,0],[-0.22,0.23],[-0.15,-0.22],[0,0],[0,0],[0,0],[-0.07,-0.23],[0,0],[0,0],[0.22,-0.15],[0,0],[0,0],[0,0],[0,0],[0.15,-0.15],[0,0],[0,0],[0.38,-0.23],[0,0],[0.07,-0.08],[0,0],[0,0],[5.7,3.15],[1.95,5.02],[-3.97,6.38],[-6.53,3.08]],"o":[[0.3,-0.15],[0.07,0.23],[-6.38,3.07],[-3.82,6.07],[1.88,4.8],[5.25,2.85],[0,0],[0.15,-0.07],[0,0],[0.15,-0.07],[0,0],[0,0],[0,0],[0.3,-0.15],[0,0],[0.15,-0.07],[0,0],[0,0],[0,0],[-0.15,0.07],[0,0],[0,0],[-0.15,-0.23],[0.23,-0.15],[0,0],[0,0],[0,0],[0.23,-0.07],[0,0],[0,0],[0.15,0.23],[0,0],[0,0],[0,0],[0,0],[-0.15,0.07],[0,0],[0,0],[-0.38,0.23],[0,0],[-0.15,0.07],[0,0],[0,0],[-10.12,5.4],[-3.38,-1.88],[-2.48,-6.38],[2.62,-4.12],[0,0]],"v":[[45.88,96.74],[46.55,96.97],[46.32,97.64],[33.05,108],[31.18,126.6],[39.57,137.25],[61.62,134.17],[62.38,133.8],[62.75,133.57],[63.5,133.12],[63.88,132.89],[64.62,132.45],[66.27,131.55],[67.1,131.02],[67.92,130.5],[69.57,129.45],[70.02,129.15],[70.92,128.55],[65.37,118.05],[50.37,122.1],[49.84,121.95],[49.77,121.88],[47.52,118.88],[47.59,118.13],[48.27,118.2],[48.34,118.28],[50.37,120.98],[65.37,116.93],[65.89,117.15],[65.96,117.23],[71.96,128.48],[71.82,129.15],[71.44,129.45],[70.54,130.05],[69.72,130.66],[68.89,131.18],[68.45,131.48],[67.7,132],[66.87,132.53],[65.67,133.28],[64.85,133.73],[64.47,133.95],[63.65,134.4],[62.9,134.85],[39.2,138.3],[30.2,126.98],[32.15,107.48],[45.88,96.75]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-4.65,-2.17],[-1.73,-4.12],[0.3,-0.07],[0.07,0.3],[4.5,2.1],[3.98,-0.38],[0.08,0.3],[-0.3,0.07]],"o":[[4.2,-0.38],[4.65,2.25],[0.07,0.3],[-0.3,0.07],[-1.65,-3.9],[-4.5,-2.18],[-0.3,0],[0.07,-0.38],[0,0]],"v":[[56,95.54],[69.2,98.31],[78.8,107.91],[78.5,108.59],[77.82,108.29],[68.68,99.29],[56,96.66],[55.4,96.21],[56,95.54]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.07,-0.23],[0,0],[0,0],[0.3,0],[0.07,0.23],[0,0],[0,0],[-0.3,0.07]],"o":[[0.23,0],[0,0],[0,0],[0,0.3],[-0.23,0],[0,0],[0,0],[-0.07,-0.23],[0,0]],"v":[[67.1,107.62],[67.62,107.99],[67.62,108.07],[68.38,115.57],[67.93,116.09],[67.4,115.71],[67.4,115.64],[66.65,108.14],[67.1,107.62]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[1.2,1.12],[1.12,-1.2],[-1.2,-1.12],[-1.12,1.2]],"o":[[1.12,-1.2],[-1.2,-1.12],[-1.12,1.2],[1.2,1.12],[0,0]],"v":[[49.43,80.82],[47.1,74.52],[42.83,74.66],[42.98,78.94],[49.43,80.81]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,1.04],[1.04,0],[0,-1.04],[-1.04,0]],"o":[[1.04,0],[0,-1.04],[-1.04,0],[0,1.04],[0,0]],"v":[[47.25,90.49],[49.12,88.62],[47.25,86.74],[45.38,88.62],[47.25,90.49]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[2.1,-0.9],[0.45,-3.07]],"o":[[0,0],[-2.4,-1.88],[-2.1,0.9],[0,0]],"v":[[46.88,86.74],[57.38,82.24],[50.62,80.74],[46.88,86.74]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-3.6],[-3.6,0],[0,3.6],[3.6,0]],"o":[[-3.6,0],[0,3.6],[3.6,0],[0,-3.6],[0,0]],"v":[[52.88,79.46],[46.35,85.99],[52.88,92.51],[59.4,85.99],[52.88,79.46]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-3],[3,0],[0,3],[-3,0]],"o":[[3,0],[0,3],[-3,0],[0,-3],[0,0]],"v":[[52.88,80.52],[58.35,85.99],[52.88,91.47],[47.4,85.99],[52.88,80.52]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.8,0.3],[0,0],[2.7,0],[2,2],[0,0],[0,0],[-3,0]],"o":[[1,0],[0,0],[-1.3,2.7],[-2.7,0],[0,0],[0,0],[1.4,2.4],[0,0]],"v":[[70.5,122.66],[73.2,122.16],[74.5,128.66],[68.5,132.66],[61.5,129.66],[63.5,118.66],[63.6,118.66],[70.5,122.66]],"c":true}}},{"ty":"st","lc":1,"lj":1,"ml":4,"o":{"k":100},"w":{"k":1.4},"c":{"k":[0.4,0.62,0.96,1]},"hd":false},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[75,75]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,-3.3],[2.33,-0.82],[0,0],[2.02,0],[1.5,1.5],[0,0],[0,0],[0,1.12],[-3.3,0]],"o":[[3.3,0],[0,2.62],[0,0],[-0.98,2.02],[-2.02,0],[0,0],[0,0],[-0.52,-0.9],[0,-3.3],[0,0]],"v":[[52.88,79.99],[58.88,85.99],[54.9,91.62],[55.88,96.49],[51.38,99.49],[46.12,97.24],[47.62,88.99],[47.7,88.99],[46.88,85.99],[52.88,79.99]],"c":true}}},{"ty":"fl","o":{"k":30},"c":{"k":[0.13,0.44,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,1.05],[1.05,0],[0,-1.05],[-1.05,0]],"o":[[1.05,0],[0,-1.05],[-1.05,0],[0,1.05],[0,0]],"v":[[59.25,87.49],[61.12,85.62],[59.25,83.74],[59.25,85.69],[59.25,87.49]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.3,-0.08],[0,0],[-0.08,0.23],[0,0],[0,0],[0.23,0.07],[0,0],[0,0],[0,0.15],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0.07],[0,0],[0.23,0.45],[0.6,-0.23],[0.53,-0.6],[0,0],[0,0],[0,0],[0.07,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[1.2,0.53],[0,-0.38]],"o":[[0,0],[0,0.3],[0,0],[0.3,0],[0,0],[0,0],[0,-0.23],[0,0],[0,0],[0.15,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.15,-0.23],[0,0],[0,-0.82],[-0.3,-0.6],[-0.45,0.15],[0,0],[0,0],[0,0],[-0.07,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.27,0.9],[-0.38,-0.23],[0,0]],"v":[[141,144.11],[139.65,154.69],[140.1,155.29],[151.95,156.79],[152.55,156.41],[153.91,151.02],[153.91,150.94],[153.61,150.42],[151.28,149.22],[154.28,148.09],[154.58,147.72],[154.88,146.52],[155.11,145.32],[155.34,144.2],[155.48,143.45],[155.78,142.09],[155.93,141.12],[156.15,139.31],[156.38,137.74],[156.38,137.52],[156.45,137.07],[156.45,135.19],[156.6,134.89],[156.6,134.52],[156.22,132.57],[154.8,132.04],[153.37,133.17],[152.92,133.62],[152.69,133.92],[152.09,134.52],[151.94,134.67],[151.49,135.2],[151.27,135.72],[150.74,136.39],[149.99,137.37],[148.49,139.39],[147.74,140.37],[147.22,141.05],[146.77,141.65],[146.47,142.02],[146.17,142.48],[145.5,143.14],[145.5,143.22],[141.75,143.74],[141,144.12]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.35,0.9],[0,0],[0,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.23,0.15],[0,0],[0,0],[0,0],[-0.08,-0.38],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.38,-0.15],[0,0],[0,0],[0,0],[0,0]],"o":[[1.43,0.38],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,-0.07],[0.38,-0.45],[0,0],[0,0],[0,0],[0.07,0.23],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.38,0.23],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[141.98,144.94],[146.11,144.11],[146.4,143.96],[146.48,143.89],[147,143.37],[147.45,142.77],[147.75,142.39],[148.2,141.87],[148.8,141.04],[149.7,139.84],[150.98,138.04],[151.5,137.29],[152.02,136.62],[152.62,135.87],[152.85,135.42],[153.15,135.12],[153.83,134.21],[154.06,133.99],[154.13,133.91],[155.11,133.09],[155.26,133.02],[155.33,133.02],[155.33,133.16],[155.56,133.99],[155.55,136.77],[155.33,138.11],[155.33,138.34],[155.18,139.39],[155.11,139.84],[155.03,140.44],[154.88,141.34],[154.73,142.31],[154.51,143.29],[154.36,144.04],[154.13,145.16],[153.98,145.91],[153.68,147.19],[149.86,148.69],[149.79,148.69],[149.79,149.59],[152.86,151.09],[151.66,155.66],[140.79,154.31],[141.98,144.93]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0.83,1.65],[2.18,-1.5],[1.42,0.68],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[1.88,-8.18],[-1.12,-2.48],[-1.43,1.05],[0,0],[0,0]],"v":[[140.18,154.77],[152.03,156.27],[153.38,150.87],[149.93,149.14],[153.98,147.57],[155.63,132.79],[145.65,143.59],[141.38,144.12],[140.18,154.77]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[-0.15,-0.23],[0,0],[-0.23,0.07],[0,0],[0,0],[0.07,0.22],[0,0],[0,0],[-0.22,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.08,0.07],[0,0],[-0.08,0.07],[0,0],[0,0],[0,0],[0,0],[-0.22,0.45],[0.52,0.38],[0.75,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0.3,1.27],[0.3,-0.15]],"o":[[0,0],[-0.23,0.15],[0,0],[0.15,0.23],[0,0],[0,0],[0.15,-0.15],[0,0],[0,0],[0.15,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.07,-0.07],[0,0],[0.07,-0.07],[0,0],[0,0],[0.15,0],[0,0],[0.68,-0.52],[0.3,-0.6],[-0.38,-0.23],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.5,-0.45],[0,-0.6],[0,0]],"v":[[120.3,145.54],[111.07,151.02],[110.93,151.69],[117.07,161.96],[117.75,162.19],[122.85,159.94],[122.93,159.87],[123.15,159.34],[122.63,156.79],[125.33,158.44],[125.85,158.44],[126.98,157.92],[129.08,156.87],[129.75,156.57],[131.86,155.52],[133.43,154.62],[134.77,153.71],[135,153.57],[135.38,153.34],[135.6,153.19],[136.35,152.74],[136.95,152.29],[137.18,152.21],[137.48,151.98],[138.75,150.48],[138.3,148.98],[136.58,148.54],[132.45,148.54],[131.18,148.61],[128.63,148.68],[127.43,148.76],[123.68,148.76],[120.98,146.13],[120.3,145.53]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.58,-0.52],[0,0],[0,0],[0,0],[0,0],[-0.22,-0.15],[0,0],[0,0],[0,0],[0.22,-0.23],[0,0],[0,0],[0,0],[0,0],[0.07,-0.07],[0,0],[0,0],[0.08,-0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.07,-0.45],[0,0],[0,0],[0,0],[0,0]],"o":[[0.52,1.35],[0,0],[0,0],[0,0],[0,0],[0.6,0.07],[0,0],[0,0],[0,0],[-0.15,0.23],[0,0],[0,0],[0,0],[0,0],[-0.07,0],[0,0],[0,0],[-0.07,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.38,-0.15],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[120.23,146.81],[123.45,149.59],[127.43,149.59],[128.93,149.52],[131.18,149.44],[136.35,149.44],[137.62,149.74],[137.77,149.97],[137.85,149.97],[137.77,150.04],[137.25,150.72],[137.1,150.95],[136.57,151.47],[135.97,151.93],[135.6,152.07],[135.45,152.22],[134.32,152.9],[133.88,153.13],[133.65,153.28],[133.2,153.5],[132.75,153.8],[131.7,154.41],[130.88,154.86],[129.23,155.68],[128.55,155.98],[127.58,156.5],[126.9,156.8],[125.7,157.41],[122.18,155.3],[122.11,155.3],[121.36,155.91],[122.03,159.21],[117.68,161.08],[112.13,151.63],[120.23,146.83]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[-0.82,1.58],[2.55,0.75],[0.38,1.5],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[7.65,-3.52],[1.2,-2.48],[-1.73,-0.52],[0,0],[0,0]],"v":[[111.38,151.46],[117.52,161.74],[122.62,159.49],[121.88,155.74],[125.62,157.99],[138.3,150.26],[123.6,148.99],[120.53,145.99],[111.38,151.46]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-5.25,-6.97],[0,0],[-0.6,-0.9],[0,0],[-0.15,-0.23],[0,0],[-0.08,-0.07],[-2.85,-1.88],[-0.3,-0.45],[1.5,-1.05],[0,0],[0,0],[1.35,1.57],[0,0],[0,0],[0,0],[11.77,-2.1],[0,0],[2.03,15.3],[-0.3,0.08],[-0.08,-0.3],[-11.7,1.95],[-5.4,13.88],[-0.22,-0.22],[0,0],[0,0],[-1.35,0.75],[0,0],[0,0],[0.68,1.12],[0.3,0.15],[1.27,2.1],[0,0],[0.08,0.15],[0,0],[0.38,0.6],[0,0],[6.67,0.53],[6.75,-3.75],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.15,0.3],[-0.3,0.15],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-6.15,-0.45]],"o":[[6.6,0.52],[0,0],[0.6,0.75],[0,0],[0.15,0.23],[0,0],[0.07,0.15],[1.2,1.95],[0.45,0.3],[0.98,1.57],[0,0],[0,0],[-1.8,1.12],[0,0],[0,0],[0,0],[-5.55,13.5],[0,0],[-12.3,1.95],[-0.07,-0.3],[0.3,-0.07],[1.95,14.7],[11.77,-1.95],[0.15,-0.38],[0,0],[0,0],[0.98,1.2],[0,0],[0,0],[1.2,-0.75],[-0.23,-0.3],[-3,-1.88],[0,0],[-0.07,-0.15],[0,0],[-0.38,-0.6],[0,0],[-5.4,-7.65],[-5.77,-0.45],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.23,0.15],[-0.15,-0.3],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[6.9,-3.9],[0,0]],"v":[[97.2,115.47],[114.38,126.42],[114.82,127.09],[116.55,129.57],[117,130.32],[117.45,131.07],[117.9,131.89],[118.12,132.27],[124.12,137.97],[125.25,139.09],[124.27,143.82],[124.12,143.89],[111.9,151.47],[106.42,150.64],[106.27,150.5],[94.65,135.8],[94.65,135.87],[68.7,159.27],[68.32,159.34],[46.72,139.32],[47.17,138.72],[47.77,139.17],[68.17,158.22],[93.97,134.52],[94.8,134.29],[94.87,134.37],[107.02,149.74],[111.07,150.57],[111.22,150.49],[123.52,142.92],[124.34,139.54],[123.59,138.79],[117.22,132.79],[116.77,131.97],[116.54,131.59],[116.09,130.84],[114.89,129.04],[114.45,128.37],[97.05,116.52],[79.5,121.39],[78.75,121.84],[77.62,122.44],[75.52,123.71],[73.57,124.84],[72.59,125.36],[71.7,125.89],[71.09,126.19],[70.34,125.96],[70.57,125.21],[71.7,124.54],[72.59,124.01],[76.79,121.54],[77.77,121.01],[78.37,120.71],[78.97,120.48],[97.2,115.46]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[-2.85,-1.8],[-0.15,-0.38],[1.2,-0.75],[0,0],[1.05,1.27],[0,0],[0.23,-0.15],[0,-0.07],[7.72,-3.68],[0,0],[0,0],[0,0],[-0.15,0.07],[0,0],[0,0],[-0.07,0.07],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-11.92,-0.9],[-0.3,2.25],[0,0],[0,0],[2.1,0.38],[0,0],[0,0]],"o":[[0,0],[0,0],[1.27,1.95],[0.3,0.23],[0.75,1.2],[0,0],[-1.43,0.9],[0,0],[-0.15,-0.23],[-0.07,0],[-4.12,10.5],[0,0],[0,0],[0,0],[0.15,0],[0,0],[0,0],[0.15,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[11.7,-0.15],[2.25,0.15],[0,0],[0,0],[0.15,-2.18],[0,0],[0,0],[0,0]],"v":[[118.04,132.36],[116.99,132.29],[117.52,133.11],[123.66,138.73],[124.41,139.56],[123.59,143.01],[111.36,150.58],[107.09,149.83],[94.86,134.46],[94.19,134.38],[94.04,134.53],[76.27,155.76],[73.12,157.26],[76.87,156.66],[78.37,156.51],[78.74,156.43],[79.49,156.36],[80.32,156.29],[80.69,156.21],[81.52,156.14],[84.21,155.91],[87.14,155.69],[88.12,155.54],[89.17,155.47],[90.74,155.39],[92.39,155.32],[93.52,155.25],[100.79,155.25],[136.19,156.45],[140.76,152.7],[142.19,141],[142.19,140.85],[138.74,136.35],[118.19,132.37],[118.04,132.37]],"c":true}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0],[0,0],[0.15,-1.65],[0,0],[0,0],[1.8,0.15],[11.7,-0.08],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0.15,-0.07],[0,0],[0.3,0],[0,0],[0.15,-0.07],[0,0],[0,0],[0,0],[-3.75,9],[0,0],[0,0],[-1.8,1.12],[0,0],[1.05,1.65],[0.38,0.3],[1.2,1.43]],"o":[[0,0],[0,0],[1.65,0.3],[0,0],[0,0],[-0.23,1.73],[-11.77,-0.98],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[-0.15,0],[0,0],[-0.3,0],[0,0],[-0.15,0],[0,0],[0,0],[0,0],[6.45,-3.9],[0,0],[0,0],[1.35,1.65],[0,0],[1.65,-0.98],[-0.3,-0.45],[-2.18,-1.2],[0,0]],"v":[[119.24,133.79],[119.02,133.56],[138.52,137.23],[141.14,140.68],[141.14,140.83],[139.71,152.53],[136.19,155.38],[100.87,154.11],[98.09,154.11],[96.07,154.18],[94.12,154.26],[92.25,154.33],[88.65,154.55],[86.4,154.7],[85.35,154.78],[84.22,154.78],[83.7,154.85],[82.72,154.93],[81.75,155],[80.77,155.07],[80.32,155.15],[79.42,155.22],[79.2,155.22],[79.34,155.15],[94.64,135.8],[94.72,135.57],[106.34,150.27],[111.89,151.25],[124.2,143.67],[125.32,138.87],[124.27,137.75],[119.25,133.77]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[222.44,69.79],[221.25,80.99]],"c":false}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[219.94,93.53],[217.99,111.94]],"c":false}}},{"ty":"sh","ks":{"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[177.6,38.4],[191.52,39.86]],"c":false}}},{"ty":"st","lc":2,"lj":2,"ml":4,"o":{"k":100},"w":{"k":1.3},"c":{"k":[0.4,0.62,0.96,1]},"hd":false},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[75,75]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-1.04,-1.28],[0.18,-1.64],[0,0],[1.29,-1.04],[1.64,0.18],[0,0],[0.39,2.76],[-0.3,0.04],[-2.46,-0.26],[0,0],[-0.3,2.83],[0,0],[0.88,1.09],[1.39,0.14],[0,0],[0.3,-2.84],[0,0],[0.3,-0.04],[0,0],[0,0],[-1.29,1.04],[-1.64,-0.18],[0,0]],"o":[[1.64,0.17],[1.04,1.29],[0,0],[-0.17,1.64],[-1.28,1.04],[0,0],[-2.91,-0.3],[0.3,-0.04],[0.35,2.38],[0,0],[2.91,0.3],[0,0],[0.15,-1.39],[-0.88,-1.08],[0,0],[-2.91,-0.3],[0,0],[-0.3,-0.03],[0,0],[0,0],[0.17,-1.64],[1.29,-1.04],[0,0],[0,0]],"v":[[162.17,28.54],[166.36,30.8],[167.71,35.38],[154.64,159.64],[152.38,163.84],[147.8,165.18],[96.56,159.8],[91.02,154.39],[92.01,154.34],[96.66,158.83],[147.91,164.21],[153.68,159.54],[166.74,35.28],[165.61,31.41],[162.07,29.51],[110.82,24.12],[105.05,28.79],[95.95,115.39],[94.97,115.44],[104.09,28.69],[104.08,28.69],[106.35,24.5],[110.93,23.15],[162.17,28.54]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.4,0.62,0.96,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[0.3,-2.84],[0,0],[2.84,0.3],[0,0],[-10.92,-0.85],[-0.29,2],[0,0],[0,0],[1.92,0.35],[0,0],[0,0],[0.14,0.09],[8.54,0.59],[0,0],[0,0],[-2.84,-0.3],[0,0]],"o":[[2.84,0.3],[0,0],[-0.3,2.84],[0,0],[10.96,-0.06],[2.02,0.14],[0,0],[0,0],[0.12,-1.87],[0,0],[0,0],[-0.07,-0.08],[-6.04,-9.98],[0,0],[0,0],[0.3,-2.84],[0,0],[0,0]],"v":[[159.85,34.1],[164.45,39.79],[152.45,153.98],[146.77,158.59],[104.02,154.1],[136.86,155.29],[140.89,152.02],[142.27,140.32],[142.29,140.17],[139.23,136.23],[118.67,132.41],[118.52,132.39],[118.26,132.07],[97.67,115.57],[97.74,115.58],[106.28,33.68],[111.96,29.07],[159.85,34.1]],"c":true}}},{"ty":"fl","o":{"k":30},"c":{"k":[0.13,0.44,0.91,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"gr","hd":false,"it":[{"ty":"sh","ks":{"k":{"i":[[0,0],[-0.07,0.67],[0.6,0.07],[0.06,-0.59],[-0.6,-0.07]],"o":[[0.67,0.07],[0.07,-0.67],[-0.6,-0.06],[-0.06,0.6],[0,0]],"v":[[129.61,29.71],[130.85,28.71],[129.85,27.48],[128.61,28.48],[129.61,29.71]],"c":true}}},{"ty":"fl","o":{"k":100},"c":{"k":[0.54,0.71,0.97,1]}},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]},{"ty":"tr","o":{"k":100},"r":{"k":0},"p":{"k":[0,0]},"a":{"k":[0,0]},"s":{"k":[100,100]},"sk":{"k":0},"sa":{"k":0},"hd":false}]}]}],"meta":{"g":"LF SVG to Lottie"}} \ No newline at end of file
diff --git a/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.png b/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.png deleted file mode 100644 index 2fcbee5..0000000 --- a/ash/public/cpp/resources/unscaled_resources/phone_hub_onboarding_image.png +++ /dev/null Binary files differ
diff --git a/ash/public/cpp/test/test_desks_templates_delegate.cc b/ash/public/cpp/test/test_desks_templates_delegate.cc index 83c29414..b8a8979 100644 --- a/ash/public/cpp/test/test_desks_templates_delegate.cc +++ b/ash/public/cpp/test/test_desks_templates_delegate.cc
@@ -35,8 +35,7 @@ void TestDesksTemplatesDelegate::GetIconForAppId( const std::string& app_id, int desired_icon_size, - base::OnceCallback<void(apps::mojom::IconValuePtr icon_value)> callback) - const {} + base::OnceCallback<void(apps::IconValuePtr icon_value)> callback) const {} void TestDesksTemplatesDelegate::LaunchAppsFromTemplate( std::unique_ptr<DeskTemplate> desk_template) {}
diff --git a/ash/public/cpp/test/test_desks_templates_delegate.h b/ash/public/cpp/test/test_desks_templates_delegate.h index 2396ce42..ee5bade 100644 --- a/ash/public/cpp/test/test_desks_templates_delegate.h +++ b/ash/public/cpp/test/test_desks_templates_delegate.h
@@ -44,11 +44,10 @@ int desired_icon_size, favicon_base::FaviconRawBitmapCallback callback, base::CancelableTaskTracker* tracker) const override; - void GetIconForAppId( - const std::string& app_id, - int desired_icon_size, - base::OnceCallback<void(apps::mojom::IconValuePtr icon_value)> callback) - const override; + void GetIconForAppId(const std::string& app_id, + int desired_icon_size, + base::OnceCallback<void(apps::IconValuePtr icon_value)> + callback) const override; void LaunchAppsFromTemplate( std::unique_ptr<DeskTemplate> desk_template) override; bool IsWindowSupportedForDeskTemplate(aura::Window* window) const override;
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn index 0cf78c1..ad633449 100644 --- a/ash/resources/vector_icons/BUILD.gn +++ b/ash/resources/vector_icons/BUILD.gn
@@ -199,6 +199,7 @@ "projector_selfie_cam_off.icon", "projector_selfie_cam_on.icon", "remove_outline.icon", + "reorder.icon", "resume.icon", "save_desk_as_template.icon", "select_to_speak_next_paragraph.icon",
diff --git a/ash/resources/vector_icons/reorder.icon b/ash/resources/vector_icons/reorder.icon new file mode 100644 index 0000000..c5d29180 --- /dev/null +++ b/ash/resources/vector_icons/reorder.icon
@@ -0,0 +1,27 @@ +// 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. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 14, 14.71f, +V_LINE_TO, 9, +R_H_LINE_TO, -2, +R_V_LINE_TO, 5.63f, +R_LINE_TO, -1.87f, -1.87f, +LINE_TO, 9, 13.91f, +LINE_TO, 13, 18, +R_LINE_TO, 4, -4.09f, +R_LINE_TO, -1.13f, -1.15f, +LINE_TO, 14, 14.71f, +CLOSE, +MOVE_TO, 11, 6.09f, +LINE_TO, 7, 2, +LINE_TO, 3, 6.09f, +R_LINE_TO, 1.13f, 1.15f, +LINE_TO, 6, 5.29f, +V_LINE_TO, 11, +R_H_LINE_TO, 2, +V_LINE_TO, 5.37f, +R_LINE_TO, 1.87f, 1.87f, +LINE_TO, 11, 6.09f, +CLOSE
diff --git a/ash/search_box/search_box_view_base.cc b/ash/search_box/search_box_view_base.cc index 7dc4f47..a37676fa 100644 --- a/ash/search_box/search_box_view_base.cc +++ b/ash/search_box/search_box_view_base.cc
@@ -41,6 +41,10 @@ namespace { +// The duration for the animation which changes the search icon. +constexpr base::TimeDelta kSearchIconAnimationDuration = + base::Milliseconds(250); + constexpr int kInnerPadding = 16; // Preferred width of search box. @@ -251,6 +255,73 @@ SearchBoxViewBase* const search_box_view_; }; +// Used to animate the transition between icon images. When a new icon is set, +// this view will temporarily store the layer of the previous icon and animate +// its opacity to fade out, while keeping the correct bounds for the fading out +// layer. At the same time the new icon will fade in. +class SearchIconImageView : public views::ImageView { + public: + SearchIconImageView() = default; + + SearchIconImageView(const SearchIconImageView&) = delete; + SearchIconImageView& operator=(const SearchIconImageView&) = delete; + + ~SearchIconImageView() override = default; + + // views::View: + void OnBoundsChanged(const gfx::Rect& previous_bounds) override { + if (old_icon_layer_) + old_icon_layer_->SetBounds(layer()->bounds()); + + views::ImageView::OnBoundsChanged(previous_bounds); + } + + void SetSearchIconImage(gfx::ImageSkia image) { + if (GetImage().isNull() || !animation_enabled_) { + SetImage(image); + return; + } + + if (old_icon_layer_ && old_icon_layer_->GetAnimator()->is_animating()) + old_icon_layer_->GetAnimator()->StopAnimating(); + + old_icon_layer_ = RecreateLayer(); + SetImage(image); + + // Animate the old layer to fade out. + views::AnimationBuilder() + .SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET) + .OnEnded(base::BindOnce(&SearchIconImageView::ResetOldIconLayer, + weak_factory_.GetWeakPtr())) + .OnAborted(base::BindOnce(&SearchIconImageView::ResetOldIconLayer, + weak_factory_.GetWeakPtr())) + .Once() + .SetDuration(kSearchIconAnimationDuration) + .SetOpacity(old_icon_layer_.get(), 0.0f, gfx::Tween::EASE_OUT_3); + + // Animate the newly set icon image to fade in. + layer()->SetOpacity(0.0f); + views::AnimationBuilder() + .SetPreemptionStrategy( + ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET) + .Once() + .SetDuration(kSearchIconAnimationDuration) + .SetOpacity(layer(), 1.0f, gfx::Tween::EASE_OUT_3); + } + + void ResetOldIconLayer() { old_icon_layer_.reset(); } + + void set_animation_enabled(bool enabled) { animation_enabled_ = enabled; } + + private: + std::unique_ptr<ui::Layer> old_icon_layer_; + + bool animation_enabled_ = false; + + base::WeakPtrFactory<SearchIconImageView> weak_factory_{this}; +}; + SearchBoxViewBase::SearchBoxViewBase(SearchBoxViewDelegate* delegate) : delegate_(delegate), content_container_(new views::View), @@ -285,7 +356,9 @@ base::Unretained(delegate_)))); search_icon_ = - content_container_->AddChildView(std::make_unique<views::ImageView>()); + content_container_->AddChildView(std::make_unique<SearchIconImageView>()); + search_icon_->SetPaintToLayer(); + search_icon_->layer()->SetFillsBoundsOpaquely(false); content_container_->AddChildView(search_box_); box_layout_->SetFlexForView(search_box_, 1); @@ -315,6 +388,7 @@ void SearchBoxViewBase::Init(const InitParams& params) { show_close_button_when_active_ = params.show_close_button_when_active; + search_icon_->set_animation_enabled(params.animate_changing_search_icon); SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); layer()->SetMasksToBounds(true); @@ -353,6 +427,10 @@ return static_cast<views::ImageButton*>(close_button_); } +views::ImageView* SearchBoxViewBase::search_icon() { + return search_icon_; +} + void SearchBoxViewBase::ShowBackOrGoogleIcon(bool show_back_button) { search_icon_->SetVisible(!show_back_button); back_button_->SetVisible(show_back_button); @@ -562,7 +640,7 @@ } void SearchBoxViewBase::SetSearchIconImage(gfx::ImageSkia image) { - search_icon_->SetImage(image); + search_icon_->SetSearchIconImage(image); } void SearchBoxViewBase::SetShowAssistantButton(bool show) {
diff --git a/ash/search_box/search_box_view_base.h b/ash/search_box/search_box_view_base.h index 1abace55..87becba 100644 --- a/ash/search_box/search_box_view_base.h +++ b/ash/search_box/search_box_view_base.h
@@ -30,6 +30,7 @@ class SearchBoxViewDelegate; class SearchBoxImageButton; +class SearchIconImageView; // These are used in histograms, do not remove/renumber entries. If you're // adding to this enum with the intention that it will be logged, update the @@ -61,6 +62,9 @@ // Whether to create a rounded-rect background. bool create_background = true; + + // Whether to animate the transition when the search icon is changed. + bool animate_changing_search_icon = false; }; virtual void Init(const InitParams& params); @@ -74,6 +78,7 @@ views::ImageButton* assistant_button(); views::ImageButton* back_button(); views::ImageButton* close_button(); + views::ImageView* search_icon(); views::Textfield* search_box() { return search_box_; } // Swaps the google icon with the back button. @@ -99,9 +104,6 @@ // deactivating the searchbox. void NotifyGestureEvent(); - // Used only in the tests to get the current search icon. - views::ImageView* get_search_icon_for_test() { return search_icon_; } - // Whether the search box is active. bool is_search_box_active() const { return is_search_box_active_; } @@ -146,7 +148,6 @@ SearchBoxViewDelegate* delegate() { return delegate_; } views::BoxLayout* box_layout() { return box_layout_; } - views::ImageView* search_icon() { return search_icon_; } void SetSearchBoxBackgroundCornerRadius(int corner_radius); @@ -194,7 +195,7 @@ // Owned by views hierarchy. views::View* content_container_; - views::ImageView* search_icon_ = nullptr; + SearchIconImageView* search_icon_ = nullptr; SearchBoxImageButton* assistant_button_ = nullptr; SearchBoxImageButton* back_button_ = nullptr; SearchBoxImageButton* close_button_ = nullptr;
diff --git a/ash/shortcut_viewer/strings/shortcut_viewer_strings_hy.xtb b/ash/shortcut_viewer/strings/shortcut_viewer_strings_hy.xtb index 1f1e9e0..2f81a52 100644 --- a/ash/shortcut_viewer/strings/shortcut_viewer_strings_hy.xtb +++ b/ash/shortcut_viewer/strings/shortcut_viewer_strings_hy.xtb
@@ -89,6 +89,7 @@ <translation id="379295446891231126"><ph name="CTRL" /><ph name="SEPARATOR" /> 1-ից 8</translation> <translation id="3837047332182291558">Ավելացնել ստեղնաշարի պայծառությունը (միայն լուսավորվող ստեղնաշարերի համար)</translation> <translation id="3949671998904569433">ստորակետ</translation> +<translation id="3976707995992061296">Նշանակել ակտիվ պատուհան բոլոր աշխատասեղանների համար կամ չեղարկել նշանակումը</translation> <translation id="3976863468609830880">Սեղմել դարակի վերջին պատկերակին</translation> <translation id="3994783594793697310">Վերակայել էկրանի մասշտաբը</translation> <translation id="4026843240379844265">Տեղափոխել ակտիվ պատուհանը էկրանների միջև</translation> @@ -149,6 +150,7 @@ <translation id="6340769215862220182">Մեծացնել էկրանի մասշտաբը</translation> <translation id="634687982629734605">Փոխեփոխ նշել հետևյալ տարրերը՝ կարգավիճակի գոտին (որտեղ ցուցադրվում է պրոֆիլի նկարը), գործարկիչի հասցեագոտին, էջանիշների գոտին (եթե տեսանելի է), բացված կայքէջը, ներբեռնումների գոտին (եթե տեսանելի է)։ Եթե արտացոլվում է երկխոսության ֆոկուսավորվող պատուհան, ֆոկուսը տեղափոխեք դրա վրա։</translation> <translation id="6359811074279051077"><ph name="MODIFIER" /><ph name="SEPARATOR" /><ph name="KEY" /></translation> +<translation id="6372960562287888784">Ակտիվացնել 1–8-րդ աշխատասեղանները։</translation> <translation id="6395172954772765143">Նշել տեքստը մինչև տողի վերջը</translation> <translation id="6425378783626925378">Սեղմել 1-8 պատկերակները դարակում</translation> <translation id="6435207348963613811">Նշել նախորդ տարրը դարակում</translation> @@ -204,6 +206,7 @@ <translation id="8644639153978066712">Ցուցադրել թաքցված ֆայլերը «Ֆայլեր» հավելվածում</translation> <translation id="8717459106217102612">Ընտրել նախորդ բառը կամ տառը</translation> <translation id="8727232706774971183">Դիտել ծանուցումները</translation> +<translation id="8855548128280178372"><ph name="SHIFT" /><ph name="SEPARATOR1" /><ph name="SEARCH" /><ph name="SEPARATOR2" /> 1-ից 8</translation> <translation id="8855885154700222542">Լիաէկրան ռեժիմի ստեղն</translation> <translation id="8881584919399569791">Ակտիվ պատուհանը տեղափոխել ձախ էկրան</translation> <translation id="88986195241502842">Էջը վար</translation>
diff --git a/ash/shortcut_viewer/strings/shortcut_viewer_strings_it.xtb b/ash/shortcut_viewer/strings/shortcut_viewer_strings_it.xtb index c7be0dd..04e6ca8 100644 --- a/ash/shortcut_viewer/strings/shortcut_viewer_strings_it.xtb +++ b/ash/shortcut_viewer/strings/shortcut_viewer_strings_it.xtb
@@ -89,6 +89,7 @@ <translation id="379295446891231126">Da <ph name="CTRL" /><ph name="SEPARATOR" /> 1 a 8</translation> <translation id="3837047332182291558">Aumenta la luminosità della tastiera (soltanto per tastiere retroilluminate)</translation> <translation id="3949671998904569433">virgola</translation> +<translation id="3976707995992061296">Attiva o disattiva l'assegnazione della finestra attiva a tutte le scrivanie</translation> <translation id="3976863468609830880">Seleziona l'ultima icona nella barra delle app</translation> <translation id="3994783594793697310">Reimposta il livello di zoom dello schermo</translation> <translation id="4026843240379844265">Sposta la finestra attiva tra gli schermi</translation> @@ -149,6 +150,7 @@ <translation id="6340769215862220182">Aumenta lo zoom dello schermo</translation> <translation id="634687982629734605">Consente di spostare lo stato attivo tra: l'area di stato (dove è visualizzata l'immagine del tuo account), Avvio app, la barra degli indirizzi, la barra dei Preferiti (se visibile), la pagina web aperta e la barra dei download (se visibile). Se viene visualizzata una finestra di dialogo attivabile, sposta lì lo stato attivo.</translation> <translation id="6359811074279051077"><ph name="MODIFIER" /><ph name="SEPARATOR" /><ph name="KEY" /></translation> +<translation id="6372960562287888784">Attiva dalla 1ª all'8ª scrivania.</translation> <translation id="6395172954772765143">Seleziona il testo alla fine della riga</translation> <translation id="6425378783626925378">Consente di fare clic sulle icone 1-8 nella barra delle app</translation> <translation id="6435207348963613811">Mette in evidenza l'elemento precedente sulla barra delle app</translation> @@ -204,6 +206,7 @@ <translation id="8644639153978066712">Visualizza i file nascosti nell'app File</translation> <translation id="8717459106217102612">Seleziona la parola o la lettera precedente</translation> <translation id="8727232706774971183">Visualizza le notifiche</translation> +<translation id="8855548128280178372"><ph name="SHIFT" /><ph name="SEPARATOR1" /><ph name="SEARCH" /><ph name="SEPARATOR2" /> da 1 a 8</translation> <translation id="8855885154700222542">Tasto schermo intero</translation> <translation id="8881584919399569791">Sposta la finestra attiva sulla scrivania a sinistra</translation> <translation id="88986195241502842">Pagina giù</translation>
diff --git a/ash/shortcut_viewer/strings/shortcut_viewer_strings_mk.xtb b/ash/shortcut_viewer/strings/shortcut_viewer_strings_mk.xtb index dcdadb7..dee43ad 100644 --- a/ash/shortcut_viewer/strings/shortcut_viewer_strings_mk.xtb +++ b/ash/shortcut_viewer/strings/shortcut_viewer_strings_mk.xtb
@@ -89,6 +89,7 @@ <translation id="379295446891231126"><ph name="CTRL" /><ph name="SEPARATOR" /> 1 до 8</translation> <translation id="3837047332182291558">Направете ја тастатура посветла (само за тастатури со заднинско осветлување)</translation> <translation id="3949671998904569433">запирка</translation> +<translation id="3976707995992061296">Вклучете/исклучете дали активниот прозорец е доделен на сите работни површини</translation> <translation id="3976863468609830880">Кликнете на последната икона на полицата</translation> <translation id="3994783594793697310">Ресетирајте го нивото на зумирање на екранот</translation> <translation id="4026843240379844265">Премести го активниот прозорец помеѓу екраните</translation> @@ -149,6 +150,7 @@ <translation id="6340769215862220182">Зумирајте го екранот</translation> <translation id="634687982629734605">Префрлајте го фокусот помеѓу: статусната област (каде што се појавува сликата од сметката), стартерот, лентата за адреси, лентата со обележувачи (ако е видлива), веб-страницата што е отворена и лентата за преземања (ако е видлива). Ако се прикаже дијалог за фокусирање, поместете го фокусот таму.</translation> <translation id="6359811074279051077"><ph name="MODIFIER" /><ph name="SEPARATOR" /><ph name="KEY" /></translation> +<translation id="6372960562287888784">Активирајте ја од 1. до 8. работна површина.</translation> <translation id="6395172954772765143">Изберете текст на крајот од редот</translation> <translation id="6425378783626925378">Кликнете на иконите од 1 до 8 на полицата</translation> <translation id="6435207348963613811">Нагласете ја претходната ставка на полицата</translation> @@ -204,6 +206,7 @@ <translation id="8644639153978066712">Прикажете ги сокриените датотеки во апликацијата „Датотеки“</translation> <translation id="8717459106217102612">Изберете претходен збор или буква</translation> <translation id="8727232706774971183">Погледнете ги известувањата</translation> +<translation id="8855548128280178372"><ph name="SHIFT" /><ph name="SEPARATOR1" /><ph name="SEARCH" /><ph name="SEPARATOR2" /> од 1. до 8.</translation> <translation id="8855885154700222542">Копче за цел екран</translation> <translation id="8881584919399569791">Преместете го активниот прозорец на работниот простор лево</translation> <translation id="88986195241502842">Страница подолу</translation>
diff --git a/ash/strings/ash_strings_am.xtb b/ash/strings/ash_strings_am.xtb index 5990b06f..8088f6c 100644 --- a/ash/strings/ash_strings_am.xtb +++ b/ash/strings/ash_strings_am.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">የእርስዎን ስልክ ማግኘት አልተቻለም። የእርስዎ ስልክ ብሉቱዝ እንደበራ ያረጋግጡ።</translation> <translation id="3510164367642747937">የመዳፊት ጠቋሚን አድምቅ</translation> <translation id="3513798432020909783">መለያው በ<ph name="MANAGER_EMAIL" /> ነው የሚቀናበረው</translation> +<translation id="3518604429872942239">የሁኔታ መሣቢያ፣ ሰዓት <ph name="TIME" />፣ + <ph name="BATTERY" /> + <ph name="NETWORK" />፣ + <ph name="MIC" />፣ + <ph name="CAMERA" />፣ + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />፣ + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{በ1 ደቂቃ ውስጥ መሣሪያን ያዘምኑ}one{በ# ደቂቃዎች ውስጥ መሣሪያን ያዘምኑ}other{በ# ደቂቃዎች ውስጥ መሣሪያን ያዘምኑ}}</translation> <translation id="353086728817903341">ከ<ph name="NUM_DEVICES" /> መሣሪያዎች ጋር ተገናኝቷል</translation> <translation id="3552189655002856821">Wi-Fi ጠፍቷል</translation> @@ -376,6 +385,7 @@ <translation id="3630697955794050612">ጠፍቷል</translation> <translation id="3631369015426612114">ማሳወቂያዎች ከሚከተሉት እንዲመጡ ፍቀድ፦</translation> <translation id="3638400994746983214">የግላዊነት ማያ ገጽን ቀያይር። <ph name="STATE_TEXT" />።</translation> +<translation id="3640092422335864171"><ph name="NAME" />ን ያስቀምጡ</translation> <translation id="3649505501900178324">ዝማኔ ጊዜው ደርሶ አልፏል</translation> <translation id="366222428570480733"><ph name="USER_EMAIL_ADDRESS" /> የሚተዳደር ተጠቃሚ</translation> <translation id="3665889125180354336">ማይክሮፎን ይቅዱ</translation> @@ -458,6 +468,7 @@ <translation id="4215497585250573029">የቪፒኤን ቅንብሮች</translation> <translation id="4217571870635786043">በቃል ማስጻፍ</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />፣ የተጫነ መረግበሪያ፣ ባለበት ቆሟል</translation> +<translation id="4223947355273782392">ከሌሎች መሣሪያዎችዎ ጋር በፍጥነት ለማጣመር <ph name="NAME" />ን <ph name="EMAIL" /> ላይ ያስቀምጡ</translation> <translation id="4239069858505860023">ጂፒአርኤስ</translation> <translation id="4242533952199664413">ቅንብሮችን ክፈት</translation> <translation id="4250229828105606438">ቅጽበታዊ ገጽ እይታ</translation>
diff --git a/ash/strings/ash_strings_ar.xtb b/ash/strings/ash_strings_ar.xtb index 898244d..b6986509 100644 --- a/ash/strings/ash_strings_ar.xtb +++ b/ash/strings/ash_strings_ar.xtb
@@ -355,6 +355,15 @@ <translation id="3509391053705095206">يتعذَّر العثور على هاتفك. تأكّد من أنّ البلوتوث مفعَّل على هاتفك.</translation> <translation id="3510164367642747937">تمييز مؤشر الماوس</translation> <translation id="3513798432020909783">يُدير <ph name="MANAGER_EMAIL" /> الحساب.</translation> +<translation id="3518604429872942239">شريط الحالة، الوقت <ph name="TIME" />، + <ph name="BATTERY" /> + <ph name="NETWORK" />، + <ph name="MIC" />، + <ph name="CAMERA" />، + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />، + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{تحديث الجهاز خلال دقيقة واحدة}zero{تحديث الجهاز خلال # دقيقة}two{تحديث الجهاز خلال دقيقتين}few{تحديث الجهاز خلال # دقائق}many{تحديث الجهاز خلال # دقيقة}other{تحديث الجهاز خلال # دقيقة}}</translation> <translation id="353086728817903341">تم الربط بـ <ph name="NUM_DEVICES" /> جهاز.</translation> <translation id="3552189655002856821">تم إيقاف شبكة Wi-Fi.</translation>
diff --git a/ash/strings/ash_strings_as.xtb b/ash/strings/ash_strings_as.xtb index ab0e02c..f8a9c6a 100644 --- a/ash/strings/ash_strings_as.xtb +++ b/ash/strings/ash_strings_as.xtb
@@ -385,6 +385,7 @@ <translation id="3630697955794050612">অফ আছে</translation> <translation id="3631369015426612114">এইবোৰৰ জাননীক অনুমতি দিয়ে</translation> <translation id="3638400994746983214">গোপনীয়তাৰ স্ক্ৰীন ট’গল কৰক। <ph name="STATE_TEXT" />।</translation> +<translation id="3640092422335864171"><ph name="NAME" /> ছেভ কৰক</translation> <translation id="3649505501900178324">আপডে'ট বাকী আছে</translation> <translation id="366222428570480733"><ph name="USER_EMAIL_ADDRESS" />এ পৰিচালনা কৰা ব্যৱহাৰকাৰী</translation> <translation id="3665889125180354336">মাইক্ৰ'ফ'ন ৰেকৰ্ড কৰক</translation> @@ -467,6 +468,7 @@ <translation id="4215497585250573029">ভিপিএনৰ ছেটিংসমূহ</translation> <translation id="4217571870635786043">শ্ৰুতলিপি</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, ইনষ্টল কৰা এপ্, পজ কৰি থোৱা</translation> +<translation id="4223947355273782392">আপোনাৰ অন্য ডিভাইচসমূহৰ সৈতে দ্ৰুতভাৱে পেয়াৰ কৰিবলৈ <ph name="NAME" /> <ph name="EMAIL" />ত ছেভ কৰক</translation> <translation id="4239069858505860023">জিপিআৰএছ</translation> <translation id="4242533952199664413">ছেটিংসমূহ খোলক</translation> <translation id="4250229828105606438">স্ক্রীণশ্বট</translation>
diff --git a/ash/strings/ash_strings_be.xtb b/ash/strings/ash_strings_be.xtb index 1500e2f7..9ac1a2ba 100644 --- a/ash/strings/ash_strings_be.xtb +++ b/ash/strings/ash_strings_be.xtb
@@ -201,6 +201,7 @@ <translation id="2352467521400612932">Налады стыла</translation> <translation id="2354174487190027830">Ідзе актывацыя сеткі <ph name="NAME" /></translation> <translation id="2359808026110333948">Працягнуць</translation> +<translation id="2360625459710946148">Упарадкаваць паводле наступнага параметра:</translation> <translation id="2367186422933365202">Не ўдаецца выканаць уваход на прыладзе Chromebook</translation> <translation id="2369165858548251131">"Вітаю" па-кітайску</translation> <translation id="2390318262976603432">Рэгіянальныя налады</translation> @@ -327,6 +328,7 @@ <translation id="334252345105450327">Зрабіць здымак экрана</translation> <translation id="3351879221545518001">Вы трансліруеце экран.</translation> <translation id="3364721542077212959">Інструменты стыла</translation> +<translation id="3365977133351922112">Тэлефон знаходзіцца занадта далёка. Паднясіце яго бліжэй.</translation> <translation id="3368922792935385530">Падключана</translation> <translation id="3371140690572404006">Прылада USB-C (пярэдні порт справа)</translation> <translation id="3375634426936648815">Падключана</translation> @@ -379,6 +381,7 @@ <translation id="3665889125180354336">Запіс з мікрафона</translation> <translation id="3680908746918359504">Выдаліць усе маркеры</translation> <translation id="36813544980941320">Інфармацыя пра сеткі Wi-Fi будзе абагульвацца паміж тэлефонам і прыладай <ph name="DEVICE_NAME" /></translation> +<translation id="3694122362646626770">Вэб-сайты</translation> <translation id="3701206655856637070">Месца захоўвання файлаў, атрыманых у выніку здымання экрана, можна змяніць</translation> <translation id="3702809606464356667">Паказаны вокны бягучага працоўнага стала. Каб пераключыцца на рэжым паказу вокнаў усіх працоўных сталоў, націсніце стрэлку ўверх</translation> <translation id="3702846122927433391">Насельніцтва Нігерыі</translation> @@ -594,6 +597,7 @@ <translation id="5170568018924773124">Паказаць у папцы</translation> <translation id="5176318573511391780">Запіс часткі экрана</translation> <translation id="5199367439331364630">Каб увайсці на прыладзе Chromebook, увядзіце пароль</translation> +<translation id="5206028654245650022"><ph name="APP_NAME" />, <ph name="NOTIFICATION_TITLE" />: <ph name="MESSAGE" />, <ph name="PHONE_NAME" /></translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{яшчэ 1 апавяшчэнне}one{яшчэ # апавяшчэнне}few{яшчэ # апавяшчэнні}many{яшчэ # апавяшчэнняў}other{яшчэ # апавяшчэння}}</translation> <translation id="5207949376430453814">Указваць на курсор рэдагавання тэксту</translation> <translation id="5208059991603368177">Уключана</translation> @@ -697,6 +701,7 @@ <translation id="5977415296283489383">Навушнікі</translation> <translation id="5978382165065462689">Абагульванне кантролю над экранам праз Аддаленую дапамогу.</translation> <translation id="5980301590375426705">Выйсці з гасцявога рэжыму</translation> +<translation id="598407983968395253">Выкарыстаць шаблон</translation> <translation id="598882571027504733">Для абнаўлення падключыце клавіятуру і перазапусціце Chromebook.</translation> <translation id="5992218262414051481">Рэжым высокай кантраснасці ўключаны. Каб выключыць яго, зноў націсніце Ctrl + Пошук + H.</translation> <translation id="6018164090099858612">Выхад з рэжыму адлюстравання</translation> @@ -878,6 +883,7 @@ <translation id="7398254312354928459">Пераключана падключэнне да сеткі</translation> <translation id="7405710164030118432">Каб разблакіраваць прыладу, увядзіце бацькоўскі код доступу Family Link.</translation> <translation id="7406608787870898861">Завяршыце наладжванне мабільнай сеткі</translation> +<translation id="740790383907119240">Ярлыкі праграм</translation> <translation id="741244894080940828">перавод адзінак вымярэння</translation> <translation id="7413851974711031813">Каб закрыць, націсніце Escape</translation> <translation id="742594950370306541">Камера выкарыстоўваецца.</translation> @@ -980,6 +986,7 @@ <translation id="8061464966246066292">Высокая кантраснасць</translation> <translation id="8098591350844501178">Спыніць трансляцыю экрана на прыёмнік "<ph name="RECEIVER_NAME" />"</translation> <translation id="8113423164597455979">Уключана, усе праграмы</translation> +<translation id="8120151603115102514">На тэлефоне не выкарыстоўваецца функцыя экрана блакіроўкі. Каб разблакіраваць Chromebook, увядзіце пароль.</translation> <translation id="8129620843620772246"><ph name="TEMPERATURE_C" /> °C</translation> <translation id="8131740175452115882">Пацвердзіць</translation> <translation id="8132487352815776550">Схаваць субцітры</translation> @@ -1029,6 +1036,7 @@ <translation id="8473301994082929012">Арганізацыя <ph name="ORGANIZATION_NAME" /> <ph name="FEATURE_STATE" /> функцыю "<ph name="FEATURE_NAME" />".</translation> <translation id="8477270416194247200">Каб скасаваць, націсніце "Alt+Пошук" або "Shift".</translation> <translation id="8492573885090281069"><ph name="DISPLAY_NAME" /> не падтрымлівае раздзяляльнасць <ph name="SPECIFIED_RESOLUTION" />. Прыменена раздзяляльнасць <ph name="FALLBACK_RESOLUTION" />. Каб захаваць змяненні, націсніце "Пацвердзіць". Папярэднія налады будуць адноўлены праз <ph name="TIMEOUT_SECONDS" />.</translation> +<translation id="85123341071060231">Bluetooth на прыладзе Chromebook выключаны. Каб разблакіраваць Chromebook, увядзіце пароль.</translation> <translation id="8513108775083588393">Аўтапаварот</translation> <translation id="851458219935658693">Паказ вокнаў бягучага працоўнага стала, выбраны пераключальнік</translation> <translation id="8517041960877371778"><ph name="DEVICE_TYPE" /> можа не зараджацца ва ўключаным стане.</translation>
diff --git a/ash/strings/ash_strings_bn.xtb b/ash/strings/ash_strings_bn.xtb index c74111b..1de235b 100644 --- a/ash/strings/ash_strings_bn.xtb +++ b/ash/strings/ash_strings_bn.xtb
@@ -376,6 +376,7 @@ <translation id="3630697955794050612">বন্ধ</translation> <translation id="3631369015426612114">নিম্নলিখিত থেকে বিজ্ঞপ্তি অনুমতি দিন</translation> <translation id="3638400994746983214">গোপনীয়তা স্ক্রিন টগল করুন। <ph name="STATE_TEXT" />।</translation> +<translation id="3640092422335864171"><ph name="NAME" /> সেভ করুন</translation> <translation id="3649505501900178324">আপডেট করতে ডিভাইস রিস্টার্ট করুন</translation> <translation id="366222428570480733"><ph name="USER_EMAIL_ADDRESS" /> ম্যানেজ করা ব্যবহারকারী</translation> <translation id="3665889125180354336">মাইক্রোফোনে রেকর্ড করুন</translation> @@ -458,6 +459,7 @@ <translation id="4215497585250573029">ভিপিএন সেটিংস</translation> <translation id="4217571870635786043">ডিক্টেশন</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, ইনস্টল করা অ্যাপ, পজ করা হয়েছে</translation> +<translation id="4223947355273782392">আপনার অন্যান্য ডিভাইসের সাথে আরও দ্রুত পেয়ার করতে <ph name="EMAIL" />-এ <ph name="NAME" /> সেভ করুন</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">সেটিংস খুলুন</translation> <translation id="4250229828105606438">স্ক্রিনশট</translation>
diff --git a/ash/strings/ash_strings_bs.xtb b/ash/strings/ash_strings_bs.xtb index 43bade9..541140cf 100644 --- a/ash/strings/ash_strings_bs.xtb +++ b/ash/strings/ash_strings_bs.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">Nije moguće pronaći vaš telefon. Provjerite je li Bluetooth na telefonu uključen.</translation> <translation id="3510164367642747937">Istakni kursor miša</translation> <translation id="3513798432020909783">Računom upravlja <ph name="MANAGER_EMAIL" /></translation> +<translation id="3518604429872942239">Traka statusa, vrijeme <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{Ažurirajte uređaj u roku od 1 minute}one{Ažurirajte uređaj u roku od # minute}few{Ažurirajte uređaj u roku od # minute}other{Ažurirajte uređaj u roku od # minuta}}</translation> <translation id="353086728817903341">Povezano je sa sljedećim brojem uređaja: <ph name="NUM_DEVICES" /></translation> <translation id="3552189655002856821">WiFi je isključen</translation>
diff --git a/ash/strings/ash_strings_el.xtb b/ash/strings/ash_strings_el.xtb index 5355107..e9621bc4 100644 --- a/ash/strings/ash_strings_el.xtb +++ b/ash/strings/ash_strings_el.xtb
@@ -376,6 +376,7 @@ <translation id="3630697955794050612">ανενεργή</translation> <translation id="3631369015426612114">Να επιτρέπονται ειδοποιήσεις από</translation> <translation id="3638400994746983214">Εναλλαγή οθόνης απορρήτου. <ph name="STATE_TEXT" />.</translation> +<translation id="3640092422335864171">Αποθήκευση <ph name="NAME" /></translation> <translation id="3649505501900178324">Εκπρόθεσμη ενημέρωση</translation> <translation id="366222428570480733"><ph name="USER_EMAIL_ADDRESS" /> Διαχειριζόμενος χρήστης</translation> <translation id="3665889125180354336">Εγγραφή μικροφώνου</translation> @@ -458,6 +459,7 @@ <translation id="4215497585250573029">Ρυθμίσεις VPN</translation> <translation id="4217571870635786043">Υπαγόρευση</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, Εγκατεστημένη εφαρμογή, Τέθηκε σε παύση</translation> +<translation id="4223947355273782392">Αποθηκεύστε τη συσκευή <ph name="NAME" /> στον λογαριασμό <ph name="EMAIL" /> για γρηγορότερη σύζευξη με άλλες συσκευές.</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">Ανοίξτε τις ρυθμίσεις</translation> <translation id="4250229828105606438">Στιγμιότυπο οθόνης</translation>
diff --git a/ash/strings/ash_strings_et.xtb b/ash/strings/ash_strings_et.xtb index dec1b9b..d6ac77f 100644 --- a/ash/strings/ash_strings_et.xtb +++ b/ash/strings/ash_strings_et.xtb
@@ -201,6 +201,7 @@ <translation id="2352467521400612932">Elektronpliiatsi seaded</translation> <translation id="2354174487190027830">Võrgu <ph name="NAME" /> aktiveerimine</translation> <translation id="2359808026110333948">Jätka</translation> +<translation id="2360625459710946148">Ümberjärjestamise alus</translation> <translation id="2367186422933365202">Teie Chromebooki ei õnnestu sisse logida</translation> <translation id="2369165858548251131">„Tere” hiina keeles</translation> <translation id="2390318262976603432">Lokaadi seaded</translation> @@ -710,6 +711,7 @@ <translation id="5977415296283489383">Kõrvaklapid</translation> <translation id="5978382165065462689">Ekraani juhtimise jagamine kaugabi kaudu.</translation> <translation id="5980301590375426705">Välju kül. seansist</translation> +<translation id="598407983968395253">Kasuta malli</translation> <translation id="598882571027504733">Värskenduse hankimiseks taaskäivitage Chromebook koos ühendatud klaviatuuriga.</translation> <translation id="5992218262414051481">Suure kontrastsusega režiim on lubatud. Vajutage selle väljalülitamiseks uuesti klahvikombinatsiooni Ctrl + otsinguklahv + H.</translation> <translation id="6018164090099858612">Peeglirežiimist väljumine</translation>
diff --git a/ash/strings/ash_strings_eu.xtb b/ash/strings/ash_strings_eu.xtb index 7c7ae04..5e8f4f6 100644 --- a/ash/strings/ash_strings_eu.xtb +++ b/ash/strings/ash_strings_eu.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">Ezin da aurkitu telefonoa. Ziurtatu telefonoaren Bluetooth-a aktibatuta dagoela.</translation> <translation id="3510164367642747937">Nabarmendu saguaren kurtsorea</translation> <translation id="3513798432020909783"><ph name="MANAGER_EMAIL" /> kontuaren bidez kudeatzen da kontu hau</translation> +<translation id="3518604429872942239">Egoera-erretilua. Ordua: <ph name="TIME" /> + <ph name="BATTERY" /> + <ph name="NETWORK" /> + <ph name="MIC" /> + <ph name="CAMERA" /> + <ph name="MANAGED" /> + <ph name="NOTIFICATION" /> + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{Eguneratu gailua minutu bat barru}other{Eguneratu gailua # minutu barru}}</translation> <translation id="353086728817903341">Konektatu da <ph name="NUM_DEVICES" /> gailutara</translation> <translation id="3552189655002856821">Desaktibatuta dago wifi-konexioa</translation> @@ -376,6 +385,7 @@ <translation id="3630697955794050612">desaktibatuta</translation> <translation id="3631369015426612114">Onartu hauen jakinarazpenak</translation> <translation id="3638400994746983214">Aktibatu/Desaktibatu pribatutasun-pantaila. <ph name="STATE_TEXT" />.</translation> +<translation id="3640092422335864171">Gorde <ph name="NAME" /></translation> <translation id="3649505501900178324">Eguneratze bat dago egiteke</translation> <translation id="366222428570480733"><ph name="USER_EMAIL_ADDRESS" />, erabiltzaile kudeatua</translation> <translation id="3665889125180354336">Mikrofono bidezko grabaketa</translation> @@ -459,6 +469,7 @@ <translation id="4215497585250573029">VPN ezarpenak</translation> <translation id="4217571870635786043">Diktaketa</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, instalatutako aplikazioa, pausatuta</translation> +<translation id="4223947355273782392">Gainerako gailuekin bizkorrago parekatu ahal izateko, gorde <ph name="NAME" /> izeneko gailua <ph name="EMAIL" /> helbideari dagokion kontuan</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">Ireki ezarpenak</translation> <translation id="4250229828105606438">Pantaila-argazkia</translation>
diff --git a/ash/strings/ash_strings_fa.xtb b/ash/strings/ash_strings_fa.xtb index 72f98ef5..bc3e0dc 100644 --- a/ash/strings/ash_strings_fa.xtb +++ b/ash/strings/ash_strings_fa.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">نمیتوان تلفنتان را پیدا کرد. مطمئن شوید بلوتوث تلفن روشن باشد.</translation> <translation id="3510164367642747937">برجسته کردن نشانگر موشواره</translation> <translation id="3513798432020909783">حساب تحت مدیریت <ph name="MANAGER_EMAIL" /> است</translation> +<translation id="3518604429872942239">سینی وضعیت، زمان <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{دستگاه را تا یک دقیقه دیگر بهروزرسانی کنید}one{دستگاه را تا # دقیقه دیگر بهروزرسانی کنید}other{دستگاه را تا # دقیقه دیگر بهروزرسانی کنید}}</translation> <translation id="353086728817903341">به <ph name="NUM_DEVICES" /> دستگاه متصل است</translation> <translation id="3552189655002856821">Wi-Fi خاموش است</translation> @@ -376,6 +385,7 @@ <translation id="3630697955794050612">خاموش</translation> <translation id="3631369015426612114">مجاز کردن اعلانهای منابع زیر</translation> <translation id="3638400994746983214">روشن/خاموش کردن صفحه حریمخصوصی. <ph name="STATE_TEXT" />.</translation> +<translation id="3640092422335864171">ذخیره <ph name="NAME" /></translation> <translation id="3649505501900178324">بهروزرسانی عقبافتاده</translation> <translation id="366222428570480733"><ph name="USER_EMAIL_ADDRESS" /> کاربر مدیریتشده</translation> <translation id="3665889125180354336">ضبط میکروفون</translation> @@ -458,6 +468,7 @@ <translation id="4215497585250573029">تنظیمات VPN</translation> <translation id="4217571870635786043">املا</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />، برنامه نصبشده، موقتاً متوقفشده</translation> +<translation id="4223947355273782392">برای مرتبطسازی سریعتر با دستگاههای دیگر، <ph name="NAME" /> را در <ph name="EMAIL" /> ذخیره کنید</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">باز کردن تنظیمات</translation> <translation id="4250229828105606438">نماگرفت</translation>
diff --git a/ash/strings/ash_strings_fil.xtb b/ash/strings/ash_strings_fil.xtb index c06c062..69ec35a 100644 --- a/ash/strings/ash_strings_fil.xtb +++ b/ash/strings/ash_strings_fil.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">Hindi makita ang iyong telepono. Tiyaking naka-on ang Bluetooth ng iyong telepono.</translation> <translation id="3510164367642747937">I-highlight ang cursor ng mouse</translation> <translation id="3513798432020909783">Pinamamahalaan ni <ph name="MANAGER_EMAIL" /> ang account</translation> +<translation id="3518604429872942239">Status tray, oras <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{I-update ang device sa loob ng 1 minuto}one{I-update ang device sa loob ng # minuto}other{I-update ang device sa loob ng # na minuto}}</translation> <translation id="353086728817903341">Nakakonekta sa <ph name="NUM_DEVICES" /> (na) device</translation> <translation id="3552189655002856821">Naka-off ang Wi-Fi</translation>
diff --git a/ash/strings/ash_strings_gl.xtb b/ash/strings/ash_strings_gl.xtb index fcff4be..d902a5a 100644 --- a/ash/strings/ash_strings_gl.xtb +++ b/ash/strings/ash_strings_gl.xtb
@@ -328,6 +328,7 @@ <translation id="334252345105450327">Fai unha captura de pantalla</translation> <translation id="3351879221545518001">Agora estás emitindo a pantalla.</translation> <translation id="3364721542077212959">Ferramentas de lapis óptico</translation> +<translation id="3365977133351922112">O teu teléfono está demasiado lonxe. Achégao.</translation> <translation id="3368922792935385530">Conectada</translation> <translation id="3371140690572404006">Dispositivo USB‑C (porto dereito frontal)</translation> <translation id="3375634426936648815">Función conectada</translation> @@ -597,6 +598,7 @@ <translation id="5170568018924773124">Mostrar no cartafol</translation> <translation id="5176318573511391780">Gravar pantalla parcial</translation> <translation id="5199367439331364630">Para iniciar sesión no Chromebook, mete o contrasinal</translation> +<translation id="5206028654245650022"><ph name="APP_NAME" />, <ph name="NOTIFICATION_TITLE" />: <ph name="MESSAGE" />, <ph name="PHONE_NAME" /></translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{1 notificación máis}other{# notificacións máis}}</translation> <translation id="5207949376430453814">Destacar o cursor de texto</translation> <translation id="5208059991603368177">Activado</translation> @@ -882,6 +884,7 @@ <translation id="7398254312354928459">Cambiouse a conexión de rede</translation> <translation id="7405710164030118432">Para desbloquear o dispositivo, introduce o código de acceso parental de Family Link</translation> <translation id="7406608787870898861">Remata de configurar a túa rede de telefonía móbil</translation> +<translation id="740790383907119240">Atallos da aplicación</translation> <translation id="741244894080940828">conversión</translation> <translation id="7413851974711031813">Para pechar o diálogo, preme a tecla Escape</translation> <translation id="742594950370306541">Estase utilizando a cámara.</translation> @@ -984,6 +987,7 @@ <translation id="8061464966246066292">Alto contraste</translation> <translation id="8098591350844501178">Deter a emisión da pantalla en: <ph name="RECEIVER_NAME" /></translation> <translation id="8113423164597455979">Si, para todas</translation> +<translation id="8120151603115102514">O teu teléfono non ten unha pantalla de bloqueo. Para desbloquear o Chromebook, escribe o contrasinal.</translation> <translation id="8129620843620772246"><ph name="TEMPERATURE_C" /> °C</translation> <translation id="8131740175452115882">Confirmar</translation> <translation id="8132487352815776550">Deter subtítulos</translation> @@ -1033,6 +1037,7 @@ <translation id="8473301994082929012"><ph name="ORGANIZATION_NAME" /> <ph name="FEATURE_STATE" /> <ph name="FEATURE_NAME" />.</translation> <translation id="8477270416194247200">Preme Alt + Buscar ou Maiúsculas para cancelar.</translation> <translation id="8492573885090281069"><ph name="DISPLAY_NAME" /> non admite <ph name="SPECIFIED_RESOLUTION" />. A resolución cambiouse a <ph name="FALLBACK_RESOLUTION" />. Para gardar os cambios, fai clic en Confirmar. A configuración anterior restaurarase en <ph name="TIMEOUT_SECONDS" />.</translation> +<translation id="85123341071060231">O Bluethooth do teu Chromebook está desactivado. Para desbloquealo, escribe o contrasinal.</translation> <translation id="8513108775083588393">Xirar autom.</translation> <translation id="851458219935658693">Seleccionouse o botón de opción para mostrar as ventás do escritorio actual</translation> <translation id="8517041960877371778">É posible que o teu <ph name="DEVICE_TYPE" /> non cargue mentres estea acendido.</translation>
diff --git a/ash/strings/ash_strings_hr.xtb b/ash/strings/ash_strings_hr.xtb index c90fe3c..6602a9b6 100644 --- a/ash/strings/ash_strings_hr.xtb +++ b/ash/strings/ash_strings_hr.xtb
@@ -328,6 +328,7 @@ <translation id="334252345105450327">Izradi snimku zaslona</translation> <translation id="3351879221545518001">Trenutačno emitirate zaslon.</translation> <translation id="3364721542077212959">Alati pisaljke</translation> +<translation id="3365977133351922112">Telefon je predaleko. Približite telefon.</translation> <translation id="3368922792935385530">Spojeno</translation> <translation id="3371140690572404006">USB-C uređaj (prednji desni priključak)</translation> <translation id="3375634426936648815">Povezano</translation> @@ -353,6 +354,15 @@ <translation id="3509391053705095206">Ne možemo pronaći vaš telefon. Provjerite je li na telefonu uključen Bluetooth.</translation> <translation id="3510164367642747937">Istakni pokazivač miša</translation> <translation id="3513798432020909783">Računom upravlja <ph name="MANAGER_EMAIL" /></translation> +<translation id="3518604429872942239">Traka statusa, vrijeme <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{Ažurirajte uređaj u roku od jedne minute}one{Ažurirajte uređaj u roku od # minute}few{Ažurirajte uređaj u roku od # minute}other{Ažurirajte uređaj u roku od # minuta}}</translation> <translation id="353086728817903341">Povezano s ovoliko uređaja: <ph name="NUM_DEVICES" />.</translation> <translation id="3552189655002856821">Wi-Fi je isključen</translation> @@ -375,6 +385,7 @@ <translation id="3630697955794050612">isključeno</translation> <translation id="3631369015426612114">Omogućite obavijesti iz sljedećih izvora</translation> <translation id="3638400994746983214">Uključite/isključite zaslon privatnosti. <ph name="STATE_TEXT" />.</translation> +<translation id="3640092422335864171">Spremite uređaj <ph name="NAME" /></translation> <translation id="3649505501900178324">Zakašnjelo ažuriranje</translation> <translation id="366222428570480733"><ph name="USER_EMAIL_ADDRESS" /> upravljani korisnik</translation> <translation id="3665889125180354336">Snimanje mikrofona</translation> @@ -457,6 +468,7 @@ <translation id="4215497585250573029">VPN postavke</translation> <translation id="4217571870635786043">Diktat</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, instalirana aplikacija, pauzirana</translation> +<translation id="4223947355273782392">Spremite uređaj <ph name="NAME" /> na račun <ph name="EMAIL" /> za brže uparivanje s ostalim uređajima</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">Otvori postavke</translation> <translation id="4250229828105606438">Snimka zaslona</translation> @@ -596,6 +608,7 @@ <translation id="5170568018924773124">Pokaži u mapi</translation> <translation id="5176318573511391780">Snimanje dijela zaslona</translation> <translation id="5199367439331364630">Da biste se prijavili na Chromebook, unesite zaporku</translation> +<translation id="5206028654245650022"><ph name="APP_NAME" />, <ph name="NOTIFICATION_TITLE" />: <ph name="MESSAGE" />, <ph name="PHONE_NAME" /></translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{Još jedna obavijest}one{Još # obavijest}few{Još # obavijesti}other{Još # obavijesti}}</translation> <translation id="5207949376430453814">Istakni znak za umetanje teksta</translation> <translation id="5208059991603368177">Uključeno</translation> @@ -881,6 +894,7 @@ <translation id="7398254312354928459">Promijenjena je mrežna veza</translation> <translation id="7405710164030118432">Da biste otključali uređaj, unesite kôd za roditeljski pristup Family Linka</translation> <translation id="7406608787870898861">Dovršite postavljanje mobilne mreže</translation> +<translation id="740790383907119240">Aplikacijski prečaci</translation> <translation id="741244894080940828">preračunavanje</translation> <translation id="7413851974711031813">Pritisnite tipku escape da biste zatvorili</translation> <translation id="742594950370306541">Fotoaparat je aktivan.</translation> @@ -983,6 +997,7 @@ <translation id="8061464966246066292">Visoki kontrast</translation> <translation id="8098591350844501178">Zaustavi emitiranje zaslona na prijamniku <ph name="RECEIVER_NAME" /></translation> <translation id="8113423164597455979">Uklj., sve ap.</translation> +<translation id="8120151603115102514">Telefon nema zaključan zaslon. Da biste otključali Chromebook, unesite zaporku.</translation> <translation id="8129620843620772246"><ph name="TEMPERATURE_C" />° C</translation> <translation id="8131740175452115882">Potvrdi</translation> <translation id="8132487352815776550">Zaustavi titlove</translation> @@ -1032,6 +1047,7 @@ <translation id="8473301994082929012"><ph name="ORGANIZATION_NAME" /> ima <ph name="FEATURE_STATE" /> <ph name="FEATURE_NAME" />.</translation> <translation id="8477270416194247200">Pritisnite Alt + Pretraživanje ili Shift da biste otkazali.</translation> <translation id="8492573885090281069"><ph name="DISPLAY_NAME" /> ne podržava razlučivost <ph name="SPECIFIED_RESOLUTION" />. Razlučivost je promijenjena u <ph name="FALLBACK_RESOLUTION" />. Kliknite Potvrdi da biste zadržali promjene. Prethodne postavke vratit će se za <ph name="TIMEOUT_SECONDS" />.</translation> +<translation id="85123341071060231">Bluetooth na Chromebooku je isključen. Da biste otključali Chromebook, unesite zaporku.</translation> <translation id="8513108775083588393">Autom. zakret.</translation> <translation id="851458219935658693">Prikaži prozore s trenutačne radne površine, odabran je izborni gumb</translation> <translation id="8517041960877371778">Uređaj <ph name="DEVICE_TYPE" /> možda se neće puniti dok je uključen.</translation>
diff --git a/ash/strings/ash_strings_hy.xtb b/ash/strings/ash_strings_hy.xtb index abd1eba5..99910b7 100644 --- a/ash/strings/ash_strings_hy.xtb +++ b/ash/strings/ash_strings_hy.xtb
@@ -119,6 +119,7 @@ <translation id="1743570585616704562">Չճանաչվեց</translation> <translation id="1746730358044914197">Ներածման եղանակները կարգավորվում են ձեր ադմինիստրատորի կողմից:</translation> <translation id="1747827819627189109">Էկրանի ստեղնաշարը միացված է</translation> +<translation id="1750088060796401187">Աշխատասեղանների առավելագույն թիվը (<ph name="MAX_DESK_LIMIT" />) լրացել է։ Հեռացրեք որևէ աշխատասեղան՝ նորը բացելու համար։</translation> <translation id="1761222317188459878">Միացնել/անջատել կապը: <ph name="STATE_TEXT" /></translation> <translation id="1768366657309696705"><ph name="LAUNCHER_KEY_NAME" /> + ․ (միջակետ) ստեղնային դյուրանցումը փոփոխվել է։ Insert ստեղնն օգտագործելու համար սեղմեք <ph name="LAUNCHER_KEY_NAME" /> + Shift + Backspace։</translation> <translation id="1771761307086386028">Ոլորել աջ</translation> @@ -375,6 +376,7 @@ <translation id="3630697955794050612">անջատված է</translation> <translation id="3631369015426612114">Թույլ տալ ծանուցումները հետևյալ կայքերից</translation> <translation id="3638400994746983214">Միացնել/անջատել գաղտնիության էկրանը։ <ph name="STATE_TEXT" />:</translation> +<translation id="3640092422335864171">Պահեք սարքը (<ph name="NAME" />)</translation> <translation id="3649505501900178324">Թարմացման ժամկետը լրացել է</translation> <translation id="366222428570480733"><ph name="USER_EMAIL_ADDRESS" /> կառավարվող օգտատեր</translation> <translation id="3665889125180354336">Ձայնագրում</translation> @@ -457,6 +459,7 @@ <translation id="4215497585250573029">VPN կարգավորումներ</translation> <translation id="4217571870635786043">Ձայնային ներածում</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, տեղադրված հավելված, դադարեցված է</translation> +<translation id="4223947355273782392">Ավելացրեք սարքը (<ph name="NAME" />) <ph name="EMAIL" /> հաշվում, որպեսզի ավելի արագ կարողանաք զուգակցել այն ձեր մյուս սարքերի հետ։</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">Բացել կարգավորումները</translation> <translation id="4250229828105606438">Սքրինշոթ</translation>
diff --git a/ash/strings/ash_strings_it.xtb b/ash/strings/ash_strings_it.xtb index d0a25f1..e8711d4 100644 --- a/ash/strings/ash_strings_it.xtb +++ b/ash/strings/ash_strings_it.xtb
@@ -119,6 +119,7 @@ <translation id="1743570585616704562">Non riconosciuta</translation> <translation id="1746730358044914197">I metodi di immissione vengono configurati dall'amministratore.</translation> <translation id="1747827819627189109">Tastiera sullo schermo attiva</translation> +<translation id="1750088060796401187">Sono consentite al massimo <ph name="MAX_DESK_LIMIT" /> scrivanie. Rimuovi una scrivania per aprirne una nuova.</translation> <translation id="1761222317188459878">Attiva/disattiva connessione di rete. <ph name="STATE_TEXT" /></translation> <translation id="1768366657309696705">La scorciatoia da tastiera <ph name="LAUNCHER_KEY_NAME" /> + Punto è cambiata. Per usare il tasto Ins, premi il tasto <ph name="LAUNCHER_KEY_NAME" /> + Maiusc + Backspace.</translation> <translation id="1771761307086386028">Scorri a destra</translation>
diff --git a/ash/strings/ash_strings_iw.xtb b/ash/strings/ash_strings_iw.xtb index 6bc73bf0..2953d84 100644 --- a/ash/strings/ash_strings_iw.xtb +++ b/ash/strings/ash_strings_iw.xtb
@@ -328,6 +328,7 @@ <translation id="334252345105450327">יצירת צילום מסך</translation> <translation id="3351879221545518001">מתבצעת עכשיו העברה של מסך.</translation> <translation id="3364721542077212959">כלי סטיילוס</translation> +<translation id="3365977133351922112">הטלפון שלך רחוק מדי. צריך לקרב את הטלפון.</translation> <translation id="3368922792935385530">מחובר</translation> <translation id="3371140690572404006">מכשיר עם יציאת USB-C (יציאה ימנית-קדמית)</translation> <translation id="3375634426936648815">מחובר</translation> @@ -596,6 +597,7 @@ <translation id="5170568018924773124">הצגה בתיקייה</translation> <translation id="5176318573511391780">הקלטה של מסך חלקי</translation> <translation id="5199367439331364630">כדי לבטל את נעילת ה-Chromebook, עליך להזין סיסמה</translation> +<translation id="5206028654245650022"><ph name="APP_NAME" />, <ph name="NOTIFICATION_TITLE" />: <ph name="MESSAGE" />, <ph name="PHONE_NAME" /></translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{התראה אחת נוספת}two{# התראות נוספות}many{# התראות נוספות}other{# התראות נוספות}}</translation> <translation id="5207949376430453814">הדגשה של סמן הטקסט</translation> <translation id="5208059991603368177">פועל</translation> @@ -881,6 +883,7 @@ <translation id="7398254312354928459">חיבור הרשת הוחלף</translation> <translation id="7405710164030118432">כדי לבטל את נעילת המכשיר, יש להזין את קוד גישת ההורה של Family Link</translation> <translation id="7406608787870898861">סיום ההגדרה של הרשת הסלולרית</translation> +<translation id="740790383907119240">קיצורי דרך של אפליקציות</translation> <translation id="741244894080940828">המרה</translation> <translation id="7413851974711031813">יש להקיש על "Esc" לסגירה</translation> <translation id="742594950370306541">המצלמה נמצאת בשימוש.</translation> @@ -985,6 +988,7 @@ <translation id="8061464966246066292">ניגודיות גבוהה</translation> <translation id="8098591350844501178">הפסקת העברת המסך אל <ph name="RECEIVER_NAME" /></translation> <translation id="8113423164597455979">מופעל, כל האפליקציות</translation> +<translation id="8120151603115102514">לטלפון שלך אין מסך נעילה. כדי לבטל את נעילת ה-Chromebook, עליך להזין סיסמה.</translation> <translation id="8129620843620772246"><ph name="TEMPERATURE_C" />° C</translation> <translation id="8131740175452115882">אישור</translation> <translation id="8132487352815776550">להפסקת הכתוביות</translation> @@ -1034,6 +1038,7 @@ <translation id="8473301994082929012"><ph name="ORGANIZATION_NAME" /> <ph name="FEATURE_STATE" /> את <ph name="FEATURE_NAME" />.</translation> <translation id="8477270416194247200">יש להקיש על Alt+Search או על Shift כדי לבטל.</translation> <translation id="8492573885090281069">התצוגה של <ph name="DISPLAY_NAME" /> לא תומכת ברזולוציה <ph name="SPECIFIED_RESOLUTION" />. הרזולוציה שונתה ל-<ph name="FALLBACK_RESOLUTION" />. לשמירת השינויים, יש ללחוץ על 'אישור'. ההגדרות הקודמות ישוחזרו בעוד <ph name="TIMEOUT_SECONDS" />.</translation> +<translation id="85123341071060231">החיבור של ה-Chromebook ל-Bluetooth כבוי. צריך להזין סיסמה כדי לפתוח את ה-Chromebook.</translation> <translation id="8513108775083588393">סיבוב אוטומטי</translation> <translation id="851458219935658693">הצגת חלונות משולחן העבודה הווירטואלי הנוכחי, לחצן הבחירה נבחר</translation> <translation id="8517041960877371778">ייתכן שה-<ph name="DEVICE_TYPE" /> לא ייטען כשהוא פועל.</translation>
diff --git a/ash/strings/ash_strings_kk.xtb b/ash/strings/ash_strings_kk.xtb index 4084e4c..2b5b6a7 100644 --- a/ash/strings/ash_strings_kk.xtb +++ b/ash/strings/ash_strings_kk.xtb
@@ -375,6 +375,7 @@ <translation id="3630697955794050612">өшірулі</translation> <translation id="3631369015426612114">Келесі көздерден алынатын хабарландыруларға рұқсат беру</translation> <translation id="3638400994746983214">Құпиялылық экранын қосу немесе өшіру. <ph name="STATE_TEXT" />.</translation> +<translation id="3640092422335864171"><ph name="NAME" /> құрылғысын сақтау</translation> <translation id="3649505501900178324">Жаңарту мерзімі өтіп кетті</translation> <translation id="366222428570480733">Басқарылатын пайдаланушы: <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="3665889125180354336">Микрофон арқылы жазу</translation> @@ -457,6 +458,7 @@ <translation id="4215497585250573029">VPN параметрлері</translation> <translation id="4217571870635786043">Мәтінді дауыспен енгізу</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, қолданба орнатылған, кідіртілген</translation> +<translation id="4223947355273782392">Басқа құрылғыларыңызбен жылдамырақ жұптау үшін <ph name="NAME" /> құрылғысын <ph name="EMAIL" /> аккаунтына сақтаңыз.</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">Параметрлерді ашу</translation> <translation id="4250229828105606438">Скриншот</translation>
diff --git a/ash/strings/ash_strings_kn.xtb b/ash/strings/ash_strings_kn.xtb index b8bedbb..cfc3b573 100644 --- a/ash/strings/ash_strings_kn.xtb +++ b/ash/strings/ash_strings_kn.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಹುಡುಕಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ. ನಿಮ್ಮ ಫೋನ್ನ ಬ್ಲೂಟೂತ್ ಆನ್ ಆಗಿದೆಯೇ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ.</translation> <translation id="3510164367642747937">ಮೌಸ್ ಕರ್ಸರ್ ಎದ್ದುಗಾಣಿಸಿ</translation> <translation id="3513798432020909783"><ph name="MANAGER_EMAIL" /> ಮೂಲಕ ಖಾತೆಯನ್ನು ನಿರ್ವಹಿಸಲಾಗಿದೆ</translation> +<translation id="3518604429872942239">ಸ್ಥಿತಿ ಟ್ರೇ, ಸಮಯ <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{1 ನಿಮಿಷದೊಳಗೆ ಸಾಧನವನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಿ}one{# ನಿಮಿಷಗಳೊಳಗೆ ಸಾಧನವನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಿ}other{# ನಿಮಿಷಗಳೊಳಗೆ ಸಾಧನವನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಿ}}</translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> ಸಾಧನಗಳಿಗೆ ಕನೆಕ್ಟ್ ಮಾಡಲಾಗಿದೆ</translation> <translation id="3552189655002856821">ವೈ-ಫೈ ಆಫ್ ಮಾಡಲಾಗಿದೆ</translation> @@ -376,6 +385,7 @@ <translation id="3630697955794050612">ಆಫ್</translation> <translation id="3631369015426612114">ಕೆಳಗಿನವುಗಳಿಂದ ಅಧಿಸೂಚನೆಗಳನ್ನು ಅನುಮತಿಸಿ</translation> <translation id="3638400994746983214">ಗೌಪ್ಯತೆ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಟಾಗಲ್ ಮಾಡಿ. <ph name="STATE_TEXT" />.</translation> +<translation id="3640092422335864171"><ph name="NAME" /> ಉಳಿಸಿ</translation> <translation id="3649505501900178324">ಅಪ್ಡೇಟ್ ಬಾಕಿ ಉಳಿದಿದೆ</translation> <translation id="366222428570480733"><ph name="USER_EMAIL_ADDRESS" /> ನಿರ್ವಹಿಸಲಾದ ಬಳಕೆದಾರರು</translation> <translation id="3665889125180354336">ಮೈಕ್ರೋಫೋನ್ ಮೂಲಕ ರೆಕಾರ್ಡ್ ಮಾಡಿ ಆಯ್ಕೆ</translation> @@ -458,6 +468,7 @@ <translation id="4215497585250573029">VPN ಸೆಟ್ಟಿಂಗ್ಗಳು</translation> <translation id="4217571870635786043">ಉಕ್ತಲೇಖನ</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿದ ಆ್ಯಪ್, ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ</translation> +<translation id="4223947355273782392">ನಿಮ್ಮ ಇತರ ಸಾಧನಗಳ ಜೊತೆಗೆ ಶೀಘ್ರ ಜೋಡಿಗೋಳಿಸುವಿಕೆಗಾಗಿ <ph name="EMAIL" /> ಗೆ <ph name="NAME" /> ಸಾಧನವನ್ನು ಉಳಿಸಿ</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆ</translation> <translation id="4250229828105606438">ಸ್ಕ್ರೀನ್ಶಾಟ್</translation>
diff --git a/ash/strings/ash_strings_ky.xtb b/ash/strings/ash_strings_ky.xtb index 51c7a88..72331a8 100644 --- a/ash/strings/ash_strings_ky.xtb +++ b/ash/strings/ash_strings_ky.xtb
@@ -201,6 +201,7 @@ <translation id="2352467521400612932">Стилус жөндөөлөрү</translation> <translation id="2354174487190027830"><ph name="NAME" /> жандыруу</translation> <translation id="2359808026110333948">Улантуу</translation> +<translation id="2360625459710946148">Төмөнкү боюнча иреттөө:</translation> <translation id="2367186422933365202">Chromebook'ка кирген жоксуз</translation> <translation id="2369165858548251131">Кытайча "Салам"</translation> <translation id="2390318262976603432">Тил жөндөөлөрү</translation> @@ -353,6 +354,15 @@ <translation id="3509391053705095206">Телефонуңуз табылбай жатат. Телефонуңуздагы Bluetooth күйгүзүлгөнүн текшериңиз.</translation> <translation id="3510164367642747937">Чычкан курсору баса белгиленсин</translation> <translation id="3513798432020909783">Аккаунтту башкарган: <ph name="MANAGER_EMAIL" /></translation> +<translation id="3518604429872942239">Абал түпкүчү, убакыт <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{Түзмөктү 1 мүнөттүн ичинде жаңыртыңыз}other{Түзмөктү # мүнөттүн ичинде жаңыртыңыз}}</translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> түзмөккө туташты</translation> <translation id="3552189655002856821">Wi-Fi өчүрүлгөн</translation> @@ -702,6 +712,7 @@ <translation id="5977415296283489383">Гарнитура</translation> <translation id="5978382165065462689">Алыскы жардамчы аркылуу экраныңыздын көзөмөлүн бөлүшүүдө.</translation> <translation id="5980301590375426705">Конокту чыгаруу</translation> +<translation id="598407983968395253">Үлгүнү колдонуу</translation> <translation id="598882571027504733">Жаңыртуу үчүн, туташкан баскычтопту үзбөй туруп, Chromebook'ту өчүрүп-күйгүзүңүз.</translation> <translation id="5992218262414051481">Жогорку контраст режими иштетилди. Аны өчүрүү үчүн Ctrl+Search+H баскычтарын кайра басыңыз.</translation> <translation id="6018164090099858612">Күзгү режиминен чыгууда</translation>
diff --git a/ash/strings/ash_strings_lo.xtb b/ash/strings/ash_strings_lo.xtb index 6b150dce..7f9ac20 100644 --- a/ash/strings/ash_strings_lo.xtb +++ b/ash/strings/ash_strings_lo.xtb
@@ -200,6 +200,7 @@ <translation id="2352467521400612932">ການຕັ້ງຄ່າປາຍປາກກາ</translation> <translation id="2354174487190027830">ກຳລັງເປີດນຳໃຊ້ <ph name="NAME" /></translation> <translation id="2359808026110333948">ສືບຕໍ່</translation> +<translation id="2360625459710946148">ຈັດຮຽງຄືນໃໝ່ຕາມ</translation> <translation id="2367186422933365202">ບໍ່ສາມາດເຂົ້າສູ່ລະບົບຫາ Chromebook ຂອງທ່ານໄດ້</translation> <translation id="2369165858548251131">"ສະບາຍດີ" ເປັນພາສາຈີນ</translation> <translation id="2390318262976603432">ການຕັ້ງຄ່າສະຖານທີ່</translation> @@ -352,6 +353,15 @@ <translation id="3509391053705095206">ບໍ່ສາມາດຊອກເຫັນໂທລະສັບຂອງທ່ານໄດ້. ກະລຸນາກວດສອບວ່າ Bluetooth ຂອງໂທລະສັບທ່ານເປີດຢູ່.</translation> <translation id="3510164367642747937">ໝາຍເຄີເຊີເມົ້າ</translation> <translation id="3513798432020909783">ບັນຊີທີ່ຈັດການໂດຍ <ph name="MANAGER_EMAIL" /></translation> +<translation id="3518604429872942239">ຖາດສະຖານະ, ເວລາ <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{ອັບເດດອຸປະກອນພາຍໃນ 1 ນາທີ}other{ອັບເດດອຸປະກອນພາຍໃນ # ນາທີ}}</translation> <translation id="353086728817903341">ເຊື່ອມຕໍ່ຫາ <ph name="NUM_DEVICES" /> ອຸປະກອນແລ້ວ</translation> <translation id="3552189655002856821">ປິດ Wi-Fi ແລ້ວ</translation> @@ -699,6 +709,7 @@ <translation id="5977415296283489383">ຫູຟັງ</translation> <translation id="5978382165065462689">ການແບ່ງປັນການຄວບຄຸມໜ້າຈໍຂອງທ່ານຜ່ານຕົວຊ່ວຍທາງໄກ.</translation> <translation id="5980301590375426705">ອອກຈາກແຂກ</translation> +<translation id="598407983968395253">ໃຊ້ແມ່ແບບ</translation> <translation id="598882571027504733">ເພື່ອຮັບເອົາການອັບເດດ, ກະລຸນາປິດເປີດ Chromebook ຂອງທ່ານຄືນໃໝ່ທີ່ມີແປ້ນພິມເຊື່ອມຕໍ່ແລ້ວ.</translation> <translation id="5992218262414051481">ເປີດນຳໃຊ້ໂໝດສີຕັດສູງແລ້ວ. ກົດ Ctrl+Search+H ອີກຄັ້ງເພື່ອປິດມັນ.</translation> <translation id="6018164090099858612">ກຳລັງອອກຈາກໂໝດແວ່ນສະທ້ອນ</translation>
diff --git a/ash/strings/ash_strings_lv.xtb b/ash/strings/ash_strings_lv.xtb index 7ae4fe4..b662733c 100644 --- a/ash/strings/ash_strings_lv.xtb +++ b/ash/strings/ash_strings_lv.xtb
@@ -201,6 +201,7 @@ <translation id="2352467521400612932">Skārienekrāna pildspalvas iestatījumi</translation> <translation id="2354174487190027830">Notiek <ph name="NAME" /> aktivizēšana.</translation> <translation id="2359808026110333948">Turpināt</translation> +<translation id="2360625459710946148">Pārkārtošana pēc:</translation> <translation id="2367186422933365202">Nevar pierakstīties Chromebook datorā.</translation> <translation id="2369165858548251131">“Sveiki!” ķīniešu valodā</translation> <translation id="2390318262976603432">Lokalizācijas iestatījumi</translation> @@ -698,6 +699,7 @@ <translation id="5977415296283489383">Austiņas</translation> <translation id="5978382165065462689">Ekrāna pārvaldības koplietošana, izmantojot attālo palīdzību.</translation> <translation id="5980301590375426705">Aizvērt viesa sesiju</translation> +<translation id="598407983968395253">Izmantot veidni</translation> <translation id="598882571027504733">Lai iegūtu atjauninājumu, restartējiet savu Chromebook datoru ar pievienoto tastatūru.</translation> <translation id="5992218262414051481">Augsta kontrasta režīms ir iespējots. Lai to izslēgtu, vēlreiz nospiediet Ctrl+Search+H.</translation> <translation id="6018164090099858612">Notiek iziešana no spoguļošanas režīma</translation>
diff --git a/ash/strings/ash_strings_mk.xtb b/ash/strings/ash_strings_mk.xtb index 259c283..42237cc 100644 --- a/ash/strings/ash_strings_mk.xtb +++ b/ash/strings/ash_strings_mk.xtb
@@ -119,6 +119,7 @@ <translation id="1743570585616704562">Не е препознаен</translation> <translation id="1746730358044914197">Методите на внесување ги конфигурира вашиот администратор.</translation> <translation id="1747827819627189109">Тастатурата на екранот е овозможена</translation> +<translation id="1750088060796401187">Дозволени се само <ph name="MAX_DESK_LIMIT" /> работни површини. Отстранете работна површина за да отворите нова.</translation> <translation id="1761222317188459878">Вклучи/исклучи мрежна врска. <ph name="STATE_TEXT" /></translation> <translation id="1768366657309696705">Кратенката од тастатура <ph name="LAUNCHER_KEY_NAME" /> + Точка се промени. За да го користите копчето Insert, притиснете го копчето <ph name="LAUNCHER_KEY_NAME" /> + Shift + Backspace.</translation> <translation id="1771761307086386028">Лизгај надесно</translation>
diff --git a/ash/strings/ash_strings_mr.xtb b/ash/strings/ash_strings_mr.xtb index ded7f7d..359cbb0 100644 --- a/ash/strings/ash_strings_mr.xtb +++ b/ash/strings/ash_strings_mr.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">तुमचा फोन शोधू शकत नाही. तुमच्या फोनचे ब्लूटूथ सुरू असल्याची खात्री करा.</translation> <translation id="3510164367642747937">माउसचा कर्सर हायलाइट करा</translation> <translation id="3513798432020909783">खाते <ph name="MANAGER_EMAIL" /> ने व्यवस्थापित केले आहे</translation> +<translation id="3518604429872942239">स्टेटस ट्रे, वेळ <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{डिव्हाइस एका मिनिटाच्या आत अपडेट करा}other{डिव्हाइस # मिनिटांच्या आत अपडेट करा}}</translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> डिव्हाइसशी कनेक्ट केले</translation> <translation id="3552189655002856821">वाय-फाय बंद केले आहे</translation>
diff --git a/ash/strings/ash_strings_ne.xtb b/ash/strings/ash_strings_ne.xtb index 75969f9..f30f050 100644 --- a/ash/strings/ash_strings_ne.xtb +++ b/ash/strings/ash_strings_ne.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">तपाईंको फोन भेट्टाउन सकिएन। आफ्नो फोनको ब्लुटुथ अन गरिएको छ भन्ने कुरा सुनिश्चित गर्नुहोस्।</translation> <translation id="3510164367642747937">माउसको कर्सरलाई हाइलाइट</translation> <translation id="3513798432020909783"><ph name="MANAGER_EMAIL" /> ले व्यवस्थापन गरेको खाता</translation> +<translation id="3518604429872942239">स्ट्याटस ट्रे, समय <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{१ मिनेटभित्र डिभाइस रिस्टार्ट गर्नुहोस्}other{# मिनेटभित्र डिभाइस रिस्टार्ट गर्नुहोस्}}</translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> वटा डिभाइसमा कनेक्ट गरिएको छ</translation> <translation id="3552189655002856821">Wi-Fi अफ गरियो</translation>
diff --git a/ash/strings/ash_strings_nl.xtb b/ash/strings/ash_strings_nl.xtb index 7af033b..1c9e1b9 100644 --- a/ash/strings/ash_strings_nl.xtb +++ b/ash/strings/ash_strings_nl.xtb
@@ -385,6 +385,7 @@ <translation id="3630697955794050612">uit</translation> <translation id="3631369015426612114">Meldingen toestaan van het volgende</translation> <translation id="3638400994746983214">Privacyscherm aan/uit. <ph name="STATE_TEXT" />.</translation> +<translation id="3640092422335864171"><ph name="NAME" /> opslaan</translation> <translation id="3649505501900178324">Update vereist</translation> <translation id="366222428570480733">Beheerde gebruiker <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="3665889125180354336">Microfoon opnemen</translation> @@ -467,6 +468,7 @@ <translation id="4215497585250573029">VPN-instellingen</translation> <translation id="4217571870635786043">Dicteren</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, geïnstalleerde app, onderbroken</translation> +<translation id="4223947355273782392">Sla <ph name="NAME" /> op in <ph name="EMAIL" /> voor sneller koppelen met je andere apparaten</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">Instellingen openen</translation> <translation id="4250229828105606438">Screenshot</translation>
diff --git a/ash/strings/ash_strings_pa.xtb b/ash/strings/ash_strings_pa.xtb index 55b4098..ae1474f 100644 --- a/ash/strings/ash_strings_pa.xtb +++ b/ash/strings/ash_strings_pa.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">ਤੁਹਾਡਾ ਫ਼ੋਨ ਨਹੀਂ ਲੱਭਿਆ ਜਾ ਸਕਦਾ। ਪੱਕਾ ਕਰੋ ਕਿ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦਾ ਬਲੂਟੁੱਥ ਚਾਲੂ ਹੈ।</translation> <translation id="3510164367642747937">ਮਾਊਸ ਕਰਸਰ ਨੂੰ ਉਜਾਗਰ ਕਰੋ</translation> <translation id="3513798432020909783"><ph name="MANAGER_EMAIL" /> ਵੱਲੋਂ ਖਾਤੇ ਦਾ ਪ੍ਰਬੰਧਨ ਕੀਤਾ ਜਾਂਦਾ ਹੈ</translation> +<translation id="3518604429872942239">ਸਥਿਤੀ ਟ੍ਰੇਅ, ਸਮਾਂ <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{ਡੀਵਾਈਸ ਨੂੰ 1 ਮਿੰਟ ਦੇ ਅੰਦਰ ਅੱਪਡੇਟ ਕਰੋ}one{ਡੀਵਾਈਸ ਨੂੰ # ਮਿੰਟ ਦੇ ਅੰਦਰ ਅੱਪਡੇਟ ਕਰੋ}other{ਡੀਵਾਈਸ ਨੂੰ # ਮਿੰਟਾਂ ਦੇ ਅੰਦਰ ਅੱਪਡੇਟ ਕਰੋ}}</translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> ਡੀਵਾਈਸਾਂ ਨਾਲ ਕਨੈਕਟ ਕੀਤਾ ਗਿਆ</translation> <translation id="3552189655002856821">ਵਾਈ-ਫਾਈ ਬੰਦ ਹੈ</translation>
diff --git a/ash/strings/ash_strings_pt-BR.xtb b/ash/strings/ash_strings_pt-BR.xtb index 8f1c344..5b46da8 100644 --- a/ash/strings/ash_strings_pt-BR.xtb +++ b/ash/strings/ash_strings_pt-BR.xtb
@@ -200,6 +200,7 @@ <translation id="2352467521400612932">Configurações da stylus</translation> <translation id="2354174487190027830">Ativando <ph name="NAME" /></translation> <translation id="2359808026110333948">Continuar</translation> +<translation id="2360625459710946148">Reordenar por</translation> <translation id="2367186422933365202">Não foi possível fazer login no Chromebook</translation> <translation id="2369165858548251131">"Olá" em chinês</translation> <translation id="2390318262976603432">Configurações de localidade</translation> @@ -374,6 +375,7 @@ <translation id="3630697955794050612">desativada</translation> <translation id="3631369015426612114">Permitir as seguintes notificações</translation> <translation id="3638400994746983214">Alternar tela de privacidade. <ph name="STATE_TEXT" /></translation> +<translation id="3640092422335864171">Salvar <ph name="NAME" /></translation> <translation id="3649505501900178324">Atualização atrasada</translation> <translation id="366222428570480733">Usuário gerenciado <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="3665889125180354336">Gravar microfone</translation> @@ -456,6 +458,7 @@ <translation id="4215497585250573029">Configurações de VPN</translation> <translation id="4217571870635786043">Ditado</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, app instalado, pausado</translation> +<translation id="4223947355273782392">Salve o <ph name="NAME" /> em <ph name="EMAIL" /> para agilizar o pareamento dele com outros dispositivos</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">Abrir configurações.</translation> <translation id="4250229828105606438">Captura de tela</translation> @@ -699,6 +702,7 @@ <translation id="5977415296283489383">Fone de ouvido</translation> <translation id="5978382165065462689">Compartilhando o controle de sua tela por meio da Assistência remota.</translation> <translation id="5980301590375426705">Sair sessão visit.</translation> +<translation id="598407983968395253">Usar modelo</translation> <translation id="598882571027504733">Para receber a atualização, reinicie seu Chromebook com o teclado conectado.</translation> <translation id="5992218262414051481">Modo de alto contraste ativado. Pressione Ctrl+Pesquisa+H novamente para desativá-lo.</translation> <translation id="6018164090099858612">Saindo do modo espelhado</translation>
diff --git a/ash/strings/ash_strings_pt-PT.xtb b/ash/strings/ash_strings_pt-PT.xtb index 88b03d4..be79f302 100644 --- a/ash/strings/ash_strings_pt-PT.xtb +++ b/ash/strings/ash_strings_pt-PT.xtb
@@ -353,6 +353,15 @@ <translation id="3509391053705095206">Não é possível encontrar o telemóvel. Certifique-se de que o Bluetooth do telemóvel está ativado.</translation> <translation id="3510164367642747937">Realçar cursor do rato</translation> <translation id="3513798432020909783">Conta gerida por <ph name="MANAGER_EMAIL" />.</translation> +<translation id="3518604429872942239">Tabuleiro do estado, hora <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{Atualize o dispositivo dentro de 1 minuto}one{Atualize o dispositivo dentro de # minuto(s)}other{Atualize o dispositivo dentro de # minutos}}</translation> <translation id="353086728817903341">Ligado a <ph name="NUM_DEVICES" /> dispositivos</translation> <translation id="3552189655002856821">O Wi-Fi está desativado</translation> @@ -375,6 +384,7 @@ <translation id="3630697955794050612">desativado</translation> <translation id="3631369015426612114">Permitir notificações das seguintes fontes:</translation> <translation id="3638400994746983214">Ative/desative o ecrã de privacidade. <ph name="STATE_TEXT" />.</translation> +<translation id="3640092422335864171">Guarde o dispositivo <ph name="NAME" /></translation> <translation id="3649505501900178324">Atualização vencida</translation> <translation id="366222428570480733">Utilizador gerido por <ph name="USER_EMAIL_ADDRESS" /></translation> <translation id="3665889125180354336">Gravar microfone</translation> @@ -457,6 +467,7 @@ <translation id="4215497585250573029">Definições da VPN</translation> <translation id="4217571870635786043">Ditado</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, app instalada, em pausa</translation> +<translation id="4223947355273782392">Guarde o dispositivo <ph name="NAME" /> em <ph name="EMAIL" /> para permitir uma sincronização mais rápida com os outros dispositivos</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">Abrir definições</translation> <translation id="4250229828105606438">Captura de ecrã</translation>
diff --git a/ash/strings/ash_strings_sr-Latn.xtb b/ash/strings/ash_strings_sr-Latn.xtb index f82c442..a1b26c6 100644 --- a/ash/strings/ash_strings_sr-Latn.xtb +++ b/ash/strings/ash_strings_sr-Latn.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">Pronalaženje telefona nije uspelo. Proverite da li je Bluetooth na telefonu uključen.</translation> <translation id="3510164367642747937">Istakni kursor miša</translation> <translation id="3513798432020909783">Nalogom upravlja <ph name="MANAGER_EMAIL" /></translation> +<translation id="3518604429872942239">Statusna traka, vreme <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{Ažurirajte uređaj u roku od 1 minuta}one{Ažurirajte uređaj u roku od # minuta}few{Ažurirajte uređaj u roku od # minuta}other{Ažurirajte uređaj u roku od # minuta}}</translation> <translation id="353086728817903341">Povezani ste sa <ph name="NUM_DEVICES" /> uređaja</translation> <translation id="3552189655002856821">WiFi je isključen</translation>
diff --git a/ash/strings/ash_strings_sr.xtb b/ash/strings/ash_strings_sr.xtb index f85f4bb..198e6e8 100644 --- a/ash/strings/ash_strings_sr.xtb +++ b/ash/strings/ash_strings_sr.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">Проналажење телефона није успело. Проверите да ли је Bluetooth на телефону укључен.</translation> <translation id="3510164367642747937">Истакни курсор миша</translation> <translation id="3513798432020909783">Налогом управља <ph name="MANAGER_EMAIL" /></translation> +<translation id="3518604429872942239">Статусна трака, време <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{Ажурирајте уређај у року од 1 минута}one{Ажурирајте уређај у року од # минута}few{Ажурирајте уређај у року од # минута}other{Ажурирајте уређај у року од # минута}}</translation> <translation id="353086728817903341">Повезани сте са <ph name="NUM_DEVICES" /> уређаја</translation> <translation id="3552189655002856821">WiFi је искључен</translation>
diff --git a/ash/strings/ash_strings_sv.xtb b/ash/strings/ash_strings_sv.xtb index 0a614e1..0a31e37 100644 --- a/ash/strings/ash_strings_sv.xtb +++ b/ash/strings/ash_strings_sv.xtb
@@ -328,6 +328,7 @@ <translation id="334252345105450327">Ta en skärmbild</translation> <translation id="3351879221545518001">Skärmen castas.</translation> <translation id="3364721542077212959">Verktyg för e-penna</translation> +<translation id="3365977133351922112">Telefonen är för långt bort. Flytta telefonen närmare.</translation> <translation id="3368922792935385530">Ansluten</translation> <translation id="3371140690572404006">USB-C-enhet (främre porten på högra sidan)</translation> <translation id="3375634426936648815">Ansluten</translation> @@ -596,6 +597,7 @@ <translation id="5170568018924773124">Visa i mapp</translation> <translation id="5176318573511391780">Spela in en del av skärmen</translation> <translation id="5199367439331364630">Ange lösenordet om du vill logga in på Chromebook</translation> +<translation id="5206028654245650022"><ph name="APP_NAME" />, <ph name="NOTIFICATION_TITLE" />: <ph name="MESSAGE" />, <ph name="PHONE_NAME" /></translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{1 avisering till}other{# aviseringar till}}</translation> <translation id="5207949376430453814">Markera textmarkören</translation> <translation id="5208059991603368177">På</translation> @@ -881,6 +883,7 @@ <translation id="7398254312354928459">Bytte nätverksanslutning</translation> <translation id="7405710164030118432">Lås upp enheten genom att ange föräldraåtkomstkoden för Family Link</translation> <translation id="7406608787870898861">Slutför konfigureringen av mobilnätverket</translation> +<translation id="740790383907119240">Genvägar till appar</translation> <translation id="741244894080940828">Räkna om</translation> <translation id="7413851974711031813">Stäng genom att trycka på Esc</translation> <translation id="742594950370306541">Kameran används.</translation> @@ -983,6 +986,7 @@ <translation id="8061464966246066292">Hög kontrast</translation> <translation id="8098591350844501178">Sluta casta skärmen till <ph name="RECEIVER_NAME" /></translation> <translation id="8113423164597455979">Alla appar på</translation> +<translation id="8120151603115102514">Telefonen saknar låsskärm. Lås upp Chromebook med lösenordet.</translation> <translation id="8129620843620772246"><ph name="TEMPERATURE_C" /> °C</translation> <translation id="8131740175452115882">Bekräfta</translation> <translation id="8132487352815776550">Stoppa textning</translation> @@ -1032,6 +1036,7 @@ <translation id="8473301994082929012"><ph name="ORGANIZATION_NAME" /> har <ph name="FEATURE_STATE" /> <ph name="FEATURE_NAME" />.</translation> <translation id="8477270416194247200">Avbryt genom att trycka på Alt + söktangenten eller Skift.</translation> <translation id="8492573885090281069"><ph name="DISPLAY_NAME" /> har inte stöd för <ph name="SPECIFIED_RESOLUTION" />. Upplösningen ändrades till <ph name="FALLBACK_RESOLUTION" />. Klicka på bekräfta om du vill behålla ändringarna. De gamla inställningarna återställs om <ph name="TIMEOUT_SECONDS" />.</translation> +<translation id="85123341071060231">Bluetooth har inaktiverats på Chromebook. Lås upp Chromebook med lösenordet.</translation> <translation id="8513108775083588393">Rotera automatiskt</translation> <translation id="851458219935658693">Visa fönster från det aktuella skrivbordet, alternativknapp har markerats</translation> <translation id="8517041960877371778">Din <ph name="DEVICE_TYPE" /> laddas eventuellt inte så länge den är på.</translation>
diff --git a/ash/strings/ash_strings_ta.xtb b/ash/strings/ash_strings_ta.xtb index 5c46035..c812cd1 100644 --- a/ash/strings/ash_strings_ta.xtb +++ b/ash/strings/ash_strings_ta.xtb
@@ -354,6 +354,15 @@ <translation id="3509391053705095206">உங்கள் மொபைலைக் கண்டறிய முடியவில்லை. அதில் புளூடூத் இயக்கப்பட்டிருப்பதை உறுதிசெய்துகொள்ளவும்.</translation> <translation id="3510164367642747937">மவுஸ் கர்சரைத் தனிப்படுத்து</translation> <translation id="3513798432020909783">கணக்கை நிர்வகிப்பது: <ph name="MANAGER_EMAIL" /></translation> +<translation id="3518604429872942239">நிலைத் தட்டு, நேரம் <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{ஒரு நிமிடத்திற்குள் சாதனத்தை மீண்டும் தொடங்குங்கள்}other{# நிமிடங்களுக்குள் சாதனத்தை மீண்டும் தொடங்குங்கள்}}</translation> <translation id="353086728817903341"><ph name="NUM_DEVICES" /> சாதனங்களுடன் இணைக்கப்பட்டுள்ளது</translation> <translation id="3552189655002856821">வைஃபை முடக்கப்பட்டது</translation>
diff --git a/ash/strings/ash_strings_tr.xtb b/ash/strings/ash_strings_tr.xtb index c93f4be..aa93307e 100644 --- a/ash/strings/ash_strings_tr.xtb +++ b/ash/strings/ash_strings_tr.xtb
@@ -328,6 +328,7 @@ <translation id="334252345105450327">Ekran görüntüsü al</translation> <translation id="3351879221545518001">Şu anda ekranı yayınlıyorsunuz.</translation> <translation id="3364721542077212959">Ekran kalemi araçları</translation> +<translation id="3365977133351922112">Telefonunuz çok uzakta. Telefonunuzu daha yakına getirin.</translation> <translation id="3368922792935385530">Bağlı</translation> <translation id="3371140690572404006">USB-C cihaz (sağ ön bağlantı noktası)</translation> <translation id="3375634426936648815">Bağlı</translation> @@ -375,6 +376,7 @@ <translation id="3630697955794050612">kapalı</translation> <translation id="3631369015426612114">Şunlardan gelen bildirimlere izin ver:</translation> <translation id="3638400994746983214">Gizlilik ekranını aç/kapat. <ph name="STATE_TEXT" />.</translation> +<translation id="3640092422335864171"><ph name="NAME" /> cihazını kaydet</translation> <translation id="3649505501900178324">Güncelleme zamanı geçti</translation> <translation id="366222428570480733"><ph name="USER_EMAIL_ADDRESS" /> Yönetilen kullanıcı</translation> <translation id="3665889125180354336">Mikrofon kaydı</translation> @@ -457,6 +459,7 @@ <translation id="4215497585250573029">VPN Ayarları</translation> <translation id="4217571870635786043">Dikte</translation> <translation id="4221957499226645091"><ph name="APP_NAME" />, Yüklü Uygulama, Duraklatıldı</translation> +<translation id="4223947355273782392">Diğer cihazlarınızla daha hızlı eşlemek için <ph name="NAME" /> cihazını <ph name="EMAIL" /> adresine kaydedin</translation> <translation id="4239069858505860023">GPRS</translation> <translation id="4242533952199664413">Ayarları aç</translation> <translation id="4250229828105606438">Ekran görüntüsü</translation> @@ -596,6 +599,7 @@ <translation id="5170568018924773124">Klasörde göster</translation> <translation id="5176318573511391780">Kısmi ekranı kaydet</translation> <translation id="5199367439331364630">Chromebook'unuzda oturum açmak için şifreyi girin</translation> +<translation id="5206028654245650022"><ph name="APP_NAME" />, <ph name="NOTIFICATION_TITLE" />: <ph name="MESSAGE" />, <ph name="PHONE_NAME" /></translation> <translation id="5206057955438543357">{NUM_NOTIFICATIONS,plural, =1{1 diğer bildirim}other{# diğer bildirim}}</translation> <translation id="5207949376430453814">Metin imlecini vurgula</translation> <translation id="5208059991603368177">Açık</translation> @@ -882,6 +886,7 @@ <translation id="7398254312354928459">Ağ bağlantısı değiştirildi</translation> <translation id="7405710164030118432">Bu cihazın kilidini açmak için Family Link ebeveyn erişim kodunuzu girin</translation> <translation id="7406608787870898861">Mobil ağınızın kurulumunu tamamlayın</translation> +<translation id="740790383907119240">Uygulama Kısayolları</translation> <translation id="741244894080940828">dönüştürme</translation> <translation id="7413851974711031813">Kapatmak için escape tuşuna basın</translation> <translation id="742594950370306541">Kamera kullanımda.</translation> @@ -984,6 +989,7 @@ <translation id="8061464966246066292">Yüksek kontrast</translation> <translation id="8098591350844501178">Ekranın <ph name="RECEIVER_NAME" /> cihazına yayınını durdur</translation> <translation id="8113423164597455979">Açık, tümü</translation> +<translation id="8120151603115102514">Telefonunuzda kilit ekranı etkinleştirilmemiş. Chromebook'unuzun kilidini açmak için şifreyi girin.</translation> <translation id="8129620843620772246"><ph name="TEMPERATURE_C" />° C</translation> <translation id="8131740175452115882">Onayla</translation> <translation id="8132487352815776550">Altyazıları durdur</translation> @@ -1033,6 +1039,7 @@ <translation id="8473301994082929012"><ph name="ORGANIZATION_NAME" />, <ph name="FEATURE_STATE" /> <ph name="FEATURE_NAME" /> özelliğine sahip.</translation> <translation id="8477270416194247200">İptal etmek için Alt+Ara veya Üst Karakter tuşuna basın.</translation> <translation id="8492573885090281069"><ph name="DISPLAY_NAME" />, <ph name="SPECIFIED_RESOLUTION" /> çözünürlüğü desteklemiyor. Çözünürlük <ph name="FALLBACK_RESOLUTION" /> olarak değiştirildi. Değişiklikleri korumak için Onayla'yı tıklayın. Önceki ayarlar <ph name="TIMEOUT_SECONDS" /> saniye içinde geri yüklenecek.</translation> +<translation id="85123341071060231">Chromebook’unuzun Bluetooth'u kapalı. Chromebook'unuzun kilidini açmak için şifreyi girin.</translation> <translation id="8513108775083588393">Oto. döndür</translation> <translation id="851458219935658693">Geçerli masadaki pencereleri göster, radyo düğmesi seçildi</translation> <translation id="8517041960877371778"><ph name="DEVICE_TYPE" /> cihazınız açıkken şarj olmayabilir.</translation>
diff --git a/ash/strings/ash_strings_uk.xtb b/ash/strings/ash_strings_uk.xtb index 8a08d90..88a5fe49 100644 --- a/ash/strings/ash_strings_uk.xtb +++ b/ash/strings/ash_strings_uk.xtb
@@ -353,6 +353,15 @@ <translation id="3509391053705095206">Не вдається знайти телефон. Переконайтеся, що на ньому ввімкнено Bluetooth.</translation> <translation id="3510164367642747937">Підсвічувати курсор миші</translation> <translation id="3513798432020909783">Обліковим записом керує <ph name="MANAGER_EMAIL" /></translation> +<translation id="3518604429872942239">Панель статусу, час: <ph name="TIME" />, + <ph name="BATTERY" /> + <ph name="NETWORK" />, + <ph name="MIC" />, + <ph name="CAMERA" />, + <ph name="MANAGED" /> + <ph name="NOTIFICATION" />, + <ph name="IME" /> + <ph name="LOCALE" /></translation> <translation id="352245152354538528">{0,plural, =1{Оновіть пристрій протягом 1 хвилини}one{Оновіть пристрій протягом # хвилини}few{Оновіть пристрій протягом # хвилин}many{Оновіть пристрій протягом # хвилин}other{Оновіть пристрій протягом # хвилини}}</translation> <translation id="353086728817903341">Підключено до стількох пристроїв: <ph name="NUM_DEVICES" /></translation> <translation id="3552189655002856821">Wi-Fi вимкнено</translation>
diff --git a/ash/strings/ash_strings_zh-HK.xtb b/ash/strings/ash_strings_zh-HK.xtb index 6d6d0f6..3a08bad 100644 --- a/ash/strings/ash_strings_zh-HK.xtb +++ b/ash/strings/ash_strings_zh-HK.xtb
@@ -354,7 +354,7 @@ <translation id="3509391053705095206">找不到手機。請確保手機的藍牙功能已開啟。</translation> <translation id="3510164367642747937">突顯滑鼠遊標</translation> <translation id="3513798432020909783">帳戶由 <ph name="MANAGER_EMAIL" /> 管理</translation> -<translation id="3518604429872942239">狀態匣,時間 <ph name="TIME" />, +<translation id="3518604429872942239">狀態列,時間 <ph name="TIME" />, <ph name="BATTERY" /> <ph name="NETWORK" />, <ph name="MIC" />,
diff --git a/ash/strings/ash_strings_zu.xtb b/ash/strings/ash_strings_zu.xtb index 62240f3c..581a19e 100644 --- a/ash/strings/ash_strings_zu.xtb +++ b/ash/strings/ash_strings_zu.xtb
@@ -376,6 +376,7 @@ <translation id="3630697955794050612">valiwe</translation> <translation id="3631369015426612114">Vumela izaziso kusukela kokulandelayo</translation> <translation id="3638400994746983214">Guqula isikrini sobumfihlo. <ph name="STATE_TEXT" />.</translation> +<translation id="3640092422335864171">Londoloza okungu-<ph name="NAME" /></translation> <translation id="3649505501900178324">Isibuyekezo sesidlulelwe isikhathi</translation> <translation id="366222428570480733">U-<ph name="USER_EMAIL_ADDRESS" /> Yomsebenzisi ophethwe</translation> <translation id="3665889125180354336">Rekhoda imakrofoni</translation> @@ -458,6 +459,7 @@ <translation id="4215497585250573029">Izilungiselelo ze-VPN</translation> <translation id="4217571870635786043">Ukuthola</translation> <translation id="4221957499226645091">I-<ph name="APP_NAME" />, Uhlelo Lokusebenza Olufakiwe, Luphunyuziwe</translation> +<translation id="4223947355273782392">Londoloza u-<ph name="NAME" /> ku-<ph name="EMAIL" /> ukuhlanganisa ngokusheshayo kwamanye amadivayisi wakho</translation> <translation id="4239069858505860023">I-GPRS</translation> <translation id="4242533952199664413">Vula izilungiselelo</translation> <translation id="4250229828105606438">Isithombe-skrini</translation>
diff --git a/ash/system/phonehub/bluetooth_disabled_view.cc b/ash/system/phonehub/bluetooth_disabled_view.cc index 04a60ec2c..78c88e8e 100644 --- a/ash/system/phonehub/bluetooth_disabled_view.cc +++ b/ash/system/phonehub/bluetooth_disabled_view.cc
@@ -37,7 +37,6 @@ auto* content_view = AddChildView( std::make_unique<PhoneHubInterstitialView>(/*show_progress=*/false)); - // TODO(crbug.com/1127996): Replace PNG file with vector icon. gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_PHONE_HUB_ERROR_STATE_IMAGE);
diff --git a/ash/system/phonehub/onboarding_view.cc b/ash/system/phonehub/onboarding_view.cc index 8ea5d2b..e0de780 100644 --- a/ash/system/phonehub/onboarding_view.cc +++ b/ash/system/phonehub/onboarding_view.cc
@@ -67,7 +67,6 @@ private: void InitLayout() { - // TODO(crbug.com/1127996): Replace PNG file with vector icon. gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_PHONE_HUB_ONBOARDING_IMAGE);
diff --git a/ash/system/phonehub/phone_connecting_view.cc b/ash/system/phonehub/phone_connecting_view.cc index 246bef0..822fcc0a 100644 --- a/ash/system/phonehub/phone_connecting_view.cc +++ b/ash/system/phonehub/phone_connecting_view.cc
@@ -29,7 +29,6 @@ content_view_ = AddChildView( std::make_unique<PhoneHubInterstitialView>(/*show_progress=*/true)); - // TODO(crbug.com/1127996): Replace PNG file with vector icon. gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_PHONE_HUB_CONNECTING_IMAGE);
diff --git a/ash/system/phonehub/phone_disconnected_view.cc b/ash/system/phonehub/phone_disconnected_view.cc index f86cde7..b9775b2 100644 --- a/ash/system/phonehub/phone_disconnected_view.cc +++ b/ash/system/phonehub/phone_disconnected_view.cc
@@ -36,7 +36,6 @@ content_view_ = AddChildView(std::make_unique<PhoneHubInterstitialView>( /*show_progress=*/false)); - // TODO(crbug.com/1127996): Replace PNG file with vector icon. gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_PHONE_HUB_ERROR_STATE_IMAGE);
diff --git a/ash/system/phonehub/phone_hub_notification_controller.cc b/ash/system/phonehub/phone_hub_notification_controller.cc index 3c601da1..f7f1754 100644 --- a/ash/system/phonehub/phone_hub_notification_controller.cc +++ b/ash/system/phonehub/phone_hub_notification_controller.cc
@@ -8,11 +8,13 @@ #include "ash/components/phonehub/notification_interaction_handler.h" #include "ash/components/phonehub/phone_hub_manager.h" #include "ash/components/phonehub/phone_model.h" +#include "ash/constants/ash_features.h" #include "ash/public/cpp/notification_utils.h" #include "ash/public/cpp/system_tray_client.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" +#include "ash/system/message_center/ash_notification_view.h" #include "ash/system/message_center/message_view_factory.h" #include "ash/system/model/system_tray_model.h" #include "ash/system/phonehub/phone_hub_metrics.h" @@ -151,6 +153,100 @@ std::string custom_view_type_; }; +class PhoneHubAshNotificationView : public AshNotificationView { + public: + explicit PhoneHubAshNotificationView( + const message_center::Notification& notification, + bool shown_in_popup, + const std::u16string& phone_name) + : AshNotificationView(notification, shown_in_popup) { + // Add customized header. + message_center::NotificationHeaderView* header_row = + static_cast<message_center::NotificationHeaderView*>( + GetViewByID(message_center::NotificationView::kHeaderRow)); + views::View* app_name_view = + GetViewByID(message_center::NotificationView::kAppNameView); + views::Label* summary_text_view = static_cast<views::Label*>( + GetViewByID(message_center::NotificationView::kSummaryTextView)); + + // The app name should be displayed in full, leaving the rest of the space + // for device name. App name will only be truncated when it reached it + // maximum width. + int app_name_width = std::min(app_name_view->GetPreferredSize().width(), + kNotificationAppNameMaxWidth); + int device_name_width = kNotificationHeaderTextWidth - app_name_width; + header_row->SetSummaryText( + gfx::ElideText(phone_name, summary_text_view->font_list(), + device_name_width, gfx::ELIDE_TAIL)); + custom_view_type_ = notification.custom_view_type(); + if (custom_view_type_ == kNotificationCustomCallViewType) { + // Expand the action buttons row by default for Call Style notification. + SetManuallyExpandedOrCollapsed(true); + SetExpanded(true); + return; + } + action_buttons_row_ = + GetViewByID(message_center::NotificationView::kActionButtonsRow); + if (!action_buttons_row_->children().empty()) + reply_button_ = static_cast<views::View*>( + action_buttons_row_->children()[kReplyButtonIndex]); + + inline_reply_ = static_cast<message_center::NotificationInputContainer*>( + GetViewByID(message_center::NotificationView::kInlineReply)); + } + + ~PhoneHubAshNotificationView() override = default; + PhoneHubAshNotificationView(const PhoneHubAshNotificationView&) = delete; + PhoneHubAshNotificationView& operator=(const PhoneHubAshNotificationView&) = + delete; + + // message_center::NotificationViewBase + void ActionButtonPressed(size_t index, const ui::Event& event) override { + if (custom_view_type_ == kNotificationCustomCallViewType) { + message_center::MessageCenter::Get()->ClickOnNotificationButton( + notification_id(), static_cast<int>(index)); + } else { + AshNotificationView::ActionButtonPressed(index, event); + } + } + + // message_center::NotificationView: + void OnNotificationInputSubmit(size_t index, + const std::u16string& text) override { + AshNotificationView::OnNotificationInputSubmit(index, text); + + DCHECK(reply_button_); + + // After sending a reply, take the UI back to action buttons and clear out + // text input. + inline_reply_->SetVisible(false); + action_buttons_row_->SetVisible(true); + inline_reply_->textfield()->SetText(std::u16string()); + + // Briefly disable reply button. + reply_button_->SetEnabled(false); + enable_reply_timer_.Start( + FROM_HERE, kInlineReplyDisableTime, + base::BindOnce(&PhoneHubAshNotificationView::EnableReplyButton, + base::Unretained(this))); + } + + void EnableReplyButton() { + reply_button_->SetEnabled(true); + enable_reply_timer_.AbandonAndStop(); + } + + private: + // Owned by view hierarchy. + views::View* action_buttons_row_ = nullptr; + views::View* reply_button_ = nullptr; + message_center::NotificationInputContainer* inline_reply_ = nullptr; + + // Timer that fires to enable reply button after a brief period of time. + base::OneShotTimer enable_reply_timer_; + std::string custom_view_type_; +}; + } // namespace // Delegate for the displayed ChromeOS notification. @@ -628,6 +724,12 @@ const message_center::Notification& notification, bool shown_in_popup) { DCHECK(notification.custom_view_type() == kNotificationCustomViewType); + + if (features::IsNotificationsRefreshEnabled()) { + return std::make_unique<PhoneHubAshNotificationView>( + notification, shown_in_popup, + ash::GetPhoneName(notification_controller)); + } return std::make_unique<PhoneHubNotificationView>( notification, ash::GetPhoneName(notification_controller)); } @@ -639,6 +741,12 @@ const message_center::Notification& notification, bool shown_in_popup) { DCHECK(notification.custom_view_type() == kNotificationCustomCallViewType); + + if (features::IsNotificationsRefreshEnabled()) { + return std::make_unique<PhoneHubAshNotificationView>( + notification, shown_in_popup, + ash::GetPhoneName(notification_controller)); + } return std::make_unique<PhoneHubNotificationView>( notification, ash::GetPhoneName(notification_controller)); }
diff --git a/ash/system/phonehub/tether_connection_pending_view.cc b/ash/system/phonehub/tether_connection_pending_view.cc index 58365a11e..3ee16a0 100644 --- a/ash/system/phonehub/tether_connection_pending_view.cc +++ b/ash/system/phonehub/tether_connection_pending_view.cc
@@ -29,7 +29,6 @@ content_view_ = AddChildView( std::make_unique<PhoneHubInterstitialView>(/*show_progress=*/true)); - // TODO(crbug.com/1127996): Replace PNG file with vector icon. gfx::ImageSkia* image = ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_PHONE_HUB_CONNECTING_IMAGE);
diff --git a/ash/test/ash_test_suite.cc b/ash/test/ash_test_suite.cc index 93ed86a..ea9d126d 100644 --- a/ash/test/ash_test_suite.cc +++ b/ash/test/ash_test_suite.cc
@@ -16,6 +16,7 @@ #include "ui/display/display_switches.h" #include "ui/gl/gl_switches.h" #include "ui/gl/test/gl_surface_test_support.h" +#include "ui/lottie/resource.h" namespace ash { @@ -40,6 +41,9 @@ // it'll pass regardless of the system language. base::i18n::SetICUDefaultLocale("en_US"); + ui::ResourceBundle::SetParseLottieAsStillImage( + &lottie::ParseLottieAsStillImage); + // Load ash test resources and en-US strings; not 'common' (Chrome) resources. base::FilePath path; base::PathService::Get(base::DIR_MODULE, &path);
diff --git a/ash/webui/camera_app_ui/resources.h b/ash/webui/camera_app_ui/resources.h index 3657510b..34535b2 100644 --- a/ash/webui/camera_app_ui/resources.h +++ b/ash/webui/camera_app_ui/resources.h
@@ -109,6 +109,14 @@ {"label_timer_3s", IDS_LABEL_TIMER_3S}, {"label_video_resolution", IDS_LABEL_VIDEO_RESOLUTION}, {"migrate_pictures_msg", IDS_MIGRATE_PICTURES_MSG}, + {"moving_in_bottom_direction", IDS_MOVING_IN_BOTTOM_DIRECTION}, + {"moving_in_bottom_left_direction", IDS_MOVING_IN_BOTTOM_LEFT_DIRECTION}, + {"moving_in_bottom_right_direction", IDS_MOVING_IN_BOTTOM_RIGHT_DIRECTION}, + {"moving_in_left_direction", IDS_MOVING_IN_LEFT_DIRECTION}, + {"moving_in_right_direction", IDS_MOVING_IN_RIGHT_DIRECTION}, + {"moving_in_top_direction", IDS_MOVING_IN_TOP_DIRECTION}, + {"moving_in_top_left_direction", IDS_MOVING_IN_TOP_LEFT_DIRECTION}, + {"moving_in_top_right_direction", IDS_MOVING_IN_TOP_RIGHT_DIRECTION}, {"msg_document_detected", IDS_MSG_DOCUMENT_DETECTED}, {"msg_processing_image", IDS_MSG_PROCESSING_IMAGE}, {"name", IDS_NAME},
diff --git a/ash/webui/camera_app_ui/resources/js/i18n_string.js b/ash/webui/camera_app_ui/resources/js/i18n_string.js index 52d75fbb..68c9149 100644 --- a/ash/webui/camera_app_ui/resources/js/i18n_string.js +++ b/ash/webui/camera_app_ui/resources/js/i18n_string.js
@@ -98,6 +98,14 @@ LABEL_TIMER_3S: 'label_timer_3s', LABEL_VIDEO_RESOLUTION: 'label_video_resolution', MIGRATE_PICTURES_MSG: 'migrate_pictures_msg', + MOVING_IN_BOTTOM_DIRECTION: 'moving_in_bottom_direction', + MOVING_IN_BOTTOM_LEFT_DIRECTION: 'moving_in_bottom_left_direction', + MOVING_IN_BOTTOM_RIGHT_DIRECTION: 'moving_in_bottom_right_direction', + MOVING_IN_LEFT_DIRECTION: 'moving_in_left_direction', + MOVING_IN_RIGHT_DIRECTION: 'moving_in_right_direction', + MOVING_IN_TOP_DIRECTION: 'moving_in_top_direction', + MOVING_IN_TOP_LEFT_DIRECTION: 'moving_in_top_left_direction', + MOVING_IN_TOP_RIGHT_DIRECTION: 'moving_in_top_right_direction', MSG_DOCUMENT_DETECTED: 'msg_document_detected', MSG_PROCESSING_IMAGE: 'msg_processing_image', NAME: 'name',
diff --git a/ash/webui/camera_app_ui/resources/js/toast.js b/ash/webui/camera_app_ui/resources/js/toast.js index 4dd7b074..d0ff0c9 100644 --- a/ash/webui/camera_app_ui/resources/js/toast.js +++ b/ash/webui/camera_app_ui/resources/js/toast.js
@@ -22,7 +22,10 @@ element.classList.toggle('spoken', spoken); if (!spoken) { - animate.play(element); + element.setAttribute('aria-hidden', 'false'); + animate.play(element).finally(() => { + element.setAttribute('aria-hidden', 'true'); + }); } }
diff --git a/ash/webui/camera_app_ui/resources/js/util.js b/ash/webui/camera_app_ui/resources/js/util.js index 67367bde6..f2855bf5 100644 --- a/ash/webui/camera_app_ui/resources/js/util.js +++ b/ash/webui/camera_app_ui/resources/js/util.js
@@ -275,10 +275,10 @@ * @private */ this.delayTimeoutId_ = setTimeout(() => { - callback(); this.intervalId_ = setInterval(() => { callback(); }, intervalMs); + callback(); }, delayMs); }
diff --git a/ash/webui/camera_app_ui/resources/js/views/crop_document.js b/ash/webui/camera_app_ui/resources/js/views/crop_document.js index d9aaea50..6ebb9bf 100644 --- a/ash/webui/camera_app_ui/resources/js/views/crop_document.js +++ b/ash/webui/camera_app_ui/resources/js/views/crop_document.js
@@ -6,12 +6,114 @@ import * as dom from '../dom.js'; import {Box, Line, Point, Size, Vector, vectorFromPoints} from '../geometry.js'; import {I18nString} from '../i18n_string.js'; +import {speak} from '../toast.js'; import {Rotation, ViewName} from '../type.js'; import * as util from '../util.js'; import {Option, Options, Review} from './review.js'; /** + * Delay for movement announcer gathering user pressed key to announce first + * feedback in milliseconds. + */ +const MOVEMENT_ANNOUNCER_START_DELAY_MS = 500; + +/** + * Interval for movement announcer to announce next movement. + */ +const MOVEMENT_ANNOUNCER_INTERVAL_MS = 2000; + +/** + * Maps from sign of x, y movement to corresponding i18n labels to be announced. + * @type {!Map<number, !Map<number, I18nString>>} + */ +const MOVEMENT_ANNOUNCE_LABELS = new Map([ + [ + -1, + new Map([ + [-1, I18nString.MOVING_IN_TOP_LEFT_DIRECTION], + [0, I18nString.MOVING_IN_LEFT_DIRECTION], + [1, I18nString.MOVING_IN_BOTTOM_LEFT_DIRECTION], + ]), + ], + [ + 0, + new Map([ + [-1, I18nString.MOVING_IN_TOP_DIRECTION], + [1, I18nString.MOVING_IN_BOTTOM_DIRECTION], + ]), + ], + [ + 1, + new Map([ + [-1, I18nString.MOVING_IN_TOP_RIGHT_DIRECTION], + [0, I18nString.MOVING_IN_RIGHT_DIRECTION], + [1, I18nString.MOVING_IN_BOTTOM_RIGHT_DIRECTION], + ]), + ], +]); + +/** + * Announces the movement direction of document corner with screen reader. + */ +class MovementAnnouncer { + /** + * @public + */ + constructor() { + /** + * Interval to throttle the consecutive announcement. + * @type {?util.DelayInterval} + * @private + */ + this.announceInterval_ = null; + + /** + * X component of last not announced movement. + * @type {number} + * @private + */ + this.lastXMovement_ = 0; + + /** + * Y component of last not announced movement. + * @type {number} + * @private + */ + this.lastYMovement_ = 0; + } + + /** + * @param {number} dx + * @param {number} dy + */ + updateMovement(dx, dy) { + this.lastXMovement_ = dx; + this.lastYMovement_ = dy; + if (this.announceInterval_ === null) { + this.announceInterval_ = new util.DelayInterval(() => { + this.announce_(); + }, MOVEMENT_ANNOUNCER_START_DELAY_MS, MOVEMENT_ANNOUNCER_INTERVAL_MS); + } + } + + /** + * @private + */ + announce_() { + if (this.lastXMovement_ === 0 && this.lastYMovement_ === 0) { + this.announceInterval_.stop(); + this.announceInterval_ = null; + return; + } + const signX = Math.sign(this.lastXMovement_); + const signY = Math.sign(this.lastYMovement_); + speak(MOVEMENT_ANNOUNCE_LABELS.get(signX).get(signY)); + this.lastXMovement_ = this.lastYMovement_ = 0; + } +} + +/** * The closest distance ratio with respect to corner space size. The dragging * corner should not be closer to the 3 lines formed by another 3 corners than * this ratio times scale of corner space size. @@ -163,19 +265,16 @@ new Vector(0, 1), new Vector(1, 0), ]; - /** - * Maps from key index in |KEYS| to corresponding movement handler. - * @type {!Map<number, function()>} - */ - const keyHandlers = new Map(); + const pressedKeyIndices = new Set(); let keyInterval = null; const clearKeydown = () => { if (keyInterval !== null) { keyInterval.stop(); keyInterval = null; } - keyHandlers.clear(); + pressedKeyIndices.clear(); }; + const announcer = new MovementAnnouncer(); corn.el.addEventListener('blur', (e) => { clearKeydown(); @@ -183,13 +282,25 @@ corn.el.addEventListener('keydown', (e) => { const keyIdx = getKeyIndex(e); - if (keyIdx === -1 || keyHandlers.has(keyIdx)) { + if (keyIdx === -1 || pressedKeyIndices.has(keyIdx)) { return; } - const movement = KEY_MOVEMENTS[(keyIdx + this.rotation_) % 4]; const move = () => { + let announceMoveX = 0; + let announceMoveY = 0; + let moveX = 0; + let moveY = 0; + for (const keyIdx of pressedKeyIndices) { + const announceMoveXY = KEY_MOVEMENTS[keyIdx]; + announceMoveX += announceMoveXY.x; + announceMoveY += announceMoveXY.y; + const moveXY = KEY_MOVEMENTS[(keyIdx + this.rotation_) % 4]; + moveX += moveXY.x; + moveY += moveXY.y; + } + announcer.updateMovement(announceMoveX, announceMoveY); const {x: curX, y: curY} = corn.pt; - const nextPt = new Point(curX + movement.x, curY + movement.y); + const nextPt = new Point(curX + moveX, curY + moveY); const validPt = this.mapToValidArea_(corn, nextPt); if (validPt === null) { return; @@ -197,14 +308,14 @@ corn.pt = validPt; this.updateCornerEl_(); }; + pressedKeyIndices.add(keyIdx); move(); - keyHandlers.set(keyIdx, move); if (keyInterval === null) { const PRESS_TIMEOUT = 500; const HOLD_INTERVAL = 100; keyInterval = new util.DelayInterval(() => { - keyHandlers.forEach((handler) => handler()); + move(); }, PRESS_TIMEOUT, HOLD_INTERVAL); } }); @@ -214,8 +325,8 @@ if (keyIdx === -1) { return; } - keyHandlers.delete(keyIdx); - if (keyHandlers.size === 0) { + pressedKeyIndices.delete(keyIdx); + if (pressedKeyIndices.size === 0) { clearKeydown(); } });
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings.grd b/ash/webui/camera_app_ui/resources/strings/camera_strings.grd index ae07550..3a8c790e 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings.grd +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings.grd
@@ -562,6 +562,30 @@ <message desc="Description read by screen reader for moving document corner with arrow key" name="IDS_DOCUMENT_CORNER_MOVE_DESC"> Move corner position with arrow keys </message> + <message desc="Message read by screen reader that document corner is moving in top direction" name="IDS_MOVING_IN_TOP_DIRECTION"> + Moving in top direction + </message> + <message desc="Message read by screen reader that document corner is moving in bottom direction" name="IDS_MOVING_IN_BOTTOM_DIRECTION"> + Moving in bottom direction + </message> + <message desc="Message read by screen reader that document corner is moving in left direction" name="IDS_MOVING_IN_LEFT_DIRECTION"> + Moving in left direction + </message> + <message desc="Message read by screen reader that document corner is moving in right direction" name="IDS_MOVING_IN_RIGHT_DIRECTION"> + Moving in right direction + </message> + <message desc="Message read by screen reader that document corner is moving in top-left direction" name="IDS_MOVING_IN_TOP_LEFT_DIRECTION"> + Moving in top-left direction + </message> + <message desc="Message read by screen reader that document corner is moving in top-right direction" name="IDS_MOVING_IN_TOP_RIGHT_DIRECTION"> + Moving in top-right direction + </message> + <message desc="Message read by screen reader that document corner is moving in bottom-left direction" name="IDS_MOVING_IN_BOTTOM_LEFT_DIRECTION"> + Moving in bottom-left direction + </message> + <message desc="Message read by screen reader that document corner is moving in bottom-right direction" name="IDS_MOVING_IN_BOTTOM_RIGHT_DIRECTION"> + Moving in bottom-right direction + </message> <message desc="Label for button for rotating document 90 degrees in clockwise direction" name="IDS_ROTATE_CLOCKWISE_BUTTON"> Rotate 90 degrees clockwise </message>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_am.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_am.xtb index dcd74cb..8d2ead7 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_am.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_am.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">የቁም ፎቶን ማንሳት አልተቻለም</translation> <translation id="3569311554794739032">እርግጠኛ ነዎት <ph name="FILE" />ን ማስወገድ ይፈልጋሉ?</translation> <translation id="3573890771273113519">ወደ የቅኝት ሁነታ ቀይር</translation> +<translation id="3583444040776960729">የሰነድ ከታች-ግራ ጥግ</translation> <translation id="3789724198583203151">90 ዲግሪ በሰዓት ተቃራኒ አቅጣጫ አሽከርክር</translation> <translation id="3810838688059735925">ቪዲዮ</translation> <translation id="3838931309141338733">የአሞሌ ኮድ ይቃኙ</translation> @@ -77,6 +78,7 @@ ካሜራው በትክክል ተገናኝቶ ከሆነ እባክዎ ይፈትሹ።</translation> <translation id="5152121255775685072">ወደ ማዕከለ-ሥዕላት ሂድ</translation> <translation id="520537883758714667">የሰነድ ቅኝት አሁን ይገኛል</translation> +<translation id="5266635337630551423">የሰነድ ከላይ-ግራ ጥግ</translation> <translation id="5317780077021120954">አስቀምጥ</translation> <translation id="5444515100983837161">የሰነዱን ሁሉንም ጠርዞች በክፈፉ ውስጥ ያስቀምጡ። ሰነዱ እና ዳራ የተለያዩ ቀለሞች ከሆኑ ቅኝት በተሻለ ሁኔታ ይሠራል።</translation> <translation id="5671277269877808209">ካሬ</translation> @@ -96,6 +98,7 @@ የእርስዎ ግብረመልስ ስለምስል ወይም ቪዲዮ ጥራት ከሆነ እባክዎ ናሙና ፎቶ ወይም ቪዲዮ ያያይዙ እና ምን ችግር እንዳለበት ያብራሩ። (ለምሳሌ፣ ፎቶ በጣም ጨለማ ነው ወይም የፎቶው ዋና አካል በትኩረት ላይ አይደለም።)</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> ሜጋ ፒክሴል</translation> <translation id="6527303717912515753">አጋራ</translation> +<translation id="6652737148136672975">የማዕዘን ቦታን በቀስት ቁልፎች አማካኝነት ያንቀሳቅሱ</translation> <translation id="667999046851023355">ሰነድ</translation> <translation id="6681668084120808868">ፎቶ አንሳ</translation> <translation id="6778482348691154169">ፎቶ ለማንሳት አልተቻለም</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">እገዛ</translation> <translation id="7658239707568436148">ይቅር</translation> <translation id="7670511624014457267">60 FPS</translation> +<translation id="7671804233658741790">የሰነድ ከታች-ቀኝ ጥግ</translation> <translation id="7726641833034062494">መደበኛ ቪዲዮን ይቅረጹ</translation> +<translation id="7748344063862150053">የሰነድ ከላይ-ቀኝ ጥግ</translation> <translation id="7983668134180549431">ጽሑፍ ተገኝቷል።</translation> <translation id="8067883171444229417">ቪዲዮ አጫውት</translation> <translation id="8120146556401698679">ማንፏቀቅ- ማጋደል-አጉላ/አሳንስ</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_as.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_as.xtb index 7892321f..116f4677 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_as.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_as.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">প’ৰ্ট্ৰেইট ফট’ ল’ব নোৱাৰিলে</translation> <translation id="3569311554794739032">আপুনি সঁচাকৈয়ে <ph name="FILE" /> আঁতৰাবলৈ বিচাৰে বুলি নিশ্চিতনে?</translation> <translation id="3573890771273113519">স্কেন ম’ডলৈ সলনি কৰক</translation> +<translation id="3583444040776960729">নথিৰ একেবাৰে তলৰ বাওঁফালৰ চুক</translation> <translation id="3789724198583203151">ঘড়ীৰ কাঁটাৰ বিপৰীত দিশত ৯০ ডিগ্ৰী ঘূৰাওক</translation> <translation id="3810838688059735925">ভিডিঅ’</translation> <translation id="3838931309141338733">বাৰক’ড স্কেন কৰক</translation> @@ -77,6 +78,7 @@ অনুগ্ৰহ কৰি কেমেৰাটো সঠিক ধৰণে সংযুক্ত হৈ আছেনে নাই পৰীক্ষা কৰক।</translation> <translation id="5152121255775685072">গেলাৰীলৈ যাওক</translation> <translation id="520537883758714667">এতিয়া নথি স্কেন কৰাৰ সুবিধাটো উপলব্ধ</translation> +<translation id="5266635337630551423">নথিৰ একেবাৰে ওপৰৰ বাওঁফালৰ চুক</translation> <translation id="5317780077021120954">ছেভ কৰক</translation> <translation id="5444515100983837161">নথিখনৰ আটাইকেইটা কাষ ফ্ৰে’মটোৰ ভিতৰত ৰাখক। নথিখনৰ সৈতে নেপথ্যৰ ৰঙটো পৃথক হ’লে স্কেন কৰাৰ সুবিধাটোৱে আটাইতকৈ ভালকৈ কৰে।</translation> <translation id="5671277269877808209">বৰ্গাকাৰ</translation> @@ -96,6 +98,7 @@ যদি আপোনাৰ মতামতটো প্ৰতিচ্ছবি অথবা ভিডিঅ’ৰ গুণগত মান সম্পৰ্কীয়, অনুগ্ৰহ কৰি নমুনা হিচাপে এখন ফট’ অথবা এটা ভিডিঅ’ সংলগ্ন কৰক আৰু কি সমস্যা হৈছে বৰ্ণনা কৰক। (উদাহৰণস্বৰূপে, ফট’খন বহুত ক’লা হৈছে অথবা মূল বস্তুটো ফ’কাছত নাই।)</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> মেগা পিক্সেল</translation> <translation id="6527303717912515753">শ্বেয়াৰ কৰক</translation> +<translation id="6652737148136672975">এৰ’ কীসমূহৰ জৰিয়তে চুকৰ স্থান সলনি কৰক</translation> <translation id="667999046851023355">নথি</translation> <translation id="6681668084120808868">ফট’ তোলক</translation> <translation id="6778482348691154169">ফট' ল'ব নোৱাৰি</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">সহায়</translation> <translation id="7658239707568436148">বাতিল কৰক</translation> <translation id="7670511624014457267">৬০ FPS</translation> +<translation id="7671804233658741790">নথিৰ একেবাৰে তলৰ সোঁফালৰ চুক</translation> <translation id="7726641833034062494">সাধাৰণ ভিডিঅ’ ৰেকৰ্ড কৰক</translation> +<translation id="7748344063862150053">নথিৰ একেবাৰে ওপৰৰ সোঁফালৰ চুক</translation> <translation id="7983668134180549431">পাঠ চিনাক্ত কৰা হৈছে।</translation> <translation id="8067883171444229417">ভিডিঅ’ প্লে কৰক</translation> <translation id="8120146556401698679">পেন কৰা, হেলনীয়া কৰা, জুম কৰা</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_bn.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_bn.xtb index fa4340c..31bb729 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_bn.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_bn.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">পোর্ট্রেট ফটো তোলা যাচ্ছে না</translation> <translation id="3569311554794739032">আপনি কি সত্যিই <ph name="FILE" /> সরাতে চান?</translation> <translation id="3573890771273113519">স্ক্যান মোডে বদল করুন</translation> +<translation id="3583444040776960729">নিচে-বাঁদিকের কোণার ডকুমেন্ট</translation> <translation id="3789724198583203151">ঘড়ির কাঁটার বিপরীতে ৯০ ডিগ্রি ঘোরান</translation> <translation id="3810838688059735925">ভিডিও</translation> <translation id="3838931309141338733">বারকোড স্ক্যান করুন</translation> @@ -77,6 +78,7 @@ ক্যামেরা ঠিকভাবে কানেক্ট করা আছে কিনা দেখুন।</translation> <translation id="5152121255775685072">গ্যালারিতে যান</translation> <translation id="520537883758714667">এখন ডকুমেন্ট স্ক্যান করা উপলভ্য</translation> +<translation id="5266635337630551423">উপরে-বাঁদিকের কোণার ডকুমেন্ট</translation> <translation id="5317780077021120954">সেভ করুন</translation> <translation id="5444515100983837161">ডকুমেন্টের সমস্ত প্রান্ত ফ্রেমের মধ্যে রাখুন। ডকুমেন্ট ও ব্যাকগ্রাউন্ডের রং আলাদা হলে, স্ক্যানিং সবচেয়ে ভাল কাজ করে।</translation> <translation id="5671277269877808209">চৌকো</translation> @@ -96,6 +98,7 @@ যদি আপনি কোনও ছবি বা ভিডিওর কোয়ালিটির ব্যাপারে মতামত জানাতে চান, তাহলে উদাহরণস্বরূপ একটি ফটো বা ভিডিও এখানে অ্যাটাচ করুন এবং আমাদের জানান সেটিতে কোন বিষয়টি আপনার খারাপ লেগেছে। (যেমন, ফটোতে পর্যাপ্ত আলোর অভাব রয়েছে বা যার ফটো তোলা হয়েছে, তাকে ফোকাসে রেখে ফটোটি তোলা হয়নি।)</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> মেগা পিক্সেল</translation> <translation id="6527303717912515753">শেয়ার করুন</translation> +<translation id="6652737148136672975">অ্যারো কী ব্যবহার করে কোণার অবস্থান সরান</translation> <translation id="667999046851023355">দস্তাবেজ</translation> <translation id="6681668084120808868">ফটো তুলুন</translation> <translation id="6778482348691154169">ফটো তোলা যাচ্ছে না</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">সহায়তা</translation> <translation id="7658239707568436148">বাতিল</translation> <translation id="7670511624014457267">৬০ FPS</translation> +<translation id="7671804233658741790">নিচে-ডানদিকের কোণার ডকুমেন্ট</translation> <translation id="7726641833034062494">নর্মাল ভিডিও রেকর্ড করুন</translation> +<translation id="7748344063862150053">উপরে-ডানদিকের কোণার ডকুমেন্ট</translation> <translation id="7983668134180549431">টেক্সট শনাক্ত করা গেছে।</translation> <translation id="8067883171444229417">ভিডিও চালানোর বোতাম</translation> <translation id="8120146556401698679">প্যান টিল্ট জুম</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_el.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_el.xtb index 57f8f47..319e4116 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_el.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_el.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">Δεν είναι δυνατή η λήψη φωτογραφίας πορτραίτου.</translation> <translation id="3569311554794739032">Είστε βέβαιοι ότι θέλετε να καταργήσετε το αρχείο <ph name="FILE" />;</translation> <translation id="3573890771273113519">Αλλαγή σε λειτουργία σάρωσης</translation> +<translation id="3583444040776960729">Κάτω αριστερή γωνία του εγγράφου</translation> <translation id="3789724198583203151">Περιστροφή 90 μοιρών αριστερόστροφα</translation> <translation id="3810838688059735925">Βίντεο</translation> <translation id="3838931309141338733">Σάρωση γραμμωτού κώδικα</translation> @@ -77,6 +78,7 @@ Ελέγξτε εάν η κάμερα έχει συνδεθεί σωστά.</translation> <translation id="5152121255775685072">Μετάβαση στο gallery</translation> <translation id="520537883758714667">Η σάρωση εγγράφων είναι πλέον διαθέσιμη</translation> +<translation id="5266635337630551423">Επάνω αριστερή γωνία του εγγράφου</translation> <translation id="5317780077021120954">Αποθήκευση</translation> <translation id="5444515100983837161">Τοποθετήστε όλες τις άκρες του εγγράφου μέσα στο πλαίσιο. Η σάρωση λειτουργεί καλύτερα εάν το έγγραφο και το φόντο έχουν διαφορετικά χρώματα.</translation> <translation id="5671277269877808209">Τετράγωνο</translation> @@ -96,6 +98,7 @@ Εάν τα σχόλιά σας αφορούν την ποιότητα φωτογραφίας ή βίντεο, επισυνάψτε ένα δείγμα εικόνας ή βίντεο και περιγράψτε το πρόβλημα. (Για παράδειγμα, η φωτογραφία είναι υπερβολικά σκοτεινή ή δεν είναι εστιασμένο το θέμα.)</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> megapixel</translation> <translation id="6527303717912515753">Κοινοποίηση</translation> +<translation id="6652737148136672975">Μετακινήστε τη θέση της γωνίας με τα πλήκτρα βέλους</translation> <translation id="667999046851023355">Έγγραφο</translation> <translation id="6681668084120808868">Λήψη φωτογραφίας</translation> <translation id="6778482348691154169">Δεν είναι δυνατή η λήψη φωτογραφίας</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">Βοήθεια</translation> <translation id="7658239707568436148">Ακύρωση</translation> <translation id="7670511624014457267">60 καρέ ανά δευτερόλεπτο</translation> +<translation id="7671804233658741790">Κάτω δεξιά γωνία του εγγράφου</translation> <translation id="7726641833034062494">Εγγραφή κανονικού βίντεο</translation> +<translation id="7748344063862150053">Επάνω δεξιά γωνία του εγγράφου</translation> <translation id="7983668134180549431">Εντοπίστηκε κείμενο.</translation> <translation id="8067883171444229417">Αναπαραγωγή βίντεο</translation> <translation id="8120146556401698679">Μετακίνηση, κλίση και εστίαση</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_eu.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_eu.xtb index 9ee14e2..7beddfb6 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_eu.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_eu.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">Ezin da atera erretratu-argazkia</translation> <translation id="3569311554794739032">Ziur zaude <ph name="FILE" /> kendu nahi duzula?</translation> <translation id="3573890771273113519">Aldatu bilatzeko modura</translation> +<translation id="3583444040776960729">Dokumentuaren beheko ezkerraldeko ertza</translation> <translation id="3789724198583203151">Biratu 90 gradu ezkerretara</translation> <translation id="3810838688059735925">Bideoa</translation> <translation id="3838931309141338733">Eskaneatu barra-kodea</translation> @@ -77,6 +78,7 @@ Egiaztatu kamera ongi konektatuta dagoela.</translation> <translation id="5152121255775685072">Joan galeriara</translation> <translation id="520537883758714667">Dokumentuak eskaneatzeko eginbidea eskuragarri dago</translation> +<translation id="5266635337630551423">Dokumentuaren goiko ezkerraldeko ertza</translation> <translation id="5317780077021120954">Gorde</translation> <translation id="5444515100983837161">Jarri dokumentuaren ertz guztiak markoaren barruan. Hobeto eskaneatzen da dokumentuaren eta hondoaren koloreak ezberdinak badira.</translation> <translation id="5671277269877808209">Karratua</translation> @@ -96,6 +98,7 @@ Irudi edo bideoaren kalitateari buruzko iritzia eman nahi baduzu, erantsi argazki edo bideo bat lagin gisa eta azal iezaguzu zein den arazoa (adibidez, argazkia ilunegia da edo subjektua ez dago fokuratuta).</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" /> × <ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> megapixel</translation> <translation id="6527303717912515753">Partekatu</translation> +<translation id="6652737148136672975">Mugitu ertzaren kokapena gezi-teklak erabilita</translation> <translation id="667999046851023355">Dokumentua</translation> <translation id="6681668084120808868">Atera argazkia</translation> <translation id="6778482348691154169">Ezin da atera argazkia</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">Laguntza</translation> <translation id="7658239707568436148">Utzi</translation> <translation id="7670511624014457267">60 f/s</translation> +<translation id="7671804233658741790">Dokumentuaren beheko eskuinaldeko ertza</translation> <translation id="7726641833034062494">Grabatu bideo normal bat</translation> +<translation id="7748344063862150053">Dokumentuaren goiko eskuinaldeko ertza</translation> <translation id="7983668134180549431">Testua hauteman da.</translation> <translation id="8067883171444229417">Erreproduzitu bideoa</translation> <translation id="8120146556401698679">Mugitu, okertu, zooma</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_fa.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_fa.xtb index 7a24138..3676c29 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_fa.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_fa.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">عکس عمودی ممکن نیست</translation> <translation id="3569311554794739032">واقعاً میخواهید <ph name="FILE" /> را بردارید؟</translation> <translation id="3573890771273113519">رفتن به حالت اسکن</translation> +<translation id="3583444040776960729">گوشه پایین سمت چپ سند</translation> <translation id="3789724198583203151">چرخش ۹۰ درجه پادساعتگرد</translation> <translation id="3810838688059735925">فیلم</translation> <translation id="3838931309141338733">اسکن بارکد</translation> @@ -77,6 +78,7 @@ مطمئن شوید دوربین درست وصل شده باشد.</translation> <translation id="5152121255775685072">رفتن به گالری</translation> <translation id="520537883758714667">اسکن سند اکنون دردسترس است</translation> +<translation id="5266635337630551423">گوشه بالا سمت چپ سند</translation> <translation id="5317780077021120954">ذخیره</translation> <translation id="5444515100983837161">همه لبههای سند را داخل قاب قرار دهید. اسکن بهترین عملکرد را زمانی دارد که رنگ سند و پسزمینه متفاوت باشد.</translation> <translation id="5671277269877808209">مربع</translation> @@ -96,6 +98,7 @@ اگر بازخوردتان درباره کیفیت تصویر یا ویدیو است، لطفاً نمونهای از عکس یا ویدیو را ضمیمه کنید و مشکل را توضیح دهید. (برای مثال، عکس خیلی تیره است یا روی سوژه موردنظر فوکوس نشده است.)</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> مگاپیکسل</translation> <translation id="6527303717912515753">اشتراکگذاری</translation> +<translation id="6652737148136672975">موقعیت گوشه را بااستفاده از کلیدهای جهتنما تغییر دهید</translation> <translation id="667999046851023355">سند</translation> <translation id="6681668084120808868">عکسبرداری</translation> <translation id="6778482348691154169">عکسبرداری انجام نشد</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">راهنما</translation> <translation id="7658239707568436148">لغو</translation> <translation id="7670511624014457267">60 FPS</translation> +<translation id="7671804233658741790">گوشه پایین سمت راست سند</translation> <translation id="7726641833034062494">ضبط ویدیوی معمولی</translation> +<translation id="7748344063862150053">گوشه بالا سمت راست سند</translation> <translation id="7983668134180549431">نوشتار شناسایی شد.</translation> <translation id="8067883171444229417">پخش ویدیو</translation> <translation id="8120146556401698679">حرکت دادن، کج کردن، بزرگنمایی</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_BOTTOM_DIRECTION.png.sha1 b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_BOTTOM_DIRECTION.png.sha1 new file mode 100644 index 0000000..fd0e195 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_BOTTOM_DIRECTION.png.sha1
@@ -0,0 +1 @@ +8fb75b76e78926316dfc8a41af91f7f035a04c28 \ No newline at end of file
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_BOTTOM_LEFT_DIRECTION.png.sha1 b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_BOTTOM_LEFT_DIRECTION.png.sha1 new file mode 100644 index 0000000..4d19ef6 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_BOTTOM_LEFT_DIRECTION.png.sha1
@@ -0,0 +1 @@ +b613bcd7d447cd4fb62a335e7dcf23ad71010388 \ No newline at end of file
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_BOTTOM_RIGHT_DIRECTION.png.sha1 b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_BOTTOM_RIGHT_DIRECTION.png.sha1 new file mode 100644 index 0000000..c5d14e3 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_BOTTOM_RIGHT_DIRECTION.png.sha1
@@ -0,0 +1 @@ +419a763d38200584f6dcc737d0fb3612677716ce \ No newline at end of file
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_LEFT_DIRECTION.png.sha1 b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_LEFT_DIRECTION.png.sha1 new file mode 100644 index 0000000..ec42895 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_LEFT_DIRECTION.png.sha1
@@ -0,0 +1 @@ +c32865e7cc3a87d3290f8e9b70ab23ee2dc94b8c \ No newline at end of file
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_RIGHT_DIRECTION.png.sha1 b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_RIGHT_DIRECTION.png.sha1 new file mode 100644 index 0000000..f02d13e --- /dev/null +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_RIGHT_DIRECTION.png.sha1
@@ -0,0 +1 @@ +e5bceb24d41cc39416b0bf34bf98df1dbf78c49a \ No newline at end of file
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_TOP_DIRECTION.png.sha1 b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_TOP_DIRECTION.png.sha1 new file mode 100644 index 0000000..2d685bc --- /dev/null +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_TOP_DIRECTION.png.sha1
@@ -0,0 +1 @@ +096602e72de477944bc7f2bd9fecf7e1fac13d7a \ No newline at end of file
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_TOP_LEFT_DIRECTION.png.sha1 b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_TOP_LEFT_DIRECTION.png.sha1 new file mode 100644 index 0000000..efdffa9 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_TOP_LEFT_DIRECTION.png.sha1
@@ -0,0 +1 @@ +1220fa82b12ad3a347fdad328dfcc82f01d5779b \ No newline at end of file
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_TOP_RIGHT_DIRECTION.png.sha1 b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_TOP_RIGHT_DIRECTION.png.sha1 new file mode 100644 index 0000000..ad37d224 --- /dev/null +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_grd/IDS_MOVING_IN_TOP_RIGHT_DIRECTION.png.sha1
@@ -0,0 +1 @@ +c208618526125f6a99cacf5f1dbe3c43a57b9993 \ No newline at end of file
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_hr.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_hr.xtb index 5d86bd9..5d57e72 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_hr.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_hr.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">Snimanje portretne fotografije nije uspjelo</translation> <translation id="3569311554794739032">Želite li doista ukloniti datoteku <ph name="FILE" />?</translation> <translation id="3573890771273113519">Prijeđi na način skeniranja</translation> +<translation id="3583444040776960729">Donji lijevi kut dokumenta</translation> <translation id="3789724198583203151">Zakreni za 90 stupnjeva suprotno od smjera kazaljke na satu</translation> <translation id="3810838688059735925">Video</translation> <translation id="3838931309141338733">Skenirajte crtični kôd</translation> @@ -77,6 +78,7 @@ Provjerite je li fotoaparat pravilno povezan.</translation> <translation id="5152121255775685072">Otvori galeriju</translation> <translation id="520537883758714667">Sad je dostupno skeniranje dokumenata</translation> +<translation id="5266635337630551423">Gornji lijevi kut dokumenta</translation> <translation id="5317780077021120954">Spremi</translation> <translation id="5444515100983837161">Postavite sve rubove dokumenta unutar okvira. Skeniranje najbolje funkcionira ako su dokument i pozadina različitih boja.</translation> <translation id="5671277269877808209">Kvadrat</translation> @@ -96,6 +98,7 @@ Ako su vaše povratne informacije o kvaliteti slika ili videozapisa, priložite primjer fotografije ili videozapisa i opišite što nije u redu. (Na primjer, fotografija je pretamna ili objekt nije fokusiran.)</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> megapiksel</translation> <translation id="6527303717912515753">Podijeli</translation> +<translation id="6652737148136672975">Položaj kuta pomičite pomoću tipki sa strelicama</translation> <translation id="667999046851023355">Dokument</translation> <translation id="6681668084120808868">Snimite fotografiju</translation> <translation id="6778482348691154169">Snimanje fotografije nije uspjelo</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">Pomoć</translation> <translation id="7658239707568436148">Odustani</translation> <translation id="7670511624014457267">60 okv/s</translation> +<translation id="7671804233658741790">Donji desni kut dokumenta</translation> <translation id="7726641833034062494">Snimite normalan videozapis</translation> +<translation id="7748344063862150053">Gornji desni kut dokumenta</translation> <translation id="7983668134180549431">Tekst je prepoznat.</translation> <translation id="8067883171444229417">Reproduciraj videozapis</translation> <translation id="8120146556401698679">Pomicanje, naginjanje, zumiranje</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_hy.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_hy.xtb index dd64492..24c7f3a 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_hy.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_hy.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">Չհաջողվեց ուղղաձիգ դիրքով լուսանկարել</translation> <translation id="3569311554794739032">Հեռացնե՞լ <ph name="FILE" /> ֆայլը:</translation> <translation id="3573890771273113519">Անցնել սկանավորման ռեժիմին</translation> +<translation id="3583444040776960729">Փաստաթղթի ներքևի ձախ անկյուն</translation> <translation id="3789724198583203151">Պտտել 90 աստիճան ժամացույցի սլաքի հակառակ ուղղությամբ</translation> <translation id="3810838688059735925">Տեսանյութ</translation> <translation id="3838931309141338733">Սկանավորել գծակոդը</translation> @@ -77,6 +78,7 @@ Ստուգեք՝ արդյոք տեսախցիկը ճիշտ է միացված:</translation> <translation id="5152121255775685072">Անցնել ցուցասրահ</translation> <translation id="520537883758714667">Փաստաթղթերի սկանավորումն արդեն հասանելի է</translation> +<translation id="5266635337630551423">Փաստաթղթի վերևի ձախ անկյուն</translation> <translation id="5317780077021120954">Պահել</translation> <translation id="5444515100983837161">Փաստաթուղթը դրեք շրջանակի մեջ։ Սկանավորումը լավագույնս աշխատում է, երբ փաստաթղթի և ֆոնի գույները տարբեր են։</translation> <translation id="5671277269877808209">Քառակուսի</translation> @@ -96,6 +98,7 @@ Եթե ձեր կարծիքը պատկերի կամ տեսանյութի որակին է վերաբերում, ապա կցեք խնդրին առնչվող օրինակի ֆայլը (օր․՝ լուսանկարը շատ մուգ է կամ ֆոկուսից դուրս)։</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> – <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> մեգապիքսել</translation> <translation id="6527303717912515753">Կիսվել</translation> +<translation id="6652737148136672975">Տեղաշարժեք անկյունը սլաքներով ստեղների օգնությամբ</translation> <translation id="667999046851023355">Փաստաթուղթ</translation> <translation id="6681668084120808868">Լուսանկարել</translation> <translation id="6778482348691154169">Չհաջողվեց լուսանկարել</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">Օգնություն</translation> <translation id="7658239707568436148">Չեղարկել</translation> <translation id="7670511624014457267">60 կադր/վ</translation> +<translation id="7671804233658741790">Փաստաթղթի ներքևի աջ անկյուն</translation> <translation id="7726641833034062494">Տեսագրել սովորական տեսանյութ</translation> +<translation id="7748344063862150053">Փաստաթղթի վերևի աջ անկյուն</translation> <translation id="7983668134180549431">Հայտնաբերվել է տեքստ։</translation> <translation id="8067883171444229417">Նվագարկել տեսանյութը</translation> <translation id="8120146556401698679">Տեղաշարժում/թեքում/մասշտաբավորում</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_kk.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_kk.xtb index 71e1a5c..c331b2d 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_kk.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_kk.xtb
@@ -55,6 +55,7 @@ <translation id="3517926952904427380">Портреттік суретке түсіру мүмкін болмады.</translation> <translation id="3569311554794739032"><ph name="FILE" /> файлын шынымен өшіргіңіз келе ме?</translation> <translation id="3573890771273113519">Сканерлеу режиміне ауысу</translation> +<translation id="3583444040776960729">Құжаттың төменгі сол жақ бұрышы</translation> <translation id="3789724198583203151">Сағат тіліне қарсы 90 градус бұру</translation> <translation id="3810838688059735925">Бейне</translation> <translation id="3838931309141338733">Сканерлеу штрих коды</translation> @@ -76,6 +77,7 @@ Камераның дұрыс жалғанғанын тексеріңіз.</translation> <translation id="5152121255775685072">Галереяға өту</translation> <translation id="520537883758714667">Енді кұжатты сканерлеуге болады.</translation> +<translation id="5266635337630551423">Құжаттың жоғарғы сол жақ бұрышы</translation> <translation id="5317780077021120954">Сақтау</translation> <translation id="5444515100983837161">Құжатты жақтаудың ішіне орналастырыңыз. Сканерлеудің сапасы жақсы болуы үшін, құжат пен фонның түсі әртүрлі болуы керек.</translation> <translation id="5671277269877808209">Шаршы</translation> @@ -95,6 +97,7 @@ Егер пікір сурет не бейне сапасы туралы болса, үлгі ретінде суретті не бейнені жіберіп, не дұрыс емес екенін (мысалы, фотосурет тым күңгірт немесе нысан фокусқа алынбаған) көрсетіңіз.</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> – <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> мегапиксел</translation> <translation id="6527303717912515753">Бөлісу</translation> +<translation id="6652737148136672975">Бұрышты бағыт пернелерімен жылжытыңыз.</translation> <translation id="667999046851023355">Құжат</translation> <translation id="6681668084120808868">Фотосуретке түсіру</translation> <translation id="6778482348691154169">Фотосуретке түсірілмеді.</translation> @@ -115,7 +118,9 @@ <translation id="7649070708921625228">Анықтама</translation> <translation id="7658239707568436148">Бас тарту</translation> <translation id="7670511624014457267">60 кадр/сек</translation> +<translation id="7671804233658741790">Құжаттың төменгі оң жақ бұрышы</translation> <translation id="7726641833034062494">Қалыпты бейне түсіру</translation> +<translation id="7748344063862150053">Құжаттың жоғарғы оң жақ бұрышы</translation> <translation id="7983668134180549431">Мәтін анықталды.</translation> <translation id="8067883171444229417">Бейнені ойнату</translation> <translation id="8120146556401698679">Панорама, қисайту, масштабтау</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_kn.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_kn.xtb index 20b7351..4caa0549 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_kn.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_kn.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">ಪೋರ್ಟ್ರೇಟ್ ಫೋಟೋ ತೆಗೆಯಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ</translation> <translation id="3569311554794739032">ನೀವು ನಿಜವಾಗಿಯೂ <ph name="FILE" /> ತೆಗೆದುಹಾಕಲು ಬಯಸುವಿರಾ?</translation> <translation id="3573890771273113519">ಸ್ಕ್ಯಾನ್ ಮೋಡ್ಗೆ ಬದಲಿಸಿ</translation> +<translation id="3583444040776960729">ಡಾಕ್ಯುಮೆಂಟ್ ಕೆಳಗಿನ ಎಡ ಮೂಲೆ</translation> <translation id="3789724198583203151">ಅಪ್ರದಕ್ಷಿಣಾಕಾರವಾಗಿ 90 ಡಿಗ್ರಿಗಳಷ್ಟು ತಿರುಗಿಸಿ</translation> <translation id="3810838688059735925">ವೀಡಿಯೊ</translation> <translation id="3838931309141338733">ಬಾರ್ಕೋಡ್ ಸ್ಕ್ಯಾನ್ ಮಾಡಿ</translation> @@ -77,6 +78,7 @@ ಕ್ಯಾಮರಾ ಸರಿಯಾಗಿ ಸಂಪರ್ಕಗೊಂಡಿದೆಯೇ ಎಂಬುದನ್ನು ಪರೀಕ್ಷಿಸಿ.</translation> <translation id="5152121255775685072">ಗ್ಯಾಲರಿಗೆ ಹೋಗಿ</translation> <translation id="520537883758714667">ಡಾಕ್ಯುಮೆಂಟ್ ಸ್ಕ್ಯಾನಿಂಗ್ ಈಗ ಲಭ್ಯವಿದೆ</translation> +<translation id="5266635337630551423">ಡಾಕ್ಯುಮೆಂಟ್ ಮೇಲಿನ ಎಡ ಮೂಲೆ</translation> <translation id="5317780077021120954">ಉಳಿಸು</translation> <translation id="5444515100983837161">ಡಾಕ್ಯುಮೆಂಟ್ನ ಎಲ್ಲಾ ಅಂಚುಗಳನ್ನು ಫ್ರೇಮ್ನೊಳಗೆ ಇರಿಸಿ. ಡಾಕ್ಯುಮೆಂಟ್ ಮತ್ತು ಹಿನ್ನೆಲೆ ವಿಭಿನ್ನ ಬಣ್ಣಗಳಾಗಿದ್ದರೆ ಸ್ಕ್ಯಾನಿಂಗ್ ಉತ್ತಮವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ.</translation> <translation id="5671277269877808209">ಚೌಕ</translation> @@ -96,6 +98,7 @@ ನಿಮ್ಮ ಪ್ರತಿಕ್ರಿಯೆಯು ಚಿತ್ರ ಅಥವಾ ವೀಡಿಯೊ ಗುಣಮಟ್ಟದ ಕುರಿತಾಗಿದ್ದರೆ, ಫೋಟೋ ಅಥವಾ ವೀಡಿಯೊದ ಮಾದರಿಯೊಂದನ್ನು ಲಗತ್ತಿಸಿ ಮತ್ತು ತಪ್ಪೇನು ಎಂಬುದನ್ನು ವಿವರಿಸಿ. (ಉದಾಹರಣೆಗಾಗಿ, ಫೋಟೋ ತುಂಬಾ ಡಾರ್ಕ್ ಆಗಿದೆ ಅಥವಾ ವಿಷಯವು ಫೋಕಸ್ನಲ್ಲಿಲ್ಲ.)</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> ಮೆಗಾ ಪಿಕ್ಸೆಲ್</translation> <translation id="6527303717912515753">ಹಂಚಿಕೊಳ್ಳು</translation> +<translation id="6652737148136672975">ಆ್ಯರೋ ಕೀಗಳ ಮೂಲಕ ಮೂಲೆಯ ಸ್ಥಾನವನ್ನು ಸರಿಸಿ</translation> <translation id="667999046851023355">ಡಾಕ್ಯುಮೆಂಟ್</translation> <translation id="6681668084120808868">ಫೋಟೋ ತೆಗೆಯಿರಿ</translation> <translation id="6778482348691154169">ಫೋಟೋ ತೆಗೆದುಕೊಳ್ಳಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">ಸಹಾಯ</translation> <translation id="7658239707568436148">ರದ್ದುಮಾಡಿ</translation> <translation id="7670511624014457267">60 FPS</translation> +<translation id="7671804233658741790">ಡಾಕ್ಯುಮೆಂಟ್ ಕೆಳಗಿನ ಬಲ ಮೂಲೆ</translation> <translation id="7726641833034062494">ಸಾಮಾನ್ಯ ವೀಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ</translation> +<translation id="7748344063862150053">ಡಾಕ್ಯುಮೆಂಟ್ ಮೇಲಿನ ಬಲ ಮೂಲೆ</translation> <translation id="7983668134180549431">ಪಠ್ಯ ಪತ್ತೆಯಾಗಿದೆ.</translation> <translation id="8067883171444229417">ವೀಡಿಯೊ ಪ್ಲೇ ಮಾಡಿ</translation> <translation id="8120146556401698679">ಪ್ಯಾನ್ ಮಾಡಿ ಟಿಲ್ಟ್ ಮಾಡಿ ಝೂಮ್ ಮಾಡಿ</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_nl.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_nl.xtb index df52f9ac..e2c7f0b 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_nl.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_nl.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">Kan geen portretfoto maken</translation> <translation id="3569311554794739032">Weet je zeker dat je <ph name="FILE" /> wilt verwijderen?</translation> <translation id="3573890771273113519">Overschakelen naar scanmodus</translation> +<translation id="3583444040776960729">Linkerbenedenhoek van document</translation> <translation id="3789724198583203151">90 graden linksom draaien</translation> <translation id="3810838688059735925">Video</translation> <translation id="3838931309141338733">Streepjescode scannen</translation> @@ -77,6 +78,7 @@ Controleer of de camera correct is aangesloten.</translation> <translation id="5152121255775685072">Naar galerij</translation> <translation id="520537883758714667">Documenten scannen is nu beschikbaar</translation> +<translation id="5266635337630551423">Linkerbovenhoek van document</translation> <translation id="5317780077021120954">Opslaan</translation> <translation id="5444515100983837161">Plaats alle randen van het document binnen het frame. Scannen werkt het beste als het document en de achtergrond een verschillende kleur hebben.</translation> <translation id="5671277269877808209">Vierkant</translation> @@ -96,6 +98,7 @@ Als je feedback over de afbeeldings- of videokwaliteit gaat, voeg dan een voorbeeldfoto of -video bij en beschrijf wat het probleem is. (Voorbeeld: de foto is te donker of het onderwerp is niet scherp in beeld.)</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> megapixel</translation> <translation id="6527303717912515753">Delen</translation> +<translation id="6652737148136672975">Hoekpositie verplaatsen met pijltoetsen</translation> <translation id="667999046851023355">Document</translation> <translation id="6681668084120808868">Foto nemen</translation> <translation id="6778482348691154169">Kan geen foto maken</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">Hulp</translation> <translation id="7658239707568436148">Annuleren</translation> <translation id="7670511624014457267">60 FPS</translation> +<translation id="7671804233658741790">Rechterbenedenhoek van document</translation> <translation id="7726641833034062494">Normale video opnemen</translation> +<translation id="7748344063862150053">Rechterbovenhoek van document</translation> <translation id="7983668134180549431">Tekst gevonden.</translation> <translation id="8067883171444229417">Video afspelen</translation> <translation id="8120146556401698679">Schuiven, kantelen, zoomen</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_pt-BR.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_pt-BR.xtb index 48f9f0cf..e47e333 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_pt-BR.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_pt-BR.xtb
@@ -6,6 +6,7 @@ <translation id="1258009455399840361">Girar 90 graus no sentido horário</translation> <translation id="1276998909102132017">Imagens da galeria</translation> <translation id="1300209025925956156">Digitalize seu documento</translation> +<translation id="1303487788671416818">Ativar a captura de tela de vídeo no tamanho original</translation> <translation id="137991641490787891"><ph name="ASPECT_RATIO_WIDTH" />. Pressione "Pesquisa" + seta para a esquerda para acessar.</translation> <translation id="1430915738399379752">Imprimir</translation> <translation id="1467231725790366244">A <ph name="CAMERA" /> foi desconectada.</translation> @@ -55,6 +56,7 @@ <translation id="3517926952904427380">Não foi possível capturar o retrato</translation> <translation id="3569311554794739032">Tem certeza de que quer remover <ph name="FILE" />?</translation> <translation id="3573890771273113519">Mudar para o modo de digitalização</translation> +<translation id="3583444040776960729">Canto inferior esquerdo do documento</translation> <translation id="3789724198583203151">Girar 90 graus no sentido anti-horário</translation> <translation id="3810838688059735925">Vídeo</translation> <translation id="3838931309141338733">Ler código de barras</translation> @@ -76,6 +78,7 @@ Verifique se ela está conectada corretamente.</translation> <translation id="5152121255775685072">Ir para a galeria</translation> <translation id="520537883758714667">A digitalização de documentos está disponível</translation> +<translation id="5266635337630551423">Canto superior esquerdo do documento</translation> <translation id="5317780077021120954">Salvar</translation> <translation id="5444515100983837161">Posicione todas as bordas do documento dentro do quadro. A digitalização funciona melhor quando o documento e o plano de fundo têm cores diferentes.</translation> <translation id="5671277269877808209">Quadrado</translation> @@ -95,6 +98,7 @@ Caso seu feedback seja sobre a qualidade da imagem ou do vídeo, adicione uma foto ou um vídeo de amostra e descreva o problema. Por exemplo, a foto está escura demais ou não está focando.</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> megapixel</translation> <translation id="6527303717912515753">Compartilhar</translation> +<translation id="6652737148136672975">Mova os cantos com as teclas de seta</translation> <translation id="667999046851023355">Documento</translation> <translation id="6681668084120808868">Tirar foto</translation> <translation id="6778482348691154169">Não foi possível tirar a foto</translation> @@ -115,7 +119,9 @@ <translation id="7649070708921625228">Ajuda</translation> <translation id="7658239707568436148">Cancelar</translation> <translation id="7670511624014457267">60 QPS</translation> +<translation id="7671804233658741790">Canto inferior direito do documento</translation> <translation id="7726641833034062494">Gravar um vídeo normal</translation> +<translation id="7748344063862150053">Canto superior direito do documento</translation> <translation id="7983668134180549431">Texto detectado.</translation> <translation id="8067883171444229417">Assistir vídeo</translation> <translation id="8120146556401698679">Panorâmica, inclinação, zoom</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_pt-PT.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_pt-PT.xtb index 1bc4050..2829420 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_pt-PT.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_pt-PT.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">Não é possível tirar foto de retrato</translation> <translation id="3569311554794739032">Tem a certeza de que pretende remover <ph name="FILE" />?</translation> <translation id="3573890771273113519">Mudar para o modo de digitalização</translation> +<translation id="3583444040776960729">Canto inferior esquerdo do documento</translation> <translation id="3789724198583203151">Rodar 90 graus no sentido contrário ao dos ponteiros do relógio</translation> <translation id="3810838688059735925">Vídeo</translation> <translation id="3838931309141338733">Ler código de barras</translation> @@ -77,6 +78,7 @@ Verifique se a câmara está ligada corretamente.</translation> <translation id="5152121255775685072">Ir para a galeria</translation> <translation id="520537883758714667">A digitalização de documentos já está disponível</translation> +<translation id="5266635337630551423">Canto superior esquerdo do documento</translation> <translation id="5317780077021120954">Guardar</translation> <translation id="5444515100983837161">Posicione todas as margens do documento dentro da moldura. A digitalização funciona melhor se o documento e o fundo tiverem cores diferentes.</translation> <translation id="5671277269877808209">Quadrado</translation> @@ -96,6 +98,7 @@ Se o seu feedback for acerca da qualidade de imagem ou vídeo, anexe uma foto ou um vídeo de exemplo e descreva o problema. (Por exemplo, a foto está demasiado escura ou o objeto não está focado.)</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> – <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> megapíxel(eis)</translation> <translation id="6527303717912515753">Partilhar</translation> +<translation id="6652737148136672975">Mova a posição do canto com as teclas de seta</translation> <translation id="667999046851023355">Documento</translation> <translation id="6681668084120808868">Tirar foto</translation> <translation id="6778482348691154169">Não é possível tirar a foto.</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">Ajuda</translation> <translation id="7658239707568436148">Cancelar</translation> <translation id="7670511624014457267">60 FPS</translation> +<translation id="7671804233658741790">Canto inferior direito do documento</translation> <translation id="7726641833034062494">Gravar vídeo normal</translation> +<translation id="7748344063862150053">Canto superior direito do documento</translation> <translation id="7983668134180549431">Texto detetado.</translation> <translation id="8067883171444229417">Reproduzir vídeo</translation> <translation id="8120146556401698679">Deslocar, inclinar, zoom</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_tr.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_tr.xtb index f2cb5506..b04150c4 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_tr.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_tr.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">Portre fotoğrafı çekilemiyor</translation> <translation id="3569311554794739032"><ph name="FILE" /> dosyasını kaldırmak istediğinizden emin misiniz?</translation> <translation id="3573890771273113519">Tarama moduna geç</translation> +<translation id="3583444040776960729">Dokümanın sol alt köşesi</translation> <translation id="3789724198583203151">Saat yönünün tersine 90 derece döndür</translation> <translation id="3810838688059735925">Video</translation> <translation id="3838931309141338733">Barkodu tara</translation> @@ -77,6 +78,7 @@ Lütfen kameranın düzgün bir şekilde bağlanıp bağlanmadığını kontrol edin.</translation> <translation id="5152121255775685072">Galeriye git</translation> <translation id="520537883758714667">Doküman tarama artık kullanılabilir</translation> +<translation id="5266635337630551423">Dokümanın sol üst köşesi</translation> <translation id="5317780077021120954">Kaydet</translation> <translation id="5444515100983837161">Dokümanın tüm kenarlarını çerçevenin içine yerleştirin. Dokümanla arka plan farklı renklere sahip olduğunda tarama daha iyi sonuç verir.</translation> <translation id="5671277269877808209">Kare</translation> @@ -96,6 +98,7 @@ Geri bildiriminiz resim ya da video kalitesi ile ilgiliyse lütfen örnek bir fotoğraf veya video ekleyip sorunun ne olduğunu açıklayın. (Örneğin, fotoğraf çok karanlık veya özne net değil.)</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> megapiksel</translation> <translation id="6527303717912515753">Paylaş</translation> +<translation id="6652737148136672975">Köşe konumunu ok tuşlarıyla taşıyın</translation> <translation id="667999046851023355">Doküman</translation> <translation id="6681668084120808868">Fotoğraf çek</translation> <translation id="6778482348691154169">Fotoğraf çekilemiyor</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">Yardım</translation> <translation id="7658239707568436148">İptal</translation> <translation id="7670511624014457267">60 FPS</translation> +<translation id="7671804233658741790">Dokümanın sağ alt köşesi</translation> <translation id="7726641833034062494">Normal video kaydet</translation> +<translation id="7748344063862150053">Dokümanın sağ üst köşesi</translation> <translation id="7983668134180549431">Metin algılandı.</translation> <translation id="8067883171444229417">Videoyu oynat</translation> <translation id="8120146556401698679">Yana kaydırın, eğin, zum yapın</translation>
diff --git a/ash/webui/camera_app_ui/resources/strings/camera_strings_zu.xtb b/ash/webui/camera_app_ui/resources/strings/camera_strings_zu.xtb index 5f2d0c4..212245c4 100644 --- a/ash/webui/camera_app_ui/resources/strings/camera_strings_zu.xtb +++ b/ash/webui/camera_app_ui/resources/strings/camera_strings_zu.xtb
@@ -56,6 +56,7 @@ <translation id="3517926952904427380">Ayikwazi ukuthatha isithombe sokuma ngobude</translation> <translation id="3569311554794739032">Ufuna ngempela ukukhipha <ph name="FILE" />?</translation> <translation id="3573890771273113519">Shintshela kwimodi yokuskena</translation> +<translation id="3583444040776960729">Idokhumenti ekhoneni eliphansi kwesobunxele</translation> <translation id="3789724198583203151">Zungezisa u-90 degrees ngokuphambana nezinti zewashi</translation> <translation id="3810838688059735925">Ividiyo</translation> <translation id="3838931309141338733">Skena ibhakhodi</translation> @@ -77,6 +78,7 @@ Hlola uma ngabe ikhamera ixhumeke kahle yini.</translation> <translation id="5152121255775685072">Hamba kugalari</translation> <translation id="520537883758714667">Ukuskena idokhumenti manje sekuyatholakala</translation> +<translation id="5266635337630551423">Idokhumenti ekhoneni eliphezulu kwesobunxele</translation> <translation id="5317780077021120954">Londoloza</translation> <translation id="5444515100983837161">Beka bonke onqenqema bedokhumenti ngaphakathi kohlaka. Ukuskena kusebenza kangcono uma idokhumenti nengemuva kuyimibala ehlukile.</translation> <translation id="5671277269877808209">Isikwele</translation> @@ -96,6 +98,7 @@ Uma impendulo yakho imayelana nesithombe noma ikhwalithi yevidiyo, sicela unamathisele isampula yesithombe noma yevidiyo bese uchaza ukuthi iyini inkinga. (Ngokwesibonelo, isithombe simnyama kakhulu noma into ayigxilile.)</translation> <translation id="6420689864531458495">(<ph name="ASPECT_RATIO_WIDTH" />:<ph name="ASPECT_RATIO_HEIGHT" /> - <ph name="WIDTH" />x<ph name="HEIGHT" />) <ph name="MEGAPIXEL" /> i-mega pixel</translation> <translation id="6527303717912515753">Yabelana</translation> +<translation id="6652737148136672975">Hambisa indawo yekhona ngokhiye bemicibisholo</translation> <translation id="667999046851023355">Idokhumenti</translation> <translation id="6681668084120808868">Thatha isithombe</translation> <translation id="6778482348691154169">Ayikwazi ukuthatha isithombe</translation> @@ -116,7 +119,9 @@ <translation id="7649070708921625228">Usizo</translation> <translation id="7658239707568436148">Khansela</translation> <translation id="7670511624014457267">60 FPS</translation> +<translation id="7671804233658741790">Idokhumenti ekhoneni eliphansi kwesokudla</translation> <translation id="7726641833034062494">Rekhoda ividiyo evamile</translation> +<translation id="7748344063862150053">Idokhumenti ekhoneni eliphezulu kwesokudla</translation> <translation id="7983668134180549431">Umbhalo utholiwe.</translation> <translation id="8067883171444229417">Dlala ividiyo</translation> <translation id="8120146556401698679">Ukusondeza kokutshekisa i-pan</translation>
diff --git a/ash/webui/camera_app_ui/resources/views/main.html b/ash/webui/camera_app_ui/resources/views/main.html index 5eb04c4..2ea3e57 100644 --- a/ash/webui/camera_app_ui/resources/views/main.html +++ b/ash/webui/camera_app_ui/resources/views/main.html
@@ -610,7 +610,8 @@ </div> </div> </div> - <div id="toast" class="centered-overlay" aria-live="polite"></div> + <div id="toast" class="centered-overlay" aria-hidden="true" + aria-live="polite"></div> <div id="focus-ring"></div> <div id="tooltip" aria-hidden="true"></div> <audio id="sound-tick-final" src="/sounds/tick_final.ogg">
diff --git a/ash/webui/diagnostics_ui/resources/data_point.html b/ash/webui/diagnostics_ui/resources/data_point.html index ecc89e9..bd72717 100644 --- a/ash/webui/diagnostics_ui/resources/data_point.html +++ b/ash/webui/diagnostics_ui/resources/data_point.html
@@ -36,7 +36,7 @@ --iron-icon-height: 20px; --iron-icon-width: 20px; bottom: 1px; - fill: var(--google-grey-700); + fill: var(--cros-icon-color-secondary); left: 4px; } @@ -51,7 +51,7 @@ } .text-red { - color: var(--google-red-600); + color: var(--cros-color-alert); } </style> <div class="data-point" tabindex="0" aria-labelledby="headerText value"
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_app.html b/ash/webui/diagnostics_ui/resources/diagnostics_app.html index 63907ed7..a526814 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_app.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_app.html
@@ -12,15 +12,15 @@ } #download-icon { - --iron-icon-fill-color: var(--google-blue-600); - color: var(--google-blue-600); + --iron-icon-fill-color: var(--cros-icon-color-prominent); + color: var(--cros-text-color-prominent); height: 20px; margin-inline-end: 8px; width: 20px; } .session-log-button { - color: var(--google-blue-600); + color: var(--cros-text-color-prominent); border-radius: 16px; height: 32px; margin-inline: 16px;
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_card.html b/ash/webui/diagnostics_ui/resources/diagnostics_card.html index ec7c591..eb1d8e04 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_card.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_card.html
@@ -1,6 +1,6 @@ <style include="diagnostics-shared diagnostics-fonts"> ::slotted([slot=chip]) { - background-color: var(--google-grey-100); + background-color: var(--google-grey-200); border-radius: 16px; } @@ -39,14 +39,14 @@ } .data-points { - border-bottom: 1px solid var(--google-grey-200); + border-bottom: 1px solid var(--cros-separator-color); display: grid; grid-template-columns: 1fr 0fr 1fr 0fr 1fr; padding-inline: var(--data-point-container-padding); } .data-points-column { - border-bottom: 1px solid var(--google-grey-200); + border-bottom: 1px solid var(--cros-separator-color); padding-inline: 24px; } @@ -55,7 +55,7 @@ } .top-section { - border-bottom: 1px solid var(--google-grey-200); + border-bottom: 1px solid var(--cros-separator-color); display: flex; margin-top: 16px; }
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.html b/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.html index 312baaf5..0c5d455 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_card_frame.html
@@ -1,6 +1,6 @@ <style include="diagnostics-shared diagnostics-fonts"> ::slotted([slot=chip]) { - background-color: var(--google-grey-100); + background-color: var(--google-grey-200); border-radius: 16px; } @@ -27,6 +27,7 @@ } .card-wrapper { + background-color: var(--cr-card-background-color); border-radius: 4px; box-shadow: var(--diagnostics-box-shadow); margin: 10px 0;
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html b/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html index df91e94..d2bc704 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_fonts_css.html
@@ -25,18 +25,18 @@ --diagnostics-regular-font-weight: 400; --diagnostics-medium-font-weight: 500; - --diagnostics-header-text-color: var(--google-grey-900); - --diagnostics-card-title-text-color: var(--google-grey-700); - --diagnostics-overview-text-color: var(--google-grey-700); - --diagnostics-data-point-title-color: var(--google-grey-900); - --diagnostics-data-point-subtitle-color: var(--google-grey-700); - --diagnostics-routine-additional-message-color: var(--google-grey-900); + --diagnostics-header-text-color: var(--cros-text-color-primary); + --diagnostics-card-title-text-color: var(--cros-text-color-secondary); + --diagnostics-overview-text-color: var(--cros-text-color-secondary); + --diagnostics-data-point-title-color: var(--cros-text-color-primary); + --diagnostics-data-point-subtitle-color: var(--cros-text-color-secondary); + --diagnostics-routine-additional-message-color: var(--cros-text-color-primary); --diagnostics-routine-name-color: var(--cros-text-color-primary); - --diagnostics-chart-title-color: var(--google-grey-700); - --diagnostics-test-status-text-color: var(--google-grey-700); - --diagnostics-caution-banner-text-color: var(--google-grey-900); - --diagnostics-link-text-color: var(--google-blue-600); - --diagnostics-settings-link-text-color: var(--google-grey-700); + --diagnostics-chart-title-color: var(--cros-text-color-secondary); + --diagnostics-test-status-text-color: var(--cros-text-color-secondary); + --diagnostics-caution-banner-text-color: var(--cros-text-color-primary); + --diagnostics-link-text-color: var(--cros-link-color); + --diagnostics-settings-link-text-color: var(--cros-text-color-secondary); --diagnostics-default-font: { font-family: var(--diagnostics-google-sans-font-family);
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.html b/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.html index 8f35dd14..d95add0 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_network_icon.html
@@ -1,6 +1,6 @@ <style include="diagnostics-shared"> :host { - --cros-icon-color-primary: var(--google-gray-700); + --cros-icon-color-primary: var(--cros-icon-color-secondary); } #connectingIcon {
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_shared_css.html b/ash/webui/diagnostics_ui/resources/diagnostics_shared_css.html index 2215dc99..13d971f 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_shared_css.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_shared_css.html
@@ -10,22 +10,18 @@ --diagnostics-box-shadow-elevation-2: var(--cr-elevation-2); --diagnostics-card-icon: { - --iron-icon-fill-color: var(--google-blue-600); + --iron-icon-fill-color: var(--cros-color-prominent); --iron-icon-height: 20px; --iron-icon-width: 20px; - background-color: var(--google-blue-50); + background-color: var(--cros-highlight-color); border-radius: 50%; padding: 8px; }; } - html { - background-color: var(--cros-bg-color); - } - hr { border: 0; - border-top: 1px solid var(--google-grey-200); + border-top: 1px solid var(--cros-separator-color); display: block; height: 1px; margin: 0; @@ -94,7 +90,7 @@ } .divider { - border-left: 1px solid var(--google-grey-200); + border-left: 1px solid var(--cros-separator-color); height: 32px; padding-inline: 16px; position: relative; @@ -103,7 +99,7 @@ .divider-horizontal { align-self: center; - border-left: 1px solid var(--google-grey-200); + border-left: 1px solid var(--cros-separator-color); height: var(--divider-horizontal-height, 94px); margin: 10px 20px; } @@ -125,7 +121,7 @@ } .link-text { - color: var(--google-blue-600); + color: var(--cros-color-prominent); cursor: pointer; }
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html b/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html index 30bfa36c..85bac51 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html +++ b/ash/webui/diagnostics_ui/resources/diagnostics_sticky_banner.html
@@ -1,7 +1,7 @@ <style include="cr-shared-style diagnostics-shared diagnostics-fonts"> #banner { align-items: center; - background-color: var(--google-blue-50); + background-color: var(--cros-highlight-color); display: flex; height: 56px; position: sticky; @@ -13,7 +13,7 @@ #bannerIcon { --iron-icon-height: 20px; --iron-icon-width: 20px; - fill: var(--google-blue-600); + fill: var(--cros-color-prominent); padding-inline-end: 16px; padding-inline-start: 40px; }
diff --git a/ash/webui/diagnostics_ui/resources/index.html b/ash/webui/diagnostics_ui/resources/index.html index 4e3e409..6d2c8ce 100644 --- a/ash/webui/diagnostics_ui/resources/index.html +++ b/ash/webui/diagnostics_ui/resources/index.html
@@ -7,8 +7,24 @@ <meta charset="utf-8"> <title></title> </head> + <link rel="stylesheet" href="chrome://resources/chromeos/colors/cros_styles.css"> <style> + /* The :not(body) selector allows the variable definitions below to 'win' + against the shared ones. */ + html:not(body) { + /* Ensure cros colors are used by cr elements. Setting these on a + specific element will still override this. */ + --cr-focus-outline-color: var(--cros-focus-ring-color); + --cr-focused-item-color: var(--cros-highlight-color-focus); + --cr-primary-text-color: var(--cros-text-color-primary); + --cr-secondary-text-color: var(--cros-text-color-secondary); + --iron-icon-fill-color: var(--cros-icon-color-primary); + background-color: var(--cros-bg-color); + } + + html, body { + height: 100%; margin: 0; } </style>
diff --git a/ash/webui/diagnostics_ui/resources/input_card.html b/ash/webui/diagnostics_ui/resources/input_card.html index a71d2e4..1eae5ad 100644 --- a/ash/webui/diagnostics_ui/resources/input_card.html +++ b/ash/webui/diagnostics_ui/resources/input_card.html
@@ -1,6 +1,6 @@ <style include="diagnostics-shared"> .device { - border-bottom: 1px solid var(--google-grey-200); + border-bottom: 1px solid var(--cros-separator-color); display: flex; padding: 16px 20px; }
diff --git a/ash/webui/diagnostics_ui/resources/network_list.html b/ash/webui/diagnostics_ui/resources/network_list.html index 1f8516c..de56443 100644 --- a/ash/webui/diagnostics_ui/resources/network_list.html +++ b/ash/webui/diagnostics_ui/resources/network_list.html
@@ -7,7 +7,7 @@ #settingsIcon { --iron-icon-height: 20px; --iron-icon-width: 20px; - fill: var(--google-grey-700); + fill: var(--cros-icon-color-secondary); margin-right: 6px; top: 1px; }
diff --git a/ash/webui/diagnostics_ui/resources/percent_bar_chart.html b/ash/webui/diagnostics_ui/resources/percent_bar_chart.html index c839dda..35868c5 100644 --- a/ash/webui/diagnostics_ui/resources/percent_bar_chart.html +++ b/ash/webui/diagnostics_ui/resources/percent_bar_chart.html
@@ -12,8 +12,8 @@ border-radius: 5px; display: inline-block; width: 95%; - --paper-progress-active-color: var(--google-blue-500); - --paper-progress-container-color: var(--google-blue-100); + --paper-progress-active-color: var(--cros-slider-color-active); + --paper-progress-container-color: var(--cros-slider-track-color-active); --paper-progress-height: 4px; } </style>
diff --git a/ash/webui/diagnostics_ui/resources/realtime_cpu_chart.html b/ash/webui/diagnostics_ui/resources/realtime_cpu_chart.html index a1c6d0de..ae34b1a3 100644 --- a/ash/webui/diagnostics_ui/resources/realtime_cpu_chart.html +++ b/ash/webui/diagnostics_ui/resources/realtime_cpu_chart.html
@@ -1,16 +1,16 @@ <style include="diagnostics-shared diagnostics-fonts"> g.tick line { - stroke: var(--google-grey-200); + stroke: var(--cros-button-label-color-primary); stroke-width: 1px; shape-rendering: crispEdges; } g.tick:first-of-type line { - stroke: var(--google-grey-700); + stroke: var(--cros-color-secondary); } g.tick text { - color: var(--google-grey-700); + color: var(--cros-color-secondary); line-height: 18px; @apply --diagnostics-chart-tick-font; } @@ -28,14 +28,14 @@ fill: url(#user-gradient); shape-render: optimizeSpeed; stroke-width: 1.5px; - stroke: var(--google-blue-600); + stroke: var(--cros-color-prominent); } .system-area { fill: url(#system-gradient); shape-render: optimizeSpeed; stroke-width: 1.5px; - stroke: var(--google-yellow-600); + stroke: var(--cros-color-warning); } .gradient-blue { @@ -85,11 +85,11 @@ } #legend-bar.user { - background-color: var(--google-blue-600); + background-color: var(--cros-color-prominent); } #legend-bar.system { - background-color: var(--google-yellow-600); + background-color: var(--cros-color-warning); } </style> <svg id="chart" width$="[[width_]]" height$="[[height_]]" aria-hidden="true">
diff --git a/ash/webui/diagnostics_ui/resources/routine_result_entry.html b/ash/webui/diagnostics_ui/resources/routine_result_entry.html index f14c5c8..d9a24773 100644 --- a/ash/webui/diagnostics_ui/resources/routine_result_entry.html +++ b/ash/webui/diagnostics_ui/resources/routine_result_entry.html
@@ -35,7 +35,7 @@ } .green { - border-left: 1px dashed var(--google-green-600); + border-left: 1px dashed var(--cros-color-positive); } .line { @@ -49,7 +49,7 @@ } .red { - border-left: 1px dashed var(--google-red-600); + border-left: 1px dashed var(--cros-color-alert); position: relative; }
diff --git a/ash/webui/diagnostics_ui/resources/routine_section.html b/ash/webui/diagnostics_ui/resources/routine_section.html index 09d376b..842fd93 100644 --- a/ash/webui/diagnostics_ui/resources/routine_section.html +++ b/ash/webui/diagnostics_ui/resources/routine_section.html
@@ -10,7 +10,7 @@ .learn-more-button { @apply --diagnostics-button-font; - background-color: rgba(var(--google-blue-600), .06); + background-color: rgba(var(--cros-color-prominent-rgb), .06); border-radius: 4px; height: 32px; margin-top: 12px; @@ -20,7 +20,7 @@ #messageIcon { --iron-icon-height: 20px; --iron-icon-width: 20px; - fill: var(--google-grey-700); + fill: var(--cros-icon-color-secondary); margin-inline-end: 8px; }
diff --git a/ash/webui/diagnostics_ui/resources/system_page.html b/ash/webui/diagnostics_ui/resources/system_page.html index 4048d6b..2b0196d2 100644 --- a/ash/webui/diagnostics_ui/resources/system_page.html +++ b/ash/webui/diagnostics_ui/resources/system_page.html
@@ -13,7 +13,7 @@ #bannerIcon { --iron-icon-height: 20px; --iron-icon-width: 20px; - fill: var(--google-blue-600); + fill: var(--cros-icon-color-prominent); padding-inline-end: 16px; padding-inline-start: 40px; } @@ -34,7 +34,7 @@ #download-icon { --iron-icon-height: 20px; --iron-icon-width: 20px; - color: var(--google-blue-600); + color: var(--cros-icon-color-prominent); right: 4px; }
diff --git a/ash/webui/diagnostics_ui/resources/text_badge.html b/ash/webui/diagnostics_ui/resources/text_badge.html index 017054ae8..0a7f79b 100644 --- a/ash/webui/diagnostics_ui/resources/text_badge.html +++ b/ash/webui/diagnostics_ui/resources/text_badge.html
@@ -1,27 +1,27 @@ <style include="diagnostics-shared"> .error { background-color: var(--google-red-50); - color: var(--google-red-600); + color: var(--cros-text-color-alert); } .queued, .stopped, .skipped { - background-color: var(--google-grey-200); - color: var(--google-grey-700); + background-color: var(--cros-button-label-color-primary); + color: var(--cros-text-color-secondary); } .running { background-color: var(--google-blue-50); - color: var(--google-blue-600); + color: var(--cros-text-color-prominent); } .success { background-color: var(--google-green-50); - color: var(--google-green-600); + color: var(--cros-text-color-positive); } .warning { background-color: #FEF7E0; - color: #F9AB00; + color: var(--cros-text-color-warning); } #textBadge {
diff --git a/ash/webui/projector_app/projector_app_client.h b/ash/webui/projector_app/projector_app_client.h index 28181d89..6597116 100644 --- a/ash/webui/projector_app/projector_app_client.h +++ b/ash/webui/projector_app/projector_app_client.h
@@ -57,6 +57,17 @@ // Observes the pending screencast state change events. virtual void OnScreencastsPendingStatusChanged( const std::set<PendingScreencast>& pending_screencast) = 0; + + // Notifies the observer the SODA binary and language pack download and + // installation progress. + virtual void OnSodaProgress(int combined_progress) = 0; + + // Notifies the observer that an error occurred during installation. + virtual void OnSodaError() = 0; + + // Notifies the observer that installation of SODA binary and at least one + // language pack has finished. + virtual void OnSodaInstalled() = 0; }; ProjectorAppClient(const ProjectorAppClient&) = delete; @@ -80,6 +91,28 @@ // Returns pending screencast uploaded by primary user. virtual const std::set<PendingScreencast>& GetPendingScreencasts() const = 0; + // Checks if device is eligible to trigger SODA installer. + virtual bool ShouldDownloadSoda() = 0; + + // Returns true if SODA binary is downloaded and the language associated with + // the user's locale is installed. + virtual bool IsSpeechRecognitionAvailable() = 0; + + // Triggers the installation of SODA (Speech On-Device API) binary and the + // corresponding language pack for projector. + virtual void InstallSoda() = 0; + + // Notifies the client the SODA binary and language pack download and + // installation progress. + virtual void OnSodaInstallProgress(int combined_progress) = 0; + + // Notifies the client that an error occurred during installation. + virtual void OnSodaInstallError() = 0; + + // Notifies the client that installation of SODA binary and at least one + // language pack has finished. + virtual void OnSodaInstalled() = 0; + protected: ProjectorAppClient(); virtual ~ProjectorAppClient();
diff --git a/ash/webui/projector_app/projector_message_handler.cc b/ash/webui/projector_app/projector_message_handler.cc index ca5a55f..73512df 100644 --- a/ash/webui/projector_app/projector_message_handler.cc +++ b/ash/webui/projector_app/projector_message_handler.cc
@@ -7,8 +7,10 @@ #include <memory> #include <string> +#include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/projector/projector_controller.h" +#include "ash/webui/projector_app/projector_app_client.h" #include "base/bind.h" #include "base/check.h" #include "base/json/values_util.h" @@ -218,6 +220,13 @@ base::Unretained(this))); } +void ProjectorMessageHandler::OnScreencastsPendingStatusChanged( + const std::set<PendingScreencast>& pending_screencast) { + AllowJavascript(); + FireWebUIListener("onScreencastsStateChange", + ScreencastListToValue(pending_screencast)); +} + void ProjectorMessageHandler::OnSodaProgress(int combined_progress) { AllowJavascript(); FireWebUIListener("onSodaInstallProgressUpdated", @@ -229,11 +238,9 @@ FireWebUIListener("onSodaInstallError"); } -void ProjectorMessageHandler::OnScreencastsPendingStatusChanged( - const std::set<PendingScreencast>& pending_screencast) { +void ProjectorMessageHandler::OnSodaInstalled() { AllowJavascript(); - FireWebUIListener("onScreencastsStateChange", - ScreencastListToValue(pending_screencast)); + FireWebUIListener("onSodaInstalled"); } void ProjectorMessageHandler::OnNewScreencastPreconditionChanged( @@ -360,19 +367,18 @@ void ProjectorMessageHandler::ShouldDownloadSoda( const base::Value::ConstListView args) { AllowJavascript(); - // TODO(b/200205765): Add checks on whether the install soda button should be - // shown. - const auto& js_callback_id = args[0].GetString(); - ResolveJavascriptCallback(base::Value(js_callback_id), base::Value(false)); + + // The device should be eligible to download SODA and SODA should not have + // already been downloaded on the device. + ResolveJavascriptCallback( + args[0], base::Value(ProjectorAppClient::Get()->ShouldDownloadSoda())); } void ProjectorMessageHandler::InstallSoda( const base::Value::ConstListView args) { AllowJavascript(); - - // TODO(b/200205765): Trigger SODA installation. - const auto& js_callback_id = args[0].GetString(); - ResolveJavascriptCallback(base::Value(js_callback_id), base::Value(false)); + ProjectorAppClient::Get()->InstallSoda(); + ResolveJavascriptCallback(args[0], base::Value(true)); } void ProjectorMessageHandler::OnError(const base::Value::ConstListView args) {
diff --git a/ash/webui/projector_app/projector_message_handler.h b/ash/webui/projector_app/projector_message_handler.h index eecd563e..f1fa384 100644 --- a/ash/webui/projector_app/projector_message_handler.h +++ b/ash/webui/projector_app/projector_message_handler.h
@@ -78,12 +78,6 @@ // ProjectorAppClient:Observer: void OnNewScreencastPreconditionChanged(bool can_start) override; - // Used to notify the SWA the SODA installation progress. - void OnSodaProgress(int combined_progress); - - // Used to notify the SWA that SODA installation failed. - void OnSodaError(); - void set_web_ui_for_test(content::WebUI* web_ui) { set_web_ui(web_ui); } // ProjectorAppClient::Observer: @@ -91,6 +85,9 @@ // updates the pending list in Projector SWA. void OnScreencastsPendingStatusChanged( const std::set<PendingScreencast>& pending_screencast) override; + void OnSodaProgress(int percentage) override; + void OnSodaError() override; + void OnSodaInstalled() override; private: // Requested by the Projector SWA to list the available accounts (primary and
diff --git a/ash/webui/projector_app/resources/app/embedder.js b/ash/webui/projector_app/resources/app/embedder.js index 9e17f6a..0a890bb 100644 --- a/ash/webui/projector_app/resources/app/embedder.js +++ b/ash/webui/projector_app/resources/app/embedder.js
@@ -66,5 +66,12 @@ } client.onScreencastsStateChange(pendingScreencasts); }); + + this.addWebUIListener( + 'onSodaInstalled', + () => { + // TODO(b/197164300): Pass this information to google3 deployed + // content in iframe. + }); }, });
diff --git a/ash/webui/projector_app/test/mock_app_client.h b/ash/webui/projector_app/test/mock_app_client.h index 06539b0..efd4447 100644 --- a/ash/webui/projector_app/test/mock_app_client.h +++ b/ash/webui/projector_app/test/mock_app_client.h
@@ -46,6 +46,12 @@ MOCK_METHOD1(OnNewScreencastPreconditionChanged, void(bool)); MOCK_CONST_METHOD0(GetPendingScreencasts, const std::set<PendingScreencast>&()); + MOCK_METHOD0(ShouldDownloadSoda, bool()); + MOCK_METHOD0(IsSpeechRecognitionAvailable, bool()); + MOCK_METHOD0(InstallSoda, void()); + MOCK_METHOD1(OnSodaInstallProgress, void(int)); + MOCK_METHOD0(OnSodaInstallError, void()); + MOCK_METHOD0(OnSodaInstalled, void()); void SetAutomaticIssueOfAccessTokens(bool success); void WaitForAccessRequest(const std::string& account_email);
diff --git a/ash/webui/projector_app/test/projector_message_handler_unittest.cc b/ash/webui/projector_app/test/projector_message_handler_unittest.cc index e2f3ce5..d5cf2b4 100644 --- a/ash/webui/projector_app/test/projector_message_handler_unittest.cc +++ b/ash/webui/projector_app/test/projector_message_handler_unittest.cc
@@ -271,7 +271,8 @@ } TEST_F(ProjectorMessageHandlerUnitTest, OnSodaProgress) { - message_handler()->OnSodaProgress(50); + static_cast<ProjectorAppClient::Observer*>(message_handler()) + ->OnSodaProgress(50); const content::TestWebUI::CallData& call_data = *(web_ui().call_data()[0]); EXPECT_EQ(call_data.function_name(), kWebUIListenerCall); EXPECT_EQ(call_data.arg1()->GetString(), kOnSodaInstallProgressUpdated); @@ -279,13 +280,18 @@ } TEST_F(ProjectorMessageHandlerUnitTest, OnSodaError) { - message_handler()->OnSodaError(); + static_cast<ProjectorAppClient::Observer*>(message_handler())->OnSodaError(); const content::TestWebUI::CallData& call_data = *(web_ui().call_data()[0]); EXPECT_EQ(call_data.function_name(), kWebUIListenerCall); EXPECT_EQ(call_data.arg1()->GetString(), kOnSodaInstallError); } TEST_F(ProjectorMessageHandlerUnitTest, ShouldDownloadSoda) { + ON_CALL(mock_app_client(), ShouldDownloadSoda()) + .WillByDefault(testing::Return(true)); + ON_CALL(mock_app_client(), IsSpeechRecognitionAvailable()) + .WillByDefault(testing::Return(false)); + base::ListValue list_args; list_args.Append(base::Value(kShouldDownloadSodaCallback)); @@ -296,10 +302,12 @@ EXPECT_EQ(call_data.function_name(), kWebUIResponse); EXPECT_EQ(call_data.arg1()->GetString(), kShouldDownloadSodaCallback); EXPECT_EQ(call_data.arg2()->GetBool(), true); - EXPECT_EQ(call_data.arg3()->GetBool(), false); + EXPECT_EQ(call_data.arg3()->GetBool(), true); } TEST_F(ProjectorMessageHandlerUnitTest, InstallSoda) { + ON_CALL(mock_app_client(), InstallSoda()).WillByDefault(testing::Return()); + base::ListValue list_args; list_args.Append(base::Value(kInstallSodaCallback)); @@ -310,7 +318,7 @@ EXPECT_EQ(call_data.function_name(), kWebUIResponse); EXPECT_EQ(call_data.arg1()->GetString(), kInstallSodaCallback); EXPECT_EQ(call_data.arg2()->GetBool(), true); - EXPECT_EQ(call_data.arg3()->GetBool(), false); + EXPECT_EQ(call_data.arg3()->GetBool(), true); } TEST_F(ProjectorMessageHandlerUnitTest, GetPendingScreencasts) {
diff --git a/ash/webui/shimless_rma/resources/onboarding_update_page.js b/ash/webui/shimless_rma/resources/onboarding_update_page.js index 327d1b6..eb0f6da 100644 --- a/ash/webui/shimless_rma/resources/onboarding_update_page.js +++ b/ash/webui/shimless_rma/resources/onboarding_update_page.js
@@ -168,6 +168,7 @@ 'currentVersionUpToDateText', this.currentVersion_); this.setUpdateNoticeMessage_(); + this.setNextButtonLabel_(); }); } @@ -263,6 +264,18 @@ this.isCompliant_ = isCompliant; this.setUpdateNoticeMessage_(); } + + /** @protected */ + setNextButtonLabel_() { + this.dispatchEvent(new CustomEvent( + 'set-next-button-label', + { + bubbles: true, + composed: true, + detail: this.updateAvailable_ ? 'skipButtonLabel' : 'nextButtonLabel' + }, + )); + } } customElements.define(
diff --git a/ash/webui/shimless_rma/resources/shimless_rma.js b/ash/webui/shimless_rma/resources/shimless_rma.js index 0214445..6fcb1233 100644 --- a/ash/webui/shimless_rma/resources/shimless_rma.js +++ b/ash/webui/shimless_rma/resources/shimless_rma.js
@@ -291,6 +291,16 @@ // Allow polymer to observe the changed state. this.notifyPath('currentPage_.buttonNext'); }; + + /** + * The setNextButtonLabelCallback callback is used by page elements to set + * the text label for the 'Next' button. + * @private {?Function} + */ + this.setNextButtonLabelCallback_ = (e) => { + this.currentPage_.buttonNextLabelKey = e.detail; + this.notifyPath('currentPage_.buttonNextLabelKey'); + }; } /** @override */ @@ -299,6 +309,8 @@ window.addEventListener('transition-state', this.transitionState_); window.addEventListener( 'disable-next-button', this.disableNextButtonCallback_); + window.addEventListener( + 'set-next-button-label', this.setNextButtonLabelCallback_); } /** @override */ @@ -307,6 +319,8 @@ window.removeEventListener('transition-state', this.transitionState_); window.removeEventListener( 'disable-next-button', this.disableNextButtonCallback_); + window.removeEventListener( + 'set-next-button-label', this.setNextButtonLabelCallback_); } /** @override */
diff --git a/ash/webui/shimless_rma/shimless_rma.cc b/ash/webui/shimless_rma/shimless_rma.cc index 4d2bb69e..3a34671 100644 --- a/ash/webui/shimless_rma/shimless_rma.cc +++ b/ash/webui/shimless_rma/shimless_rma.cc
@@ -71,6 +71,7 @@ {"cancelButtonLabel", IDS_SHIMLESS_RMA_CANCEL_BUTTON}, {"backButtonLabel", IDS_SHIMLESS_RMA_BACK_BUTTON}, {"nextButtonLabel", IDS_SHIMLESS_RMA_NEXT_BUTTON}, + {"skipButtonLabel", IDS_SHIMLESS_RMA_SKIP_BUTTON}, // Landing page {"welcomeTitleText", IDS_SHIMLESS_RMA_LANDING_PAGE_TITLE}, {"beginRmaWarningText", IDS_SHIMLESS_RMA_AUTHORIZED_TECH_ONLY_WARNING},
diff --git a/ash/wm/desks/desks_controller.cc b/ash/wm/desks/desks_controller.cc index 46afe61..cf8e1392 100644 --- a/ash/wm/desks/desks_controller.cc +++ b/ash/wm/desks/desks_controller.cc
@@ -711,12 +711,21 @@ UMA_HISTOGRAM_ENUMERATION( kMoveWindowFromActiveDeskHistogramName, DesksMoveWindowFromActiveDeskSource::kVisibleOnAllDesks); + Shell::Get() + ->accessibility_controller() + ->TriggerAccessibilityAlertWithMessage(l10n_util::GetStringFUTF8( + IDS_ASH_VIRTUAL_DESKS_ASSIGNED_TO_ALL_DESKS, window->GetTitle())); } void DesksController::MaybeRemoveVisibleOnAllDesksWindow(aura::Window* window) { if (visible_on_all_desks_windows_.erase(window)) { wm::AnimateWindow(window, wm::WINDOW_ANIMATION_TYPE_BOUNCE); NotifyAllDesksForContentChanged(); + Shell::Get() + ->accessibility_controller() + ->TriggerAccessibilityAlertWithMessage(l10n_util::GetStringFUTF8( + IDS_ASH_VIRTUAL_DESKS_UNASSIGNED_FROM_ALL_DESKS, + window->GetTitle())); } }
diff --git a/ash/wm/desks/templates/desks_templates_icon_view.cc b/ash/wm/desks/templates/desks_templates_icon_view.cc index 31d1705..87456eb 100644 --- a/ash/wm/desks/templates/desks_templates_icon_view.cc +++ b/ash/wm/desks/templates/desks_templates_icon_view.cc
@@ -125,8 +125,12 @@ LoadDefaultIcon(); } -void DesksTemplatesIconView::OnAppIconLoaded( - apps::mojom::IconValuePtr icon_value) { +void DesksTemplatesIconView::OnAppIconLoaded(apps::IconValuePtr icon_value) { + if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) { + LoadDefaultIcon(); + return; + } + gfx::ImageSkia image_result = icon_value->uncompressed; if (!image_result.isNull()) { icon_view_->SetImage(image_result, gfx::Size(kIconSize, kIconSize));
diff --git a/ash/wm/desks/templates/desks_templates_icon_view.h b/ash/wm/desks/templates/desks_templates_icon_view.h index c06344b..7fad12da 100644 --- a/ash/wm/desks/templates/desks_templates_icon_view.h +++ b/ash/wm/desks/templates/desks_templates_icon_view.h
@@ -10,7 +10,7 @@ #include "base/memory/weak_ptr.h" #include "base/task/cancelable_task_tracker.h" #include "components/favicon_base/favicon_types.h" -#include "components/services/app_service/public/mojom/types.mojom.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/view.h" @@ -61,7 +61,7 @@ // use a placeholder icon. void OnFaviconLoaded( const favicon_base::FaviconRawBitmapResult& image_result); - void OnAppIconLoaded(apps::mojom::IconValuePtr icon_value); + void OnAppIconLoaded(apps::IconValuePtr icon_value); // Loads the default favicon to `icon_view_`. Should be called when we fail to // load an icon.
diff --git a/base/BUILD.gn b/base/BUILD.gn index 817a461f..5ae8a23c 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -29,6 +29,7 @@ import("//build/config/logging.gni") import("//build/config/nacl/config.gni") import("//build/config/profiling/profiling.gni") +import("//build/config/rust.gni") import("//build/config/sysroot.gni") import("//build/config/ui.gni") import("//build/nocompile.gni") @@ -703,6 +704,8 @@ "task/sequence_manager/thread_controller_with_message_pump_impl.h", "task/sequence_manager/time_domain.cc", "task/sequence_manager/time_domain.h", + "task/sequence_manager/wake_up_queue.cc", + "task/sequence_manager/wake_up_queue.h", "task/sequence_manager/work_deduplicator.cc", "task/sequence_manager/work_deduplicator.h", "task/sequence_manager/work_queue.cc", @@ -1454,6 +1457,19 @@ } } + if (enable_rust && toolchain_has_rust) { + # TODO(adetaylor): we include conversions between base and cxx's Rust types. + # We assume that any //base client who has flipped 'enable_rust' likely wants + # these, but it's conceivable that some clients might want to enable Rust + # without adding these cxx conversions. If so we would want to add an + # additional gn conditional e.g. enable_rust_binding_in_base + sources += [ + "containers/span_rust.h", + "strings/string_piece_rust.h", + ] + deps += [ "//build/rust:cxx_cppdeps" ] + } + if (use_clang_profiling) { # Call-sites use this conditional on the CLANG_PROFILING macro, for clarity. sources += [ @@ -3158,7 +3174,7 @@ "task/sequence_manager/test/mock_time_message_pump_unittest.cc", "task/sequence_manager/thread_controller_power_monitor_unittest.cc", "task/sequence_manager/thread_controller_with_message_pump_impl_unittest.cc", - "task/sequence_manager/time_domain_unittest.cc", + "task/sequence_manager/wake_up_queue_unittest.cc", "task/sequence_manager/work_deduplicator_unittest.cc", "task/sequence_manager/work_queue_sets_unittest.cc", "task/sequence_manager/work_queue_unittest.cc", @@ -3736,6 +3752,14 @@ ] } + if (enable_rust && toolchain_has_rust) { + sources += [ + "containers/span_rust_unittest.cc", + "strings/string_piece_rust_unittest.cc", + ] + deps += [ "//build/rust:cxx_cppdeps" ] + } + configs += [ ":memory_tagging" ] }
diff --git a/base/DEPS b/base/DEPS index 162a1bc..5f0151c 100644 --- a/base/DEPS +++ b/base/DEPS
@@ -8,6 +8,11 @@ "+third_party/modp_b64", "+third_party/perfetto/include", "+third_party/perfetto/protos/perfetto", + # Conversions between base and Rust types (e.g. base::span <-> rust::Slice) + # require the cxx.h header from cxx. This is only used if Rust is enabled + # in the gn build; see //base/BUILD.gn's conditional dependency on + # //build/rust:cxx_cppdeps. + "+third_party/rust/cxx", "+third_party/tcmalloc", "+third_party/test_fonts",
diff --git a/base/containers/span_rust.h b/base/containers/span_rust.h new file mode 100644 index 0000000..cbe8a3b --- /dev/null +++ b/base/containers/span_rust.h
@@ -0,0 +1,22 @@ +// 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 BASE_CONTAINERS_SPAN_RUST_H_ +#define BASE_CONTAINERS_SPAN_RUST_H_ + +#include <stdint.h> + +#include "base/containers/span.h" +#include "third_party/rust/cxx/v1/crate/include/cxx.h" + +namespace base { + +// Create a Rust slice from a base::span. +inline rust::Slice<const uint8_t> SpanToRustSlice(span<const uint8_t> span) { + return rust::Slice<const uint8_t>(span.data(), span.size()); +} + +} // namespace base + +#endif // BASE_CONTAINERS_SPAN_RUST_H_
diff --git a/base/containers/span_rust_unittest.cc b/base/containers/span_rust_unittest.cc new file mode 100644 index 0000000..5f17d13 --- /dev/null +++ b/base/containers/span_rust_unittest.cc
@@ -0,0 +1,21 @@ +// 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 "base/containers/span_rust.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +namespace { + +TEST(BaseSpanRustTest, SliceConstruct) { + uint8_t data[] = {0, 1, 2, 3, 4}; + span<const uint8_t> data_span(data, 2); + rust::Slice<const uint8_t> rust_slice = SpanToRustSlice(data_span); + EXPECT_EQ(2ul, rust_slice.length()); + EXPECT_EQ(1, rust_slice[1]); +} + +} // namespace +} // namespace base
diff --git a/base/process/kill.h b/base/process/kill.h index d66a0a9..8d236dbd 100644 --- a/base/process/kill.h +++ b/base/process/kill.h
@@ -13,7 +13,6 @@ #include "base/process/process_handle.h" #include "base/time/time.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" namespace base { @@ -54,7 +53,7 @@ TERMINATION_STATUS_PROCESS_WAS_KILLED, // e.g. SIGKILL or task manager kill TERMINATION_STATUS_PROCESS_CRASHED, // e.g. Segmentation fault TERMINATION_STATUS_STILL_RUNNING, // child hasn't exited yet -#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) +#if defined(OS_CHROMEOS) // Used for the case when oom-killer kills a process on ChromeOS. TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM, #endif
diff --git a/base/strings/string_piece_rust.h b/base/strings/string_piece_rust.h new file mode 100644 index 0000000..bfea383 --- /dev/null +++ b/base/strings/string_piece_rust.h
@@ -0,0 +1,38 @@ +// 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 BASE_STRINGS_STRING_PIECE_RUST_H_ +#define BASE_STRINGS_STRING_PIECE_RUST_H_ + +#include <stdint.h> + +#include "base/strings/string_piece.h" +#include "third_party/rust/cxx/v1/crate/include/cxx.h" + +namespace base { + +// Create a Rust str from a base::BasigStringPiece. This will call std::abort +// if there is any invalid UTF8. If you're concerned about this, then +// instead use StringPieceToRustSlice and convert the data to a string on +// the Rust side (or pass in a std::string). +inline rust::Str StringPieceToRustStrUTF8(StringPiece string_piece) { + return rust::Str(string_piece.data(), string_piece.size()); +} + +// Create a Rust slice from a StringPiece. No UTF8 check is performed. +inline rust::Slice<const uint8_t> StringPieceToRustSlice( + StringPiece string_piece) { + return rust::Slice<const uint8_t>( + reinterpret_cast<const uint8_t*>(string_piece.data()), + string_piece.length() * sizeof(StringPiece::value_type)); +} + +// Create a StringPiece from a Rust str. +inline StringPiece RustStrToStringPiece(rust::Str str) { + return StringPiece(str.data(), str.size()); +} + +} // namespace base + +#endif // BASE_STRINGS_STRING_PIECE_RUST_H_
diff --git a/base/strings/string_piece_rust_unittest.cc b/base/strings/string_piece_rust_unittest.cc new file mode 100644 index 0000000..7a2e4bc --- /dev/null +++ b/base/strings/string_piece_rust_unittest.cc
@@ -0,0 +1,30 @@ +// 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 "base/strings/string_piece_rust.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +namespace { + +TEST(BaseStringPieceRustTest, StrRoundTrip) { + std::string data = "hello"; + StringPiece data_piece(data); + rust::Str rust_str = StringPieceToRustStrUTF8(data_piece); + EXPECT_EQ(5ul, rust_str.length()); + StringPiece data_piece2 = RustStrToStringPiece(rust_str); + EXPECT_EQ(data_piece, data_piece2); +} + +TEST(BaseStringPieceRustTest, StrToSlice) { + std::string data = "hello"; + StringPiece data_piece(data); + rust::Slice<const uint8_t> rust_slice = StringPieceToRustSlice(data_piece); + EXPECT_EQ(5ul, rust_slice.length()); + EXPECT_EQ('e', rust_slice[1]); +} + +} // namespace +} // namespace base
diff --git a/base/task/sequence_manager/sequence_manager_impl.cc b/base/task/sequence_manager/sequence_manager_impl.cc index 27fb410b..c9a56ec0 100644 --- a/base/task/sequence_manager/sequence_manager_impl.cc +++ b/base/task/sequence_manager/sequence_manager_impl.cc
@@ -25,6 +25,7 @@ #include "base/task/sequence_manager/thread_controller_impl.h" #include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h" #include "base/task/sequence_manager/time_domain.h" +#include "base/task/sequence_manager/wake_up_queue.h" #include "base/task/sequence_manager/work_queue.h" #include "base/task/sequence_manager/work_queue_sets.h" #include "base/threading/thread_id_name_manager.h"
diff --git a/base/task/sequence_manager/task_queue_impl.cc b/base/task/sequence_manager/task_queue_impl.cc index 4ee60d2..0399ba5 100644 --- a/base/task/sequence_manager/task_queue_impl.cc +++ b/base/task/sequence_manager/task_queue_impl.cc
@@ -16,7 +16,7 @@ #include "base/strings/stringprintf.h" #include "base/task/common/scoped_defer_task_posting.h" #include "base/task/sequence_manager/sequence_manager_impl.h" -#include "base/task/sequence_manager/time_domain.h" +#include "base/task/sequence_manager/wake_up_queue.h" #include "base/task/sequence_manager/work_queue.h" #include "base/task/task_observer.h" #include "base/threading/thread_restrictions.h" @@ -558,14 +558,13 @@ StackVector<Task, 8> tasks_to_delete; while (!main_thread_only().delayed_incoming_queue.empty()) { - Task* task = - const_cast<Task*>(&main_thread_only().delayed_incoming_queue.top()); - CHECK(task->task); - if (!task->task.IsCancelled()) + const Task& task = main_thread_only().delayed_incoming_queue.top(); + CHECK(task.task); + if (!task.task.IsCancelled()) break; - tasks_to_delete->push_back(std::move(*task)); - main_thread_only().delayed_incoming_queue.pop(); + tasks_to_delete->push_back( + main_thread_only().delayed_incoming_queue.take_top()); } if (!tasks_to_delete->empty()) { @@ -588,28 +587,32 @@ StackVector<Task, 8> tasks_to_delete; while (!main_thread_only().delayed_incoming_queue.empty()) { - Task& task = - const_cast<Task&>(main_thread_only().delayed_incoming_queue.top()); + const Task& task = main_thread_only().delayed_incoming_queue.top(); CHECK(task.task); - if (task.task.IsCancelled()) { - tasks_to_delete->push_back(std::move(task)); - main_thread_only().delayed_incoming_queue.pop(); - continue; - } - if (task.delayed_run_time > lazy_now->Now()) + + // Leave the top task alone if it hasn't been canceled and it is not ready. + const bool is_cancelled = task.task.IsCancelled(); + if (!is_cancelled && task.delayed_run_time > lazy_now->Now()) break; + Task ready_task = main_thread_only().delayed_incoming_queue.take_top(); + if (is_cancelled) { + tasks_to_delete->push_back(std::move(ready_task)); + continue; + } + + // The top task is ready to run. Move it to the delayed work queue. #if DCHECK_IS_ON() if (sequence_manager_->settings().log_task_delay_expiry) - VLOG(0) << name_ << " Delay expired for " << task.posted_from.ToString(); + VLOG(0) << name_ << " Delay expired for " + << ready_task.posted_from.ToString(); #endif // DCHECK_IS_ON() - DCHECK(!task.delayed_run_time.is_null()); - ActivateDelayedFenceIfNeeded(task.delayed_run_time); - DCHECK(!task.enqueue_order_set()); - task.set_enqueue_order(sequence_manager_->GetNextSequenceNumber()); + DCHECK(!ready_task.delayed_run_time.is_null()); + ActivateDelayedFenceIfNeeded(ready_task.delayed_run_time); + DCHECK(!ready_task.enqueue_order_set()); + ready_task.set_enqueue_order(sequence_manager_->GetNextSequenceNumber()); - delayed_work_queue_task_pusher.Push(std::move(task)); - main_thread_only().delayed_incoming_queue.pop(); + delayed_work_queue_task_pusher.Push(std::move(ready_task)); } // Explicitly delete tasks last. @@ -1342,16 +1345,16 @@ CHECK(task.task); if (task.is_high_res) pending_high_res_tasks_++; - queue_.push(std::move(task)); + queue_.insert(std::move(task)); } -void TaskQueueImpl::DelayedIncomingQueue::pop() { +Task TaskQueueImpl::DelayedIncomingQueue::take_top() { DCHECK(!empty()); if (top().is_high_res) { pending_high_res_tasks_--; DCHECK_GE(pending_high_res_tasks_, 0); } - queue_.pop(); + return queue_.take_top(); } void TaskQueueImpl::DelayedIncomingQueue::swap(DelayedIncomingQueue* rhs) { @@ -1361,49 +1364,23 @@ void TaskQueueImpl::DelayedIncomingQueue::SweepCancelledTasks( SequenceManagerImpl* sequence_manager) { - pending_high_res_tasks_ -= queue_.SweepCancelledTasks(sequence_manager); -} - -size_t TaskQueueImpl::DelayedIncomingQueue::PQueue::SweepCancelledTasks( - SequenceManagerImpl* sequence_manager) { - // Under the hood a std::priority_queue is a heap implemented top of a - // std::vector. We poke at that vector directly here to filter out canceled - // tasks in place. - size_t num_high_res_tasks_swept = 0u; - auto keep_task = [&num_high_res_tasks_swept](const Task& task) { - if (!task.task.IsCancelled()) + // Note: IntrusiveHeap::EraseIf() is safe against re-entrancy caused by + // deleted tasks posting new tasks. + queue_.EraseIf([this](const Task& task) { + if (task.task.IsCancelled()) { + if (task.is_high_res) { + --pending_high_res_tasks_; + DCHECK_GE(pending_high_res_tasks_, 0); + } return true; - if (task.is_high_res) - num_high_res_tasks_swept++; + } return false; - }; - - // Because task destructors could have a side-effect of posting new tasks, we - // move all the cancelled tasks into a temporary container before deleting - // them. This is to avoid |c| from changing while c.erase() is running. - auto delete_start = std::stable_partition(c.begin(), c.end(), keep_task); - StackVector<Task, 8> tasks_to_delete; - std::move(delete_start, c.end(), - std::back_inserter(tasks_to_delete.container())); - c.erase(delete_start, c.end()); - - // stable_partition ensures order was not changed if there was nothing to - // delete. - if (!tasks_to_delete->empty()) { - ranges::make_heap(c, comp); - tasks_to_delete->clear(); - } - return num_high_res_tasks_swept; + }); } Value TaskQueueImpl::DelayedIncomingQueue::AsValue(TimeTicks now) const { - return queue_.AsValue(now); -} - -Value TaskQueueImpl::DelayedIncomingQueue::PQueue::AsValue( - TimeTicks now) const { Value state(Value::Type::LIST); - for (const Task& task : c) + for (const Task& task : queue_) state.Append(TaskAsValue(task, now)); return state; }
diff --git a/base/task/sequence_manager/task_queue_impl.h b/base/task/sequence_manager/task_queue_impl.h index e27a459..8ee1e01 100644 --- a/base/task/sequence_manager/task_queue_impl.h +++ b/base/task/sequence_manager/task_queue_impl.h
@@ -335,7 +335,7 @@ ~DelayedIncomingQueue(); void push(Task task); - void pop(); + Task take_top(); bool empty() const { return queue_.empty(); } size_t size() const { return queue_.size(); } const Task& top() const { return queue_.top(); } @@ -351,19 +351,20 @@ Value AsValue(TimeTicks now) const; private: - struct PQueue - : public std::priority_queue<Task, std::vector<Task>, std::greater<>> { - // Removes all cancelled tasks from the queue. Returns the number of - // removed high resolution tasks (which could be lower than the total - // number of removed tasks). - // - // TODO(crbug.com/1155905): we pass SequenceManager to be able to record - // crash keys. Remove this parameter after chasing down this crash. - size_t SweepCancelledTasks(SequenceManagerImpl* sequence_manager); - Value AsValue(TimeTicks now) const; + // An implementation of HeapHandleAccessor that doesn't keep the heap + // handles up-to-date. Useful if elements are never accessed using their + // handles. + // TODO(pmonette): Use a full implementation of HeapHandleAccessor once + // TaskQueueImpl supports removing tasks from the + // DelayedIncomingQueue using heap handles. + struct NullHeapHandleAccessor { + void SetHeapHandle(Task* element, HeapHandle handle) const {} + void ClearHeapHandle(Task* element) const {} + HeapHandle GetHeapHandle(const Task* element) const { + return HeapHandle::Invalid(); + } }; - - PQueue queue_; + IntrusiveHeap<Task, std::greater<>, NullHeapHandleAccessor> queue_; // Number of pending tasks in the queue that need high resolution timing. int pending_high_res_tasks_ = 0;
diff --git a/base/task/sequence_manager/time_domain.cc b/base/task/sequence_manager/time_domain.cc index db84f84..d0c8f25c 100644 --- a/base/task/sequence_manager/time_domain.cc +++ b/base/task/sequence_manager/time_domain.cc
@@ -4,9 +4,7 @@ #include "base/task/sequence_manager/time_domain.h" -#include "base/task/sequence_manager/associated_thread_id.h" #include "base/task/sequence_manager/sequence_manager_impl.h" -#include "base/task/sequence_manager/work_queue.h" #include "base/threading/thread_checker.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -29,174 +27,5 @@ return state; } -namespace internal { - -WakeUpQueue::WakeUpQueue( - scoped_refptr<internal::AssociatedThreadId> associated_thread) - : associated_thread_(std::move(associated_thread)) {} - -WakeUpQueue::~WakeUpQueue() { - DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); -} - -void WakeUpQueue::RemoveAllCanceledDelayedTasksFromFront(LazyNow* lazy_now) { - // Repeatedly trim the front of the top queue until it stabilizes. This is - // needed because a different queue can become the top one once you remove the - // canceled tasks. - while (!wake_up_queue_.empty()) { - auto* top_queue = wake_up_queue_.top().queue; - - // If no tasks are removed from the top queue, then it means the top queue - // cannot change anymore. - if (!top_queue->RemoveAllCanceledDelayedTasksFromFront(lazy_now)) - break; - } -} - -// TODO(kraynov): https://crbug.com/857101 Consider making an interface -// for SequenceManagerImpl which will expose SetNextDelayedDoWork and -// MaybeScheduleImmediateWork methods to make the functions below pure-virtual. - -void WakeUpQueue::SetNextWakeUpForQueue(internal::TaskQueueImpl* queue, - LazyNow* lazy_now, - absl::optional<DelayedWakeUp> wake_up) { - DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); - DCHECK_EQ(queue->wake_up_queue(), this); - DCHECK(queue->IsQueueEnabled() || !wake_up); - - absl::optional<TimeTicks> previous_wake_up; - absl::optional<WakeUpResolution> previous_queue_resolution; - if (!wake_up_queue_.empty()) - previous_wake_up = wake_up_queue_.top().wake_up.time; - if (queue->heap_handle().IsValid()) { - previous_queue_resolution = - wake_up_queue_.at(queue->heap_handle()).wake_up.resolution; - } - - if (wake_up) { - // Insert a new wake-up into the heap. - if (queue->heap_handle().IsValid()) { - // O(log n) - wake_up_queue_.Replace(queue->heap_handle(), {wake_up.value(), queue}); - } else { - // O(log n) - wake_up_queue_.insert({wake_up.value(), queue}); - } - } else { - // Remove a wake-up from heap if present. - if (queue->heap_handle().IsValid()) - wake_up_queue_.erase(queue->heap_handle()); - } - - absl::optional<TimeTicks> new_wake_up; - if (!wake_up_queue_.empty()) - new_wake_up = wake_up_queue_.top().wake_up.time; - - if (previous_queue_resolution && - *previous_queue_resolution == WakeUpResolution::kHigh) { - pending_high_res_wake_up_count_--; - } - if (wake_up && wake_up->resolution == WakeUpResolution::kHigh) - pending_high_res_wake_up_count_++; - DCHECK_GE(pending_high_res_wake_up_count_, 0); - - if (new_wake_up != previous_wake_up) - OnNextDelayedWakeUpChanged(lazy_now, GetNextDelayedWakeUp()); -} - -void WakeUpQueue::MoveReadyDelayedTasksToWorkQueues(LazyNow* lazy_now) { - DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); - // Wake up any queues with pending delayed work. - bool update_needed = false; - while (!wake_up_queue_.empty() && - wake_up_queue_.top().wake_up.time <= lazy_now->Now()) { - internal::TaskQueueImpl* queue = wake_up_queue_.top().queue; - // OnWakeUp() is expected to update the next wake-up for this queue with - // SetNextWakeUpForQueue(), thus allowing us to make progress. - queue->OnWakeUp(lazy_now); - update_needed = true; - } - if (!update_needed || wake_up_queue_.empty()) - return; - // If any queue was notified, possibly update following queues. This ensures - // the wake up is up to date, which is necessary because calling OnWakeUp() on - // a throttled queue may affect state that is shared between other related - // throttled queues. The wake up for an affected queue might be pushed back - // and needs to be updated. This is done lazily only once the related queue - // becomes the next one to wake up, since that wake up can't be moved up. - // `wake_up_queue_` is non-empty here, per the condition above. - internal::TaskQueueImpl* queue = wake_up_queue_.top().queue; - queue->UpdateDelayedWakeUp(lazy_now); - while (!wake_up_queue_.empty()) { - internal::TaskQueueImpl* old_queue = - std::exchange(queue, wake_up_queue_.top().queue); - if (old_queue == queue) - break; - queue->UpdateDelayedWakeUp(lazy_now); - } -} - -absl::optional<DelayedWakeUp> WakeUpQueue::GetNextDelayedWakeUp() const { - DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); - if (wake_up_queue_.empty()) - return absl::nullopt; - return wake_up_queue_.top().wake_up; -} - -Value WakeUpQueue::AsValue(TimeTicks now) const { - Value state(Value::Type::DICTIONARY); - state.SetStringKey("name", GetName()); - state.SetIntKey("registered_delay_count", wake_up_queue_.size()); - if (!wake_up_queue_.empty()) { - TimeDelta delay = wake_up_queue_.top().wake_up.time - now; - state.SetDoubleKey("next_delay_ms", delay.InMillisecondsF()); - } - return state; -} - -DefaultWakeUpQueue::DefaultWakeUpQueue( - scoped_refptr<internal::AssociatedThreadId> associated_thread, - internal::SequenceManagerImpl* sequence_manager) - : WakeUpQueue(std::move(associated_thread)), - sequence_manager_(sequence_manager) {} - -DefaultWakeUpQueue::~DefaultWakeUpQueue() = default; - -void DefaultWakeUpQueue::OnNextDelayedWakeUpChanged( - LazyNow* lazy_now, - absl::optional<DelayedWakeUp> wake_up) { - sequence_manager_->SetNextDelayedWakeUp(lazy_now, wake_up); -} - -void DefaultWakeUpQueue::UnregisterQueue(internal::TaskQueueImpl* queue) { - DCHECK_EQ(queue->wake_up_queue(), this); - LazyNow lazy_now(sequence_manager_->main_thread_clock()); - SetNextWakeUpForQueue(queue, &lazy_now, absl::nullopt); -} - -const char* DefaultWakeUpQueue::GetName() const { - return "DefaultWakeUpQueue"; -} - -NonWakingWakeUpQueue::NonWakingWakeUpQueue( - scoped_refptr<internal::AssociatedThreadId> associated_thread) - : WakeUpQueue(std::move(associated_thread)) {} - -NonWakingWakeUpQueue::~NonWakingWakeUpQueue() = default; - -void NonWakingWakeUpQueue::OnNextDelayedWakeUpChanged( - LazyNow* lazy_now, - absl::optional<DelayedWakeUp> wake_up) {} - -const char* NonWakingWakeUpQueue::GetName() const { - return "NonWakingWakeUpQueue"; -} - -void NonWakingWakeUpQueue::UnregisterQueue(internal::TaskQueueImpl* queue) { - DCHECK_EQ(queue->wake_up_queue(), this); - SetNextWakeUpForQueue(queue, nullptr, absl::nullopt); -} - -} // namespace internal } // namespace sequence_manager } // namespace base
diff --git a/base/task/sequence_manager/time_domain.h b/base/task/sequence_manager/time_domain.h index bf146dc..a860efb2 100644 --- a/base/task/sequence_manager/time_domain.h +++ b/base/task/sequence_manager/time_domain.h
@@ -6,9 +6,7 @@ #define BASE_TASK_SEQUENCE_MANAGER_TIME_DOMAIN_H_ #include "base/check.h" -#include "base/containers/intrusive_heap.h" #include "base/task/sequence_manager/lazy_now.h" -#include "base/task/sequence_manager/task_queue_impl.h" #include "base/task/sequence_manager/tasks.h" #include "base/time/tick_clock.h" #include "base/values.h" @@ -20,7 +18,6 @@ class SequenceManager; namespace internal { -class AssociatedThreadId; class SequenceManagerImpl; } // namespace internal @@ -72,132 +69,6 @@ internal::SequenceManagerImpl* sequence_manager_ = nullptr; // Not owned. }; -namespace internal { - -// WakeUpQueue is a queue of (wake_up, TaskQueueImpl*) pairs which -// aggregates wake-ups from multiple TaskQueueImpl into a single wake-up, and -// notifies TaskQueueImpls when wake-up times are reached. -class BASE_EXPORT WakeUpQueue { - public: - WakeUpQueue(const WakeUpQueue&) = delete; - WakeUpQueue& operator=(const WakeUpQueue&) = delete; - virtual ~WakeUpQueue(); - - // Returns a wake-up for the next pending delayed task (pending delayed tasks - // that are ripe may be ignored). If there are no such tasks (immediate tasks - // don't count) or queues are disabled it returns nullopt. - absl::optional<DelayedWakeUp> GetNextDelayedWakeUp() const; - - // Debug info. - Value AsValue(TimeTicks now) const; - - bool has_pending_high_resolution_tasks() const { - return pending_high_res_wake_up_count_; - } - - // Returns true if there are no pending delayed tasks. - bool empty() const { return wake_up_queue_.empty(); } - - // Moves ready delayed tasks in TaskQueues to delayed WorkQueues, consuming - // expired wake-ups in the process. - void MoveReadyDelayedTasksToWorkQueues(LazyNow* lazy_now); - - // Schedule `queue` to wake up at certain time. Repeating calls with the same - // `queue` invalidate previous requests. Nullopt `wake_up` cancels a - // previously set wake up for `queue`. - void SetNextWakeUpForQueue(internal::TaskQueueImpl* queue, - LazyNow* lazy_now, - absl::optional<DelayedWakeUp> wake_up); - - // Remove the TaskQueue from any internal data structures. - virtual void UnregisterQueue(internal::TaskQueueImpl* queue) = 0; - - // Removes all canceled delayed tasks from the front of the queue. After - // calling this, GetNextDelayedWakeUp() is guaranteed to return a wake up time - // for a non-canceled task. - void RemoveAllCanceledDelayedTasksFromFront(LazyNow* lazy_now); - - protected: - explicit WakeUpQueue( - scoped_refptr<internal::AssociatedThreadId> associated_thread); - - // Called every time the next `next_wake_up` changes. absl::nullopt is used to - // cancel the next wake-up. Subclasses may use this to tell SequenceManager to - // schedule the next wake-up at the given time. - virtual void OnNextDelayedWakeUpChanged( - LazyNow* lazy_now, - absl::optional<DelayedWakeUp> next_wake_up) = 0; - - virtual const char* GetName() const = 0; - - private: - friend class MockWakeUpQueue; - - struct ScheduledDelayedWakeUp { - DelayedWakeUp wake_up; - internal::TaskQueueImpl* queue; - - bool operator>(const ScheduledDelayedWakeUp& other) const { - return wake_up > other.wake_up; - } - - void SetHeapHandle(HeapHandle handle) { - DCHECK(handle.IsValid()); - queue->set_heap_handle(handle); - } - - void ClearHeapHandle() { - DCHECK(queue->heap_handle().IsValid()); - queue->set_heap_handle(HeapHandle()); - } - - HeapHandle GetHeapHandle() const { return queue->heap_handle(); } - }; - - IntrusiveHeap<ScheduledDelayedWakeUp, std::greater<>> wake_up_queue_; - int pending_high_res_wake_up_count_ = 0; - - scoped_refptr<internal::AssociatedThreadId> associated_thread_; -}; - -// Default WakeUpQueue implementation that forwards wake-ups to -// `sequence_manager_`. -class BASE_EXPORT DefaultWakeUpQueue : public WakeUpQueue { - public: - DefaultWakeUpQueue( - scoped_refptr<internal::AssociatedThreadId> associated_thread, - internal::SequenceManagerImpl* sequence_manager); - ~DefaultWakeUpQueue() override; - - private: - // WakeUpQueue implementation: - void OnNextDelayedWakeUpChanged( - LazyNow* lazy_now, - absl::optional<DelayedWakeUp> wake_up) override; - const char* GetName() const override; - void UnregisterQueue(internal::TaskQueueImpl* queue) override; - - internal::SequenceManagerImpl* sequence_manager_; // Not owned. -}; - -// WakeUpQueue implementation that doesn't sends wake-ups to -// any SequenceManager, such that task queues don't cause wake-ups. -class BASE_EXPORT NonWakingWakeUpQueue : public WakeUpQueue { - public: - explicit NonWakingWakeUpQueue( - scoped_refptr<internal::AssociatedThreadId> associated_thread); - ~NonWakingWakeUpQueue() override; - - private: - // WakeUpQueue implementation: - void OnNextDelayedWakeUpChanged( - LazyNow* lazy_now, - absl::optional<DelayedWakeUp> wake_up) override; - const char* GetName() const override; - void UnregisterQueue(internal::TaskQueueImpl* queue) override; -}; - -} // namespace internal } // namespace sequence_manager } // namespace base
diff --git a/base/task/sequence_manager/wake_up_queue.cc b/base/task/sequence_manager/wake_up_queue.cc new file mode 100644 index 0000000..af2c7706 --- /dev/null +++ b/base/task/sequence_manager/wake_up_queue.cc
@@ -0,0 +1,185 @@ +// 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 "base/task/sequence_manager/wake_up_queue.h" + +#include "base/task/sequence_manager/associated_thread_id.h" +#include "base/task/sequence_manager/sequence_manager_impl.h" +#include "base/task/sequence_manager/task_queue_impl.h" +#include "base/threading/thread_checker.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace base { +namespace sequence_manager { +namespace internal { + +WakeUpQueue::WakeUpQueue( + scoped_refptr<internal::AssociatedThreadId> associated_thread) + : associated_thread_(std::move(associated_thread)) {} + +WakeUpQueue::~WakeUpQueue() { + DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); +} + +void WakeUpQueue::RemoveAllCanceledDelayedTasksFromFront(LazyNow* lazy_now) { + // Repeatedly trim the front of the top queue until it stabilizes. This is + // needed because a different queue can become the top one once you remove the + // canceled tasks. + while (!wake_up_queue_.empty()) { + auto* top_queue = wake_up_queue_.top().queue; + + // If no tasks are removed from the top queue, then it means the top queue + // cannot change anymore. + if (!top_queue->RemoveAllCanceledDelayedTasksFromFront(lazy_now)) + break; + } +} + +// TODO(kraynov): https://crbug.com/857101 Consider making an interface +// for SequenceManagerImpl which will expose SetNextDelayedDoWork and +// MaybeScheduleImmediateWork methods to make the functions below pure-virtual. + +void WakeUpQueue::SetNextWakeUpForQueue(internal::TaskQueueImpl* queue, + LazyNow* lazy_now, + absl::optional<DelayedWakeUp> wake_up) { + DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); + DCHECK_EQ(queue->wake_up_queue(), this); + DCHECK(queue->IsQueueEnabled() || !wake_up); + + absl::optional<TimeTicks> previous_wake_up; + absl::optional<WakeUpResolution> previous_queue_resolution; + if (!wake_up_queue_.empty()) + previous_wake_up = wake_up_queue_.top().wake_up.time; + if (queue->heap_handle().IsValid()) { + previous_queue_resolution = + wake_up_queue_.at(queue->heap_handle()).wake_up.resolution; + } + + if (wake_up) { + // Insert a new wake-up into the heap. + if (queue->heap_handle().IsValid()) { + // O(log n) + wake_up_queue_.Replace(queue->heap_handle(), {wake_up.value(), queue}); + } else { + // O(log n) + wake_up_queue_.insert({wake_up.value(), queue}); + } + } else { + // Remove a wake-up from heap if present. + if (queue->heap_handle().IsValid()) + wake_up_queue_.erase(queue->heap_handle()); + } + + absl::optional<TimeTicks> new_wake_up; + if (!wake_up_queue_.empty()) + new_wake_up = wake_up_queue_.top().wake_up.time; + + if (previous_queue_resolution && + *previous_queue_resolution == WakeUpResolution::kHigh) { + pending_high_res_wake_up_count_--; + } + if (wake_up && wake_up->resolution == WakeUpResolution::kHigh) + pending_high_res_wake_up_count_++; + DCHECK_GE(pending_high_res_wake_up_count_, 0); + + if (new_wake_up != previous_wake_up) + OnNextDelayedWakeUpChanged(lazy_now, GetNextDelayedWakeUp()); +} + +void WakeUpQueue::MoveReadyDelayedTasksToWorkQueues(LazyNow* lazy_now) { + DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); + // Wake up any queues with pending delayed work. + bool update_needed = false; + while (!wake_up_queue_.empty() && + wake_up_queue_.top().wake_up.time <= lazy_now->Now()) { + internal::TaskQueueImpl* queue = wake_up_queue_.top().queue; + // OnWakeUp() is expected to update the next wake-up for this queue with + // SetNextWakeUpForQueue(), thus allowing us to make progress. + queue->OnWakeUp(lazy_now); + update_needed = true; + } + if (!update_needed || wake_up_queue_.empty()) + return; + // If any queue was notified, possibly update following queues. This ensures + // the wake up is up to date, which is necessary because calling OnWakeUp() on + // a throttled queue may affect state that is shared between other related + // throttled queues. The wake up for an affected queue might be pushed back + // and needs to be updated. This is done lazily only once the related queue + // becomes the next one to wake up, since that wake up can't be moved up. + // `wake_up_queue_` is non-empty here, per the condition above. + internal::TaskQueueImpl* queue = wake_up_queue_.top().queue; + queue->UpdateDelayedWakeUp(lazy_now); + while (!wake_up_queue_.empty()) { + internal::TaskQueueImpl* old_queue = + std::exchange(queue, wake_up_queue_.top().queue); + if (old_queue == queue) + break; + queue->UpdateDelayedWakeUp(lazy_now); + } +} + +absl::optional<DelayedWakeUp> WakeUpQueue::GetNextDelayedWakeUp() const { + DCHECK_CALLED_ON_VALID_THREAD(associated_thread_->thread_checker); + if (wake_up_queue_.empty()) + return absl::nullopt; + return wake_up_queue_.top().wake_up; +} + +Value WakeUpQueue::AsValue(TimeTicks now) const { + Value state(Value::Type::DICTIONARY); + state.SetStringKey("name", GetName()); + state.SetIntKey("registered_delay_count", wake_up_queue_.size()); + if (!wake_up_queue_.empty()) { + TimeDelta delay = wake_up_queue_.top().wake_up.time - now; + state.SetDoubleKey("next_delay_ms", delay.InMillisecondsF()); + } + return state; +} + +DefaultWakeUpQueue::DefaultWakeUpQueue( + scoped_refptr<internal::AssociatedThreadId> associated_thread, + internal::SequenceManagerImpl* sequence_manager) + : WakeUpQueue(std::move(associated_thread)), + sequence_manager_(sequence_manager) {} + +DefaultWakeUpQueue::~DefaultWakeUpQueue() = default; + +void DefaultWakeUpQueue::OnNextDelayedWakeUpChanged( + LazyNow* lazy_now, + absl::optional<DelayedWakeUp> wake_up) { + sequence_manager_->SetNextDelayedWakeUp(lazy_now, wake_up); +} + +void DefaultWakeUpQueue::UnregisterQueue(internal::TaskQueueImpl* queue) { + DCHECK_EQ(queue->wake_up_queue(), this); + LazyNow lazy_now(sequence_manager_->main_thread_clock()); + SetNextWakeUpForQueue(queue, &lazy_now, absl::nullopt); +} + +const char* DefaultWakeUpQueue::GetName() const { + return "DefaultWakeUpQueue"; +} + +NonWakingWakeUpQueue::NonWakingWakeUpQueue( + scoped_refptr<internal::AssociatedThreadId> associated_thread) + : WakeUpQueue(std::move(associated_thread)) {} + +NonWakingWakeUpQueue::~NonWakingWakeUpQueue() = default; + +void NonWakingWakeUpQueue::OnNextDelayedWakeUpChanged( + LazyNow* lazy_now, + absl::optional<DelayedWakeUp> wake_up) {} + +const char* NonWakingWakeUpQueue::GetName() const { + return "NonWakingWakeUpQueue"; +} + +void NonWakingWakeUpQueue::UnregisterQueue(internal::TaskQueueImpl* queue) { + DCHECK_EQ(queue->wake_up_queue(), this); + SetNextWakeUpForQueue(queue, nullptr, absl::nullopt); +} + +} // namespace internal +} // namespace sequence_manager +} // namespace base
diff --git a/base/task/sequence_manager/wake_up_queue.h b/base/task/sequence_manager/wake_up_queue.h new file mode 100644 index 0000000..3384f6e --- /dev/null +++ b/base/task/sequence_manager/wake_up_queue.h
@@ -0,0 +1,151 @@ +// 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 BASE_TASK_SEQUENCE_MANAGER_WAKE_UP_QUEUE_H_ +#define BASE_TASK_SEQUENCE_MANAGER_WAKE_UP_QUEUE_H_ + +#include "base/check.h" +#include "base/containers/intrusive_heap.h" +#include "base/task/sequence_manager/lazy_now.h" +#include "base/task/sequence_manager/task_queue_impl.h" +#include "base/time/time.h" +#include "base/values.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace base { +namespace sequence_manager { +namespace internal { + +class AssociatedThreadId; +class SequenceManagerImpl; +class TaskQueueImpl; + +// WakeUpQueue is a queue of (wake_up, TaskQueueImpl*) pairs which +// aggregates wake-ups from multiple TaskQueueImpl into a single wake-up, and +// notifies TaskQueueImpls when wake-up times are reached. +class BASE_EXPORT WakeUpQueue { + public: + WakeUpQueue(const WakeUpQueue&) = delete; + WakeUpQueue& operator=(const WakeUpQueue&) = delete; + virtual ~WakeUpQueue(); + + // Returns a wake-up for the next pending delayed task (pending delayed tasks + // that are ripe may be ignored). If there are no such tasks (immediate tasks + // don't count) or queues are disabled it returns nullopt. + absl::optional<DelayedWakeUp> GetNextDelayedWakeUp() const; + + // Debug info. + Value AsValue(TimeTicks now) const; + + bool has_pending_high_resolution_tasks() const { + return pending_high_res_wake_up_count_; + } + + // Returns true if there are no pending delayed tasks. + bool empty() const { return wake_up_queue_.empty(); } + + // Moves ready delayed tasks in TaskQueues to delayed WorkQueues, consuming + // expired wake-ups in the process. + void MoveReadyDelayedTasksToWorkQueues(LazyNow* lazy_now); + + // Schedule `queue` to wake up at certain time. Repeating calls with the same + // `queue` invalidate previous requests. Nullopt `wake_up` cancels a + // previously set wake up for `queue`. + void SetNextWakeUpForQueue(internal::TaskQueueImpl* queue, + LazyNow* lazy_now, + absl::optional<DelayedWakeUp> wake_up); + + // Remove the TaskQueue from any internal data structures. + virtual void UnregisterQueue(internal::TaskQueueImpl* queue) = 0; + + // Removes all canceled delayed tasks from the front of the queue. After + // calling this, GetNextDelayedWakeUp() is guaranteed to return a wake up time + // for a non-canceled task. + void RemoveAllCanceledDelayedTasksFromFront(LazyNow* lazy_now); + + protected: + explicit WakeUpQueue( + scoped_refptr<internal::AssociatedThreadId> associated_thread); + + // Called every time the next `next_wake_up` changes. absl::nullopt is used to + // cancel the next wake-up. Subclasses may use this to tell SequenceManager to + // schedule the next wake-up at the given time. + virtual void OnNextDelayedWakeUpChanged( + LazyNow* lazy_now, + absl::optional<DelayedWakeUp> next_wake_up) = 0; + + virtual const char* GetName() const = 0; + + private: + friend class MockWakeUpQueue; + + struct ScheduledDelayedWakeUp { + DelayedWakeUp wake_up; + internal::TaskQueueImpl* queue; + + bool operator>(const ScheduledDelayedWakeUp& other) const { + return wake_up > other.wake_up; + } + + void SetHeapHandle(HeapHandle handle) { + DCHECK(handle.IsValid()); + queue->set_heap_handle(handle); + } + + void ClearHeapHandle() { + DCHECK(queue->heap_handle().IsValid()); + queue->set_heap_handle(HeapHandle()); + } + + HeapHandle GetHeapHandle() const { return queue->heap_handle(); } + }; + + IntrusiveHeap<ScheduledDelayedWakeUp, std::greater<>> wake_up_queue_; + int pending_high_res_wake_up_count_ = 0; + + scoped_refptr<internal::AssociatedThreadId> associated_thread_; +}; + +// Default WakeUpQueue implementation that forwards wake-ups to +// `sequence_manager_`. +class BASE_EXPORT DefaultWakeUpQueue : public WakeUpQueue { + public: + DefaultWakeUpQueue( + scoped_refptr<internal::AssociatedThreadId> associated_thread, + internal::SequenceManagerImpl* sequence_manager); + ~DefaultWakeUpQueue() override; + + private: + // WakeUpQueue implementation: + void OnNextDelayedWakeUpChanged( + LazyNow* lazy_now, + absl::optional<DelayedWakeUp> wake_up) override; + const char* GetName() const override; + void UnregisterQueue(internal::TaskQueueImpl* queue) override; + + internal::SequenceManagerImpl* sequence_manager_; // Not owned. +}; + +// WakeUpQueue implementation that doesn't sends wake-ups to +// any SequenceManager, such that task queues don't cause wake-ups. +class BASE_EXPORT NonWakingWakeUpQueue : public WakeUpQueue { + public: + explicit NonWakingWakeUpQueue( + scoped_refptr<internal::AssociatedThreadId> associated_thread); + ~NonWakingWakeUpQueue() override; + + private: + // WakeUpQueue implementation: + void OnNextDelayedWakeUpChanged( + LazyNow* lazy_now, + absl::optional<DelayedWakeUp> wake_up) override; + const char* GetName() const override; + void UnregisterQueue(internal::TaskQueueImpl* queue) override; +}; + +} // namespace internal +} // namespace sequence_manager +} // namespace base + +#endif // BASE_TASK_SEQUENCE_MANAGER_WAKE_UP_QUEUE_H_
diff --git a/base/task/sequence_manager/time_domain_unittest.cc b/base/task/sequence_manager/wake_up_queue_unittest.cc similarity index 99% rename from base/task/sequence_manager/time_domain_unittest.cc rename to base/task/sequence_manager/wake_up_queue_unittest.cc index a35faa4d..685e3647 100644 --- a/base/task/sequence_manager/time_domain_unittest.cc +++ b/base/task/sequence_manager/wake_up_queue_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/task/sequence_manager/time_domain.h" +#include "base/task/sequence_manager/wake_up_queue.h" #include <memory>
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 6c82220..8870976 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -7.20211116.2.1 +7.20211116.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index 6c82220..8870976 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -7.20211116.2.1 +7.20211116.3.1
diff --git a/build/rust/BUILD.gn b/build/rust/BUILD.gn index ce224875..d9ab10c 100644 --- a/build/rust/BUILD.gn +++ b/build/rust/BUILD.gn
@@ -27,6 +27,18 @@ "//third_party/rust/cxx/v1/crate/include/cxx.h", "//third_party/rust/cxx/v1/crate/src/cxx.cc", ] + + # Depending on the C++ bindings side of cxx then requires also depending + # on the Rust bindings, since one calls the other. And the Rust bindings + # require the Rust standard library. + # Normally the Rust stdlib is brought in as a dependency by depending + # on any first-party Rust target. But in this case, it's conceivable + # that pure-C++ targets will not depend on any 1p Rust code so we'll add + # the Rust stdlib explicitly. + deps = [ + ":cxx_rustdeps", + "//build/rust/std", + ] public_configs = [ ":cxx_cppconfig" ] }
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 39c910ef..7f3ffb8 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -122,8 +122,6 @@ "layers/picture_layer_impl.h", "layers/recording_source.cc", "layers/recording_source.h", - "layers/region_capture_bounds.cc", - "layers/region_capture_bounds.h", "layers/render_surface_impl.cc", "layers/render_surface_impl.h", "layers/scrollbar_layer_base.cc",
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc index ca389a2..50227e73 100644 --- a/cc/layers/layer.cc +++ b/cc/layers/layer.cc
@@ -53,7 +53,7 @@ SkColor background_color; Region non_fast_scrollable_region; TouchActionRegion touch_action_region; - RegionCaptureBounds capture_bounds; + viz::RegionCaptureBounds capture_bounds; Region wheel_event_region; ElementId element_id; } inputs; @@ -1119,7 +1119,7 @@ SetNeedsCommit(); } -void Layer::SetCaptureBounds(RegionCaptureBounds bounds) { +void Layer::SetCaptureBounds(viz::RegionCaptureBounds bounds) { DCHECK(IsPropertyChangeAllowed()); if (inputs_.capture_bounds == bounds) { return;
diff --git a/cc/layers/layer.h b/cc/layers/layer.h index 90eb601..53fc2f6 100644 --- a/cc/layers/layer.h +++ b/cc/layers/layer.h
@@ -22,7 +22,6 @@ #include "cc/input/input_handler.h" #include "cc/input/scroll_snap_data.h" #include "cc/layers/layer_collections.h" -#include "cc/layers/region_capture_bounds.h" #include "cc/layers/touch_action_region.h" #include "cc/paint/element_id.h" #include "cc/paint/filter_operations.h" @@ -30,6 +29,7 @@ #include "cc/trees/effect_node.h" #include "cc/trees/property_tree.h" #include "cc/trees/target_property.h" +#include "components/viz/common/surfaces/region_capture_bounds.h" #include "components/viz/common/surfaces/subtree_capture_id.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/point3_f.h" @@ -457,8 +457,8 @@ } // Set or get the region that should be used for capture. - void SetCaptureBounds(RegionCaptureBounds bounds); - const RegionCaptureBounds& capture_bounds() const { + void SetCaptureBounds(viz::RegionCaptureBounds bounds); + const viz::RegionCaptureBounds& capture_bounds() const { return inputs_.capture_bounds; } @@ -882,7 +882,7 @@ // moved to a separate sub-struct. Region non_fast_scrollable_region; TouchActionRegion touch_action_region; - RegionCaptureBounds capture_bounds; + viz::RegionCaptureBounds capture_bounds; Region wheel_event_region; ElementId element_id;
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc index 2787650..c6d222f 100644 --- a/cc/layers/layer_impl.cc +++ b/cc/layers/layer_impl.cc
@@ -352,7 +352,7 @@ return *all_touch_action_regions_; } -void LayerImpl::SetCaptureBounds(RegionCaptureBounds bounds) { +void LayerImpl::SetCaptureBounds(viz::RegionCaptureBounds bounds) { if (capture_bounds_ == bounds) return; capture_bounds_ = std::move(bounds);
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h index 289000b..b84d83b 100644 --- a/cc/layers/layer_impl.h +++ b/cc/layers/layer_impl.h
@@ -25,13 +25,13 @@ #include "cc/layers/draw_properties.h" #include "cc/layers/layer_collections.h" #include "cc/layers/performance_properties.h" -#include "cc/layers/region_capture_bounds.h" #include "cc/layers/render_surface_impl.h" #include "cc/layers/touch_action_region.h" #include "cc/paint/element_id.h" #include "cc/tiles/tile_priority.h" #include "cc/trees/target_property.h" #include "components/viz/common/quads/shared_quad_state.h" +#include "components/viz/common/surfaces/region_capture_bounds.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/display_color_spaces.h" #include "ui/gfx/geometry/point3_f.h" @@ -272,8 +272,10 @@ return !touch_action_region_.IsEmpty(); } - void SetCaptureBounds(RegionCaptureBounds bounds); - const RegionCaptureBounds& capture_bounds() const { return capture_bounds_; } + void SetCaptureBounds(viz::RegionCaptureBounds bounds); + const viz::RegionCaptureBounds& capture_bounds() const { + return capture_bounds_; + } // Set or get the region that contains wheel event handler. // The |wheel_event_handler_region| specify the area where wheel event handler @@ -508,7 +510,7 @@ // The bounds of elements marked for potential region capture, stored in // the coordinate space of this layer. - RegionCaptureBounds capture_bounds_; + viz::RegionCaptureBounds capture_bounds_; Region wheel_event_handler_region_; SkColor background_color_; SkColor safe_opaque_background_color_;
diff --git a/cc/layers/region_capture_bounds.cc b/cc/layers/region_capture_bounds.cc deleted file mode 100644 index 4dd5bef..0000000 --- a/cc/layers/region_capture_bounds.cc +++ /dev/null
@@ -1,35 +0,0 @@ -// 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 "cc/layers/region_capture_bounds.h" - -#include <utility> - -namespace cc { - -RegionCaptureBounds::RegionCaptureBounds() = default; -RegionCaptureBounds::RegionCaptureBounds(const RegionCaptureBounds& regions) = - default; -RegionCaptureBounds::RegionCaptureBounds(RegionCaptureBounds&& regions) = - default; -RegionCaptureBounds::RegionCaptureBounds( - base::flat_map<RegionCaptureCropId, gfx::Rect> bounds) - : bounds_(std::move(bounds)) {} -RegionCaptureBounds::~RegionCaptureBounds() = default; - -void RegionCaptureBounds::Set(const RegionCaptureCropId& crop_id, - const gfx::Rect& region) { - bounds_.insert_or_assign(crop_id, region); -} - -RegionCaptureBounds& RegionCaptureBounds::operator=( - const RegionCaptureBounds& other) = default; -RegionCaptureBounds& RegionCaptureBounds::operator=( - RegionCaptureBounds&& other) = default; - -bool RegionCaptureBounds::operator==(const RegionCaptureBounds& other) const { - return bounds_ == other.bounds_; -} - -} // namespace cc
diff --git a/cc/layers/region_capture_bounds.h b/cc/layers/region_capture_bounds.h deleted file mode 100644 index b71f087..0000000 --- a/cc/layers/region_capture_bounds.h +++ /dev/null
@@ -1,49 +0,0 @@ -// 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 CC_LAYERS_REGION_CAPTURE_BOUNDS_H_ -#define CC_LAYERS_REGION_CAPTURE_BOUNDS_H_ - -#include "base/containers/flat_map.h" -#include "base/token.h" -#include "cc/cc_export.h" -#include "ui/gfx/geometry/rect.h" - -namespace cc { - -using RegionCaptureCropId = base::Token; - -// Represents a map from a region capture crop identifier, which is a randomly -// generated token, to a rectangle representing the bounds of the HTML element -// associated with the crop identifier. The boundaries here are captured from -// the CompositorFrame root render pass and are thus in that coordinate space. -// See the design document at: https://tinyurl.com/region-capture. -class CC_EXPORT RegionCaptureBounds final { - public: - RegionCaptureBounds(); - RegionCaptureBounds(const RegionCaptureBounds& regions); - RegionCaptureBounds(RegionCaptureBounds&& regions); - explicit RegionCaptureBounds( - base::flat_map<RegionCaptureCropId, gfx::Rect> bounds); - ~RegionCaptureBounds(); - - // We currently only support a single set of bounds for a given crop id. - // Multiple calls with the same crop id will update the bounds. - void Set(const RegionCaptureCropId& crop_id, const gfx::Rect& bounds); - - const base::flat_map<RegionCaptureCropId, gfx::Rect>& bounds() const { - return bounds_; - } - - RegionCaptureBounds& operator=(const RegionCaptureBounds& other); - RegionCaptureBounds& operator=(RegionCaptureBounds&& other); - bool operator==(const RegionCaptureBounds& other) const; - - private: - base::flat_map<RegionCaptureCropId, gfx::Rect> bounds_; -}; - -} // namespace cc - -#endif // CC_LAYERS_REGION_CAPTURE_BOUNDS_H_
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 763062fb..96fad38 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -18231,16 +18231,16 @@ } TEST_F(LayerTreeHostImplTest, CollectRegionCaptureBounds) { - const auto kFirstId = RegionCaptureCropId::CreateRandom(); - const auto kSecondId = RegionCaptureCropId::CreateRandom(); - const auto kThirdId = RegionCaptureCropId::CreateRandom(); - const auto kFourthId = RegionCaptureCropId::CreateRandom(); + const auto kFirstId = viz::RegionCaptureCropId::CreateRandom(); + const auto kSecondId = viz::RegionCaptureCropId::CreateRandom(); + const auto kThirdId = viz::RegionCaptureCropId::CreateRandom(); + const auto kFourthId = viz::RegionCaptureCropId::CreateRandom(); - const RegionCaptureBounds kRootBounds{ + const viz::RegionCaptureBounds kRootBounds{ {{kFirstId, gfx::Rect{0, 0, 250, 250}}, {kSecondId, gfx::Rect{}}}}; - const RegionCaptureBounds kChildBounds{ + const viz::RegionCaptureBounds kChildBounds{ {{kThirdId, gfx::Rect{5, 6, 300, 400}}}}; - const RegionCaptureBounds kSecondChildBounds{ + const viz::RegionCaptureBounds kSecondChildBounds{ {{kFourthId, gfx::Rect{20, 10, 400, 500}}}}; // Set up the root layer.
diff --git a/chrome/VERSION b/chrome/VERSION index 5e2b4ce..0960de09 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=98 MINOR=0 -BUILD=4710 +BUILD=4711 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 72be5861..9a20edb 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -387,6 +387,7 @@ "//chrome/browser/policy/android:java", "//chrome/browser/power_bookmarks:proto_java", "//chrome/browser/preferences:java", + "//chrome/browser/prefetch/android:java", "//chrome/browser/privacy:java", "//chrome/browser/privacy_review/android:java", "//chrome/browser/privacy_sandbox/android:java", @@ -1363,6 +1364,8 @@ "//chrome/browser/policy/android:java", "//chrome/browser/power_bookmarks:proto_java", "//chrome/browser/preferences:java", + "//chrome/browser/prefetch/android:java", + "//chrome/browser/prefetch/android:javatests", "//chrome/browser/privacy_sandbox/android:java", "//chrome/browser/privacy_sandbox/android:javatests", "//chrome/browser/profiles/android:java", @@ -2339,6 +2342,7 @@ "//base:base_java", "//base:base_java_test_support", "//base:jni_java", + "//chrome/browser/prefetch/android:java", "//chrome/browser/profiles/android:java", "//chrome/browser/sync/android:java", "//chrome/browser/tab:java",
diff --git a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java index c33c723..ccfe63a6 100644 --- a/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java +++ b/chrome/android/features/start_surface/internal/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
@@ -34,7 +34,6 @@ import androidx.annotation.VisibleForTesting; import org.chromium.base.ObserverList; -import org.chromium.base.StrictModeContext; import org.chromium.base.ThreadUtils; import org.chromium.base.jank_tracker.JankScenario; import org.chromium.base.jank_tracker.JankTracker; @@ -51,6 +50,7 @@ import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.Pref; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabLaunchType; @@ -58,7 +58,6 @@ import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; -import org.chromium.chrome.browser.tasks.pseudotab.PseudoTab; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; import org.chromium.chrome.start_surface.R; import org.chromium.components.prefs.PrefService; @@ -66,8 +65,6 @@ import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.util.ColorUtils; -import java.util.List; - /** The mediator implements the logic to interact with the surfaces and caller. */ class StartSurfaceMediator implements StartSurface.Controller, TabSwitcher.OverviewModeObserver, View.OnClickListener, StartSurface.OnTabSelectingListener { @@ -477,17 +474,7 @@ /* isVisible= */ true, /* skipUpdateController = */ true); } else if (mStartSurfaceState == StartSurfaceState.SHOWN_HOMEPAGE) { setExploreSurfaceVisibility(!mIsIncognito && mExploreSurfaceCoordinatorFactory != null); - boolean hasNormalTab; - if (CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START) - && !mTabModelSelector.isTabStateInitialized()) { - List<PseudoTab> allTabs; - try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) { - allTabs = PseudoTab.getAllPseudoTabsFromStateFile(mContext); - } - hasNormalTab = allTabs != null && !allTabs.isEmpty(); - } else { - hasNormalTab = mTabModelSelector.getModel(false).getCount() > 0; - } + boolean hasNormalTab = getNormalTabCount() > 0; // If new home surface for home button is enabled, MV tiles and carousel tab switcher // will not show. @@ -955,6 +942,15 @@ || state == StartSurfaceState.SHOWN_TABSWITCHER; } + private int getNormalTabCount() { + if (!mTabModelSelector.isTabStateInitialized()) { + return SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.REGULAR_TAB_COUNT); + } else { + return mTabModelSelector.getModel(false).getCount(); + } + } + TabSwitcher.Controller getSecondaryTasksSurfaceController() { return mSecondaryTasksSurfaceController; }
diff --git a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java index 6e16587..9daaa539 100644 --- a/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java +++ b/chrome/android/features/start_surface/internal/javatests/src/org/chromium/chrome/features/start_surface/InstantStartTest.java
@@ -848,20 +848,9 @@ "force-fieldtrials=Study/Group", IMMEDIATE_RETURN_PARAMS + "/start_surface_variation/single"}) @DisabledTest(message = "https://crbug.com/1263928") - public void testShadowVisibility() { + public void testToolbarLayoutAndShadowVisibilityWithInstant() { // clang-format on - StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule); - ChromeTabbedActivity cta = mActivityTestRule.getActivity(); - StartSurfaceTestUtils.waitForOverviewVisible(cta); - - onView(withId(R.id.toolbar_shadow)) - .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE))); - - startAndWaitNativeInitialization(); - StartSurfaceTestUtils.waitForOverviewVisible(cta); - - onView(withId(R.id.toolbar_shadow)) - .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE))); + testToolbarLayoutAndShadowVisibility(); } @Test @@ -874,16 +863,9 @@ @CommandLineFlags.Add({ChromeSwitches.DISABLE_NATIVE_INITIALIZATION, "force-fieldtrials=Study/Group", IMMEDIATE_RETURN_PARAMS + "/start_surface_variation/single"}) - public void testShadowVisibilityWithoutInstantStart() { + public void testToolbarLayoutAndShadowVisibilityWithoutInstant() { // clang-format on - StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule); - onViewWaiting(withId(R.id.toolbar_shadow)).check(matches(isDisplayed())); - - startAndWaitNativeInitialization(); - StartSurfaceTestUtils.waitForOverviewVisible(mActivityTestRule.getActivity()); - - onView(withId(R.id.toolbar_shadow)) - .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE))); + testToolbarLayoutAndShadowVisibility(); } @Test @@ -1497,6 +1479,28 @@ } } + private void testToolbarLayoutAndShadowVisibility() { + StartSurfaceTestUtils.startMainActivityFromLauncher(mActivityTestRule); + ChromeTabbedActivity cta = mActivityTestRule.getActivity(); + + onView(withId(R.id.toolbar)) + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE))); + onView(withId(R.id.toolbar_shadow)) + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE))); + + startAndWaitNativeInitialization(); + StartSurfaceTestUtils.waitForOverviewVisible(cta); + + onView(withId(R.id.toolbar)) + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE))); + onView(withId(R.id.toolbar_shadow)) + .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE))); + + StartSurfaceTestUtils.scrollToolbar(cta); + onView(withId(R.id.toolbar_shadow)) + .check(matches(withEffectiveVisibility(Visibility.VISIBLE))); + } + private void startNewTabFromLauncherIcon(boolean incognito) { Intent intent = IntentHandler.createTrustedOpenNewTabIntent( ContextUtils.getApplicationContext(), incognito);
diff --git a/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java b/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java index 1833819e..daf212db 100644 --- a/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java +++ b/chrome/android/features/start_surface/internal/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java
@@ -331,6 +331,7 @@ createStartSurfaceMediator(/* isStartSurfaceEnabled= */ true, false); doReturn(2).when(mNormalTabModel).getCount(); + doReturn(true).when(mTabModelSelector).isTabStateInitialized(); mediator.setOverviewState(StartSurfaceState.SHOWING_HOMEPAGE); mediator.showOverview(false); mediator.setOverviewState(StartSurfaceState.SHOWN_HOMEPAGE); @@ -507,6 +508,7 @@ assertThat(mediator.getStartSurfaceState(), equalTo(StartSurfaceState.NOT_SHOWN)); doReturn(2).when(mNormalTabModel).getCount(); + doReturn(true).when(mTabModelSelector).isTabStateInitialized(); mediator.setOverviewState(StartSurfaceState.SHOWING_HOMEPAGE); mediator.showOverview(false); assertThat(mediator.getStartSurfaceState(), equalTo(StartSurfaceState.SHOWN_HOMEPAGE)); @@ -588,6 +590,7 @@ assertThat(mediator.getStartSurfaceState(), equalTo(StartSurfaceState.NOT_SHOWN)); doReturn(2).when(mNormalTabModel).getCount(); + doReturn(true).when(mTabModelSelector).isTabStateInitialized(); mediator.setOverviewState(StartSurfaceState.SHOWING_HOMEPAGE); mediator.showOverview(false); verify(mTabModelSelector).addObserver(mTabModelSelectorObserverCaptor.capture()); @@ -629,6 +632,7 @@ doReturn(2).when(mNormalTabModel).getCount(); doReturn(true).when(mActivityStateChecker).isFinishingOrDestroyed(); + doReturn(true).when(mTabModelSelector).isTabStateInitialized(); mediator.setOverviewState(StartSurfaceState.SHOWING_HOMEPAGE); mediator.showOverview(false); assertThat(mediator.getStartSurfaceState(), equalTo(StartSurfaceState.SHOWN_HOMEPAGE));
diff --git a/chrome/android/features/tab_ui/BUILD.gn b/chrome/android/features/tab_ui/BUILD.gn index 7eb4997..67725f6 100644 --- a/chrome/android/features/tab_ui/BUILD.gn +++ b/chrome/android/features/tab_ui/BUILD.gn
@@ -203,6 +203,7 @@ "//chrome/browser/feedback/android:java", "//chrome/browser/flags:java", "//chrome/browser/lens:java", + "//chrome/browser/preferences:java", "//chrome/browser/profiles/android:java", "//chrome/browser/search_engines/android:java", "//chrome/browser/share:java",
diff --git a/chrome/android/features/tab_ui/java/res/drawable/single_tab_background.xml b/chrome/android/features/tab_ui/java/res/drawable/single_tab_background.xml index 7c8cc65..bf5dfc8 100644 --- a/chrome/android/features/tab_ui/java/res/drawable/single_tab_background.xml +++ b/chrome/android/features/tab_ui/java/res/drawable/single_tab_background.xml
@@ -6,6 +6,6 @@ <shape xmlns:android="http://schemas.android.com/apk/res/android"> <stroke android:width="1dp" - android:color="@color/divider_line_bg_color" /> + android:color="@macro/divider_line_bg_color" /> <corners android:radius="@dimen/card_rounded_corner_radius" /> </shape>
diff --git a/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml b/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml index 54f5f554..f6b54b2 100644 --- a/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml +++ b/chrome/android/features/tab_ui/java/res/layout/tab_grid_card_item.xml
@@ -78,7 +78,7 @@ style="@style/HorizontalDivider" android:layout_below="@id/tab_title" android:visibility="?attr/tabGridDividerVisible" - android:background="@color/divider_line_bg_color"/> + android:background="@macro/divider_line_bg_color"/> <org.chromium.ui.widget.ButtonCompat android:id="@+id/create_group_button" android:layout_width="wrap_content"
diff --git a/chrome/android/features/tab_ui/java/res/values/colors.xml b/chrome/android/features/tab_ui/java/res/values/colors.xml index 8ef4e61..5d9e5f13 100644 --- a/chrome/android/features/tab_ui/java/res/values/colors.xml +++ b/chrome/android/features/tab_ui/java/res/values/colors.xml
@@ -17,7 +17,6 @@ <color name="tab_grid_card_action_button_tint_color">@color/default_icon_color_baseline</color> <color name="tab_grid_card_action_button_tint_color_incognito">@color/default_icon_color_light</color> - <color name="tab_grid_card_divider_tint_color">@color/divider_line_bg_color</color> <color name="tab_grid_card_divider_tint_color_incognito">@color/divider_line_bg_color_light</color> <color name="tab_grid_card_thumbnail_placeholder_color">@color/default_bg_color_secondary</color>
diff --git a/chrome/android/features/tab_ui/java/res/values/styles.xml b/chrome/android/features/tab_ui/java/res/values/styles.xml index 6faedc5..42f4227 100644 --- a/chrome/android/features/tab_ui/java/res/values/styles.xml +++ b/chrome/android/features/tab_ui/java/res/values/styles.xml
@@ -8,7 +8,7 @@ <resources> <style name="TabGridDialogTitleTheme"> - <item name="colorControlNormal">@color/divider_line_bg_color</item> + <item name="colorControlNormal">@macro/divider_line_bg_color</item> <item name="colorControlActivated">@color/filled_button_bg_color</item> <item name="colorControlHighlight">@color/filled_button_bg_color</item> </style>
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java index 7c05af75..99b3136 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MultiThumbnailCardProvider.java
@@ -27,6 +27,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.tasks.pseudotab.PseudoTab; import org.chromium.chrome.tab_ui.R; +import org.chromium.components.browser_ui.styles.SemanticColorUtils; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.url.GURL; @@ -250,8 +251,7 @@ mThumbnailFramePaint.setStyle(Paint.Style.STROKE); mThumbnailFramePaint.setStrokeWidth( resource.getDimension(R.dimen.tab_list_mini_card_frame_size)); - mThumbnailFramePaint.setColor( - ApiCompatibilityUtils.getColor(resource, R.color.divider_line_bg_color)); + mThumbnailFramePaint.setColor(SemanticColorUtils.getDividerLineBgColor(context)); mThumbnailFramePaint.setAntiAlias(true); // TODO(996048): Use pre-defined styles to avoid style out of sync if any text/color styles
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java index 4a60adc..f972598 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMediator.java
@@ -38,6 +38,8 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.init.FirstDrawDetector; import org.chromium.chrome.browser.multiwindow.MultiWindowModeStateDispatcher; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabCreationState; import org.chromium.chrome.browser.tab.TabHidingType; @@ -616,19 +618,7 @@ if (mRegisteredFirstMeaningfulPaintRecorder) return; mRegisteredFirstMeaningfulPaintRecorder = true; - boolean hasTabs = false; - if (mTabModelSelector.isTabStateInitialized()) { - hasTabs = mTabModelSelector.getTabModelFilterProvider() - .getCurrentTabModelFilter() - .getCount() - > 0; - } else { - List<PseudoTab> allTabs; - try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) { - allTabs = PseudoTab.getAllPseudoTabsFromStateFile(mContext); - } - hasTabs = allTabs != null && !allTabs.isEmpty(); - } + boolean hasTabs = getTabCount() > 0; if (!hasTabs) { FirstDrawDetector.waitForFirstDraw( @@ -890,4 +880,15 @@ if (filter == null) return; RecordHistogram.recordCountHistogram(TAB_ENTRIES_HISTOGRAM, filter.getCount()); } + + private int getTabCount() { + if (mTabModelSelector.isTabStateInitialized()) { + return mTabModelSelector.getTabModelFilterProvider() + .getCurrentTabModelFilter() + .getCount(); + } else { + return SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.REGULAR_TAB_COUNT); + } + } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeProvider.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeProvider.java index 3092350a..003735d63 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeProvider.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeProvider.java
@@ -23,6 +23,7 @@ import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.tab_ui.R; +import org.chromium.components.browser_ui.styles.SemanticColorUtils; /** * Utility class that provides theme related attributes for Tab UI. @@ -226,9 +227,9 @@ */ @ColorInt public static int getDividerColor(Context context, boolean isIncognito) { - return ApiCompatibilityUtils.getColor(context.getResources(), - isIncognito ? R.color.tab_grid_card_divider_tint_color_incognito - : R.color.tab_grid_card_divider_tint_color); + return isIncognito ? ApiCompatibilityUtils.getColor( + context.getResources(), R.color.tab_grid_card_divider_tint_color_incognito) + : SemanticColorUtils.getTabGridCardDividerTintColor(context); } /** @@ -302,9 +303,9 @@ */ @ColorInt public static int getMiniThumbnailFrameColor(Context context, boolean isIncognito) { - return ApiCompatibilityUtils.getColor(context.getResources(), - isIncognito ? R.color.tab_grid_card_divider_tint_color_incognito - : R.color.tab_grid_card_divider_tint_color); + return isIncognito ? ApiCompatibilityUtils.getColor( + context.getResources(), R.color.tab_grid_card_divider_tint_color_incognito) + : SemanticColorUtils.getTabGridCardDividerTintColor(context); } /**
diff --git a/chrome/android/java/res/drawable-ldrtl/google_pay_with_divider.xml b/chrome/android/java/res/drawable-ldrtl/google_pay_with_divider.xml index c698ca2f..d8d4d77f 100644 --- a/chrome/android/java/res/drawable-ldrtl/google_pay_with_divider.xml +++ b/chrome/android/java/res/drawable-ldrtl/google_pay_with_divider.xml
@@ -37,5 +37,5 @@ </group> <path android:pathData="M1 16l0 -14 1 0 0 14z" - android:fillColor="@color/divider_line_bg_color" /> + android:fillColor="@macro/divider_line_bg_color" /> </vector>
diff --git a/chrome/android/java/res/drawable/google_pay_with_divider.xml b/chrome/android/java/res/drawable/google_pay_with_divider.xml index 4be6c43..8e5994b 100644 --- a/chrome/android/java/res/drawable/google_pay_with_divider.xml +++ b/chrome/android/java/res/drawable/google_pay_with_divider.xml
@@ -37,5 +37,5 @@ </group> <path android:pathData="M50 16l0 -14 1 0 0 14z" - android:fillColor="@color/divider_line_bg_color" /> + android:fillColor="@macro/divider_line_bg_color" /> </vector>
diff --git a/chrome/android/java/res/layout/autofill_cc_details.xml b/chrome/android/java/res/layout/autofill_cc_details.xml index b58b9e3d..682c0ea 100644 --- a/chrome/android/java/res/layout/autofill_cc_details.xml +++ b/chrome/android/java/res/layout/autofill_cc_details.xml
@@ -21,7 +21,7 @@ <ImageView android:id="@+id/message_divider" - android:background="@color/divider_line_bg_color" + android:background="@macro/divider_line_bg_color" android:importantForAccessibility="no" android:layout_height="match_parent" android:layout_width="1dp"
diff --git a/chrome/android/java/res/layout/divider_line_menu_item.xml b/chrome/android/java/res/layout/divider_line_menu_item.xml index fbf346e..a1396348 100644 --- a/chrome/android/java/res/layout/divider_line_menu_item.xml +++ b/chrome/android/java/res/layout/divider_line_menu_item.xml
@@ -18,6 +18,6 @@ <View style="@style/HorizontalDivider" android:layout_width="match_parent" - android:background="@color/divider_line_bg_color" /> + android:background="@macro/divider_line_bg_color" /> </LinearLayout> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/find_in_page.xml b/chrome/android/java/res/layout/find_in_page.xml index d278daa..1a57e120 100644 --- a/chrome/android/java/res/layout/find_in_page.xml +++ b/chrome/android/java/res/layout/find_in_page.xml
@@ -39,7 +39,7 @@ android:layout_height="match_parent" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" - android:background="@color/divider_line_bg_color" /> + android:background="@macro/divider_line_bg_color" /> <org.chromium.ui.widget.ChromeImageButton android:id="@+id/find_prev_button" style="@style/ToolbarButton"
diff --git a/chrome/android/java/res/layout/infobar_footer.xml b/chrome/android/java/res/layout/infobar_footer.xml index d37b8fb..e2777fa 100644 --- a/chrome/android/java/res/layout/infobar_footer.xml +++ b/chrome/android/java/res/layout/infobar_footer.xml
@@ -16,7 +16,7 @@ <View style="@style/HorizontalDivider" android:layout_width="match_parent" - android:background="@color/divider_line_bg_color" /> + android:background="@macro/divider_line_bg_color" /> <LinearLayout android:layout_width="match_parent"
diff --git a/chrome/android/java/res/layout/long_screenshots_area_selection_dialog.xml b/chrome/android/java/res/layout/long_screenshots_area_selection_dialog.xml index 409f19d8..8f50c42 100644 --- a/chrome/android/java/res/layout/long_screenshots_area_selection_dialog.xml +++ b/chrome/android/java/res/layout/long_screenshots_area_selection_dialog.xml
@@ -55,7 +55,7 @@ <View android:id="@+id/divider" - android:background="@color/divider_line_bg_color" + android:background="@macro/divider_line_bg_color" android:layout_above="@id/footer" android:layout_height="1dp" android:layout_width="match_parent"/>
diff --git a/chrome/android/java/res/layout/managed_by_menu_item.xml b/chrome/android/java/res/layout/managed_by_menu_item.xml index d796427..b363c47 100644 --- a/chrome/android/java/res/layout/managed_by_menu_item.xml +++ b/chrome/android/java/res/layout/managed_by_menu_item.xml
@@ -13,7 +13,7 @@ <View style="@style/HorizontalDivider" android:layout_width="match_parent" - android:background="@color/divider_line_bg_color" /> + android:background="@macro/divider_line_bg_color" /> <org.chromium.components.browser_ui.widget.text.TextViewWithCompoundDrawables android:id="@+id/menu_item_text"
diff --git a/chrome/android/java/res/layout/powered_by_chrome_footer.xml b/chrome/android/java/res/layout/powered_by_chrome_footer.xml index 7ad2ee7..4e87d4f 100644 --- a/chrome/android/java/res/layout/powered_by_chrome_footer.xml +++ b/chrome/android/java/res/layout/powered_by_chrome_footer.xml
@@ -21,5 +21,5 @@ <View android:layout_width="match_parent" android:layout_height="1dp" - android:background="@color/divider_line_bg_color" /> + android:background="@macro/divider_line_bg_color" /> </FrameLayout>
diff --git a/chrome/android/java/res/layout/share_sheet_content.xml b/chrome/android/java/res/layout/share_sheet_content.xml index 00d1eeb..f272986 100644 --- a/chrome/android/java/res/layout/share_sheet_content.xml +++ b/chrome/android/java/res/layout/share_sheet_content.xml
@@ -84,7 +84,7 @@ <View android:id="@+id/preview_divider" - android:background="@color/divider_line_bg_color" + android:background="@macro/divider_line_bg_color" android:layout_height="1dp" android:layout_width="match_parent"/> @@ -100,7 +100,7 @@ <View android:id="@+id/share_sheet_divider" - android:background="@color/divider_line_bg_color" + android:background="@macro/divider_line_bg_color" android:layout_height="1dp" android:layout_width="match_parent" android:visibility="gone" />
diff --git a/chrome/android/java/res/values-v27/styles.xml b/chrome/android/java/res/values-v27/styles.xml index 6e8cd43..df47ceb 100644 --- a/chrome/android/java/res/values-v27/styles.xml +++ b/chrome/android/java/res/values-v27/styles.xml
@@ -6,23 +6,23 @@ <resources> <style name="Theme.Chromium.WithWindowAnimation" parent="Base.Theme.Chromium.WithWindowAnimation"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> - <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> + <item name="android:navigationBarDividerColor">@macro/bottom_system_nav_divider_color</item> <item name="android:windowLightNavigationBar">@bool/window_light_navigation_bar</item> </style> <style name="Base.V27.Theme.Chromium.Settings" parent="Base.Theme.Chromium.Settings"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> - <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> + <item name="android:navigationBarDividerColor">@macro/bottom_system_nav_divider_color</item> <item name="android:windowLightNavigationBar">@bool/window_light_navigation_bar</item> </style> <style name="Theme.Chromium.DialogWhenLarge" parent="Base.Theme.Chromium.DialogWhenLarge"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> - <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> + <item name="android:navigationBarDividerColor">@macro/bottom_system_nav_divider_color</item> <item name="android:windowLightNavigationBar">@bool/window_light_navigation_bar</item> </style> <style name="Theme.Chromium.Activity.Fullscreen" parent="Base.Theme.Chromium.Activity.Fullscreen"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> - <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> + <item name="android:navigationBarDividerColor">@macro/bottom_system_nav_divider_color</item> <item name="android:windowLightNavigationBar">@bool/window_light_navigation_bar</item> </style> </resources>
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index 156afdc..1083458 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -52,7 +52,6 @@ <!-- Overlay Panel colors --> <color name="overlay_panel_bar_background_color">@color/default_bg_color</color> - <color name="overlay_panel_separator_line_color">@color/divider_line_bg_color</color> <!-- Contextual Search colors --> <color name="contextual_search_promo_background_color">@color/default_bg_color_elev_0</color>
diff --git a/chrome/android/java/res/values/styles.xml b/chrome/android/java/res/values/styles.xml index b9a2a66..2968cbd 100644 --- a/chrome/android/java/res/values/styles.xml +++ b/chrome/android/java/res/values/styles.xml
@@ -327,7 +327,7 @@ <style name="TabBarLineShadow"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">1dp</item> - <item name="android:src">@color/divider_line_bg_color</item> + <item name="android:src">@macro/divider_line_bg_color</item> <item name="android:scaleType">fitXY</item> </style> <style name="TextAppearance.UpdateMenuItem">
diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml index ed124c1..f438f91 100644 --- a/chrome/android/java/res/xml/privacy_preferences.xml +++ b/chrome/android/java/res/xml/privacy_preferences.xml
@@ -33,11 +33,11 @@ android:key="can_make_payment" android:title="@string/can_make_payment_title" android:summary="@string/settings_can_make_payment_toggle_label"/> - <org.chromium.components.browser_ui.settings.ChromeSwitchPreference + <Preference android:key="preload_pages" android:title="@string/preload_pages_title" android:summary="@string/preload_pages_summary" - android:persistent="false"/> + android:fragment="org.chromium.chrome.browser.prefetch.settings.PreloadPagesSettingsFragment"/> <org.chromium.components.browser_ui.settings.ChromeBasePreference android:key="usage_stats_reporting" android:title="@string/usage_stats_setting_title"
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 891d819..1da1584 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1120,14 +1120,6 @@ || StartSurfaceConfiguration.shouldShowNewSurfaceFromHomeButton()); } - /** - * Returns whether grid Tab switcher or the Start surface should be shown at startup. - */ - private boolean shouldShowOverviewPageOnStart() { - return ReturnToChromeExperimentsUtil.shouldShowOverviewPageOnStart( - this, getIntent(), getTabModelSelector(), mInactivityTracker); - } - private void logMainIntentBehavior(Intent intent) { assert IntentUtils.isMainIntentFromLauncher(intent); // TODO(tedchoc): We should cache the last visible time and reuse it to avoid different @@ -1609,7 +1601,7 @@ this::supportsFindInPage, getTabCreatorManagerSupplier(), getFullscreenManager(), getCompositorViewHolderSupplier(), getTabContentManagerSupplier(), getOverviewModeBehaviorSupplier(), this::getSnackbarManager, getActivityType(), - this::isInOverviewMode, this::isWarmOnResume, + this::isInOverviewMode, this::shouldShowOverviewPageOnStart, this::isWarmOnResume, /* appMenuDelegate= */ this, /* statusBarColorProvider= */ this, mEphemeralTabCoordinatorSupplier, getIntentRequestTracker(), getControlContainerHeightResource(), this::getInsetObserverView, @@ -2636,6 +2628,14 @@ } @Override + public boolean shouldShowOverviewPageOnStart() { + assert mInactivityTracker != null; + assert getTabModelSelector() != null; + return ReturnToChromeExperimentsUtil.shouldShowOverviewPageOnStart( + this, getIntent(), getTabModelSelector(), mInactivityTracker); + } + + @Override protected IntentHandlerDelegate createIntentHandlerDelegate() { return new InternalIntentDelegate(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java index 5c6147f3..dd6855fb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -513,7 +513,8 @@ getFullscreenManager(), mCompositorViewHolderSupplier, getTabContentManagerSupplier(), getOverviewModeBehaviorSupplier(), this::getSnackbarManager, getActivityType(), this::isInOverviewMode, - this::isWarmOnResume, /* appMenuDelegate= */ this, + this::shouldShowOverviewPageOnStart, this::isWarmOnResume, + /* appMenuDelegate= */ this, /* statusBarColorProvider= */ this, getIntentRequestTracker(), mTabReparentingControllerSupplier, false); // clang-format on @@ -850,7 +851,8 @@ protected StartupTabPreloader getStartupTabPreloader() { if (mStartupTabPreloader == null) { mStartupTabPreloader = new StartupTabPreloader(this::getIntent, - getLifecycleDispatcher(), getWindowAndroid(), this, mIntentHandler); + getLifecycleDispatcher(), getWindowAndroid(), this, mIntentHandler, + getActivityTabStartupMetricsTracker()); } return mStartupTabPreloader; } @@ -1774,6 +1776,13 @@ return false; } + /** + * Returns whether grid Tab switcher or the Start surface should be shown at startup. + */ + public boolean shouldShowOverviewPageOnStart() { + return false; + } + @CallSuper @Override public boolean canShowAppMenu() { @@ -2556,7 +2565,7 @@ boolean usingDesktopUserAgent = currentTab.getWebContents().getNavigationController().getUseDesktopUserAgent(); usingDesktopUserAgent = !usingDesktopUserAgent; - if (ContentFeatureList.isEnabled(ContentFeatureList.REQUEST_DESKTOP_SITE_GLOBAL)) { + if (ContentFeatureList.isEnabled(ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS)) { Profile profile = getCurrentTabModel().getProfile(); RequestDesktopUtils.setRequestDesktopSiteContentSettingsForUrl( profile, currentTab.getUrl(), usingDesktopUserAgent);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java index 6ac69c43c..741fa92 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelBase.java
@@ -459,8 +459,7 @@ /** @return the color to use to draw the separator between the Bar and Content. */ public int getSeparatorLineColor() { - return ApiCompatibilityUtils.getColor( - mContext.getResources(), R.color.overlay_panel_separator_line_color); + return SemanticColorUtils.getOverlayPanelSeparatorLineColor(mContext); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java index ceb5695..807987c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -162,7 +162,7 @@ this::supportsFindInPage, getTabCreatorManagerSupplier(), getFullscreenManager(), getCompositorViewHolderSupplier(), getTabContentManagerSupplier(), getOverviewModeBehaviorSupplier(), this::getSnackbarManager, getActivityType(), - this::isInOverviewMode, this::isWarmOnResume, + this::isInOverviewMode, this::shouldShowOverviewPageOnStart, this::isWarmOnResume, /* appMenuDelegate= */ this, /* statusBarColorProvider= */ this, getIntentRequestTracker(), () -> mToolbarCoordinator, () -> mNavigationController, () -> mIntentDataProvider, getMultiWindowModeStateDispatcher());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java index 30cd8ce..ade3c782 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
@@ -89,6 +89,8 @@ * @param snackbarManagerSupplier Supplies the {@link SnackbarManager}. * @param activityType The {@link ActivityType} for the activity. * @param isInOverviewModeSupplier Supplies whether the app is in overview mode. + * @param shouldShowOverviewPageOnStartSupplier Supplies whether the overview page should be + * shown on start. * @param isWarmOnResumeSupplier Supplies whether the app was warm on resume. * @param appMenuDelegate The app menu delegate. * @param statusBarColorProvider Provides the status bar color. @@ -122,6 +124,7 @@ @NonNull OneshotSupplier<OverviewModeBehavior> overviewModeBehaviorSupplier, @NonNull Supplier<SnackbarManager> snackbarManagerSupplier, @ActivityType int activityType, @NonNull Supplier<Boolean> isInOverviewModeSupplier, + @NonNull Supplier<Boolean> shouldShowOverviewPageOnStartSupplier, @NonNull Supplier<Boolean> isWarmOnResumeSupplier, @NonNull AppMenuDelegate appMenuDelegate, @NonNull StatusBarColorProvider statusBarColorProvider, @@ -141,8 +144,9 @@ supportsAppMenuSupplier, supportsFindInPage, tabCreatorManagerSupplier, fullscreenManager, compositorViewHolderSupplier, tabContentManagerSupplier, overviewModeBehaviorSupplier, snackbarManagerSupplier, activityType, - isInOverviewModeSupplier, isWarmOnResumeSupplier, appMenuDelegate, - statusBarColorProvider, intentRequestTracker, new OneshotSupplierImpl<>(), false); + isInOverviewModeSupplier, shouldShowOverviewPageOnStartSupplier, + isWarmOnResumeSupplier, appMenuDelegate, statusBarColorProvider, + intentRequestTracker, new OneshotSupplierImpl<>(), false); // clang-format on mToolbarCoordinator = customTabToolbarCoordinator; mNavigationController = customTabNavigationController;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbarPhone.java index da47f7e..b83e785 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbarPhone.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/findinpage/FindToolbarPhone.java
@@ -14,6 +14,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; import org.chromium.components.browser_ui.styles.ChromeColors; +import org.chromium.components.browser_ui.styles.SemanticColorUtils; /** * A phone specific version of the {@link FindToolbar}. @@ -45,7 +46,6 @@ protected void updateVisualsForTabModel(boolean isIncognito) { int queryTextColorId; int queryHintTextColorId; - int dividerColorId; if (isIncognito) { setBackgroundColor(ChromeColors.getDefaultThemeColor(getContext(), true)); ColorStateList white = ChromeColors.getPrimaryIconTint(getContext(), true); @@ -54,7 +54,7 @@ ApiCompatibilityUtils.setImageTintList(mCloseFindButton, white); queryTextColorId = R.color.find_in_page_query_white_color; queryHintTextColorId = R.color.find_in_page_query_incognito_hint_color; - dividerColorId = R.color.white_alpha_12; + mDivider.setBackgroundResource(R.color.white_alpha_12); } else { setBackgroundColor(ChromeColors.getDefaultThemeColor(getContext(), false)); ColorStateList dark = ChromeColors.getPrimaryIconTint(getContext(), false); @@ -63,13 +63,12 @@ ApiCompatibilityUtils.setImageTintList(mCloseFindButton, dark); queryTextColorId = R.color.default_text_color_list; queryHintTextColorId = R.color.find_in_page_query_default_hint_color; - dividerColorId = R.color.divider_line_bg_color; + mDivider.setBackgroundColor(SemanticColorUtils.getDividerLineBgColor(getContext())); } mFindQuery.setTextColor( AppCompatResources.getColorStateList(getContext(), queryTextColorId)); mFindQuery.setHintTextColor( ApiCompatibilityUtils.getColor(getContext().getResources(), queryHintTextColorId)); - mDivider.setBackgroundResource(dividerColorId); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java b/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java index 323454a3..9fcc220 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTabPreloader.java
@@ -19,6 +19,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.DestroyObserver; +import org.chromium.chrome.browser.metrics.ActivityTabStartupMetricsTracker; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.ProfileManager; import org.chromium.chrome.browser.tab.EmptyTabObserver; @@ -41,6 +42,7 @@ public class StartupTabPreloader implements ProfileManager.Observer, DestroyObserver { public static final String EXTRA_DISABLE_STARTUP_TAB_PRELOADER = "org.chromium.chrome.browser.init.DISABLE_STARTUP_TAB_PRELOADER"; + private static boolean sFailNextTabMatchForTesting; private final Supplier<Intent> mIntentSupplier; private final ActivityLifecycleDispatcher mActivityLifecycleDispatcher; @@ -50,15 +52,22 @@ private LoadUrlParams mLoadUrlParams; private Tab mTab; private StartupTabObserver mObserver; + private ActivityTabStartupMetricsTracker mStartupMetricsTracker; + + public static void failNextTabMatchForTesting() { + sFailNextTabMatchForTesting = true; + } public StartupTabPreloader(Supplier<Intent> intentSupplier, ActivityLifecycleDispatcher activityLifecycleDispatcher, WindowAndroid windowAndroid, - TabCreatorManager tabCreatorManager, IntentHandler intentHandler) { + TabCreatorManager tabCreatorManager, IntentHandler intentHandler, + ActivityTabStartupMetricsTracker startupMetricsTracker) { mIntentSupplier = intentSupplier; mActivityLifecycleDispatcher = activityLifecycleDispatcher; mWindowAndroid = windowAndroid; mTabCreatorManager = tabCreatorManager; mIntentHandler = intentHandler; + mStartupMetricsTracker = startupMetricsTracker; mActivityLifecycleDispatcher.register(this); ProfileManager.addObserver(this); @@ -85,12 +94,17 @@ if (mTab == null) return null; boolean tabMatches = type == mTab.getLaunchType() - && doLoadUrlParamsMatchForWarmupManagerNavigation(mLoadUrlParams, loadUrlParams); + && doLoadUrlParamsMatchForWarmupManagerNavigation(mLoadUrlParams, loadUrlParams) + && !sFailNextTabMatchForTesting; + + sFailNextTabMatchForTesting = false; RecordHistogram.recordBooleanHistogram( "Startup.Android.StartupTabPreloader.TabTaken", tabMatches); if (!tabMatches) { + mStartupMetricsTracker.onStartupTabPreloadDropped(); + mTab.destroy(); mTab = null; mLoadUrlParams = null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java index 55afa64..18cc0713 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/ActivityTabStartupMetricsTracker.java
@@ -25,13 +25,42 @@ public class ActivityTabStartupMetricsTracker { private static final String UMA_HISTOGRAM_TABBED_SUFFIX = ".Tabbed"; + private class PageLoadMetricsObserverImpl implements PageLoadMetrics.Observer { + private static final long NO_NAVIGATION_ID = -1; + + private long mNavigationId = NO_NAVIGATION_ID; + private boolean mShouldRecordHistograms; + + @Override + public void onNewNavigation(WebContents webContents, long navigationId, + boolean isFirstNavigationInWebContents) { + if (mNavigationId != NO_NAVIGATION_ID) return; + + mNavigationId = navigationId; + mShouldRecordHistograms = mShouldTrackStartupMetrics; + } + + @Override + public void onFirstContentfulPaint(WebContents webContents, long navigationId, + long navigationStartTick, long firstContentfulPaintMs) { + if (navigationId != mNavigationId || !mShouldRecordHistograms) return; + + recordFirstContentfulPaint(navigationStartTick / 1000 + firstContentfulPaintMs); + } + + void reset() { + mNavigationId = NO_NAVIGATION_ID; + mShouldRecordHistograms = false; + } + }; + private final long mActivityStartTimeMs; // Event duration recorded from the |mActivityStartTimeMs|. private long mFirstCommitTimeMs; private String mHistogramSuffix; private TabModelSelectorTabObserver mTabModelSelectorTabObserver; - private PageLoadMetrics.Observer mPageLoadMetricsObserver; + private PageLoadMetricsObserverImpl mPageLoadMetricsObserver; private boolean mShouldTrackStartupMetrics; private boolean mFirstVisibleContentRecorded; private boolean mVisibleContentRecorded; @@ -69,29 +98,7 @@ registerFinishNavigation(isTrackedPage); } }; - mPageLoadMetricsObserver = new PageLoadMetrics.Observer() { - private static final long NO_NAVIGATION_ID = -1; - - private long mNavigationId = NO_NAVIGATION_ID; - private boolean mShouldRecordHistograms; - - @Override - public void onNewNavigation(WebContents webContents, long navigationId, - boolean isFirstNavigationInWebContents) { - if (mNavigationId != NO_NAVIGATION_ID) return; - - mNavigationId = navigationId; - mShouldRecordHistograms = mShouldTrackStartupMetrics; - } - - @Override - public void onFirstContentfulPaint(WebContents webContents, long navigationId, - long navigationStartTick, long firstContentfulPaintMs) { - if (navigationId != mNavigationId || !mShouldRecordHistograms) return; - - recordFirstContentfulPaint(navigationStartTick / 1000 + firstContentfulPaintMs); - } - }; + mPageLoadMetricsObserver = new PageLoadMetricsObserverImpl(); PageLoadMetrics.addObserver(mPageLoadMetricsObserver); } @@ -110,6 +117,21 @@ } /** + * Invoked when a tab preloaded at startup is dropped rather than taken, meaning that a new tab + * will need to be created to do the initial navigation. Resets state related to observation of + * the initial navigation to ensure that loading startup metrics are properly recorded in this + * case. Note that it is not necessary to reset the state of |mTabModelSelectorTabObserver| in + * this case, as that observer tracks state starting only from the addition of a tab to the tab + * model, which by definition has not yet occurred at this point. + */ + public void onStartupTabPreloadDropped() { + // Note that observers are not created in all contexts (e.g., CCT). + if (mPageLoadMetricsObserver == null) return; + + mPageLoadMetricsObserver.reset(); + } + + /** * Marks that startup metrics should be tracked with the |histogramSuffix|. * Must only be called on the UI thread. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java index 7d44584..0009313 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
@@ -20,6 +20,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.incognito.reauth.IncognitoReauthSettingSwitchPreference; import org.chromium.chrome.browser.preferences.Pref; +import org.chromium.chrome.browser.prefetch.settings.PreloadPagesSettingsFragment; import org.chromium.chrome.browser.privacy.secure_dns.SecureDnsSettings; import org.chromium.chrome.browser.privacy_review.PrivacyReviewDialog; import org.chromium.chrome.browser.privacy_sandbox.PrivacySandboxReferrer; @@ -49,7 +50,7 @@ public class PrivacySettings extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener { private static final String PREF_CAN_MAKE_PAYMENT = "can_make_payment"; - private static final String PREF_NETWORK_PREDICTIONS = "preload_pages"; + private static final String PREF_PRELOAD_PAGES = "preload_pages"; private static final String PREF_HTTPS_FIRST_MODE = "https_first_mode"; private static final String PREF_SECURE_DNS = "secure_dns"; private static final String PREF_USAGE_STATS = "usage_stats_reporting"; @@ -116,12 +117,9 @@ (ChromeSwitchPreference) findPreference(PREF_CAN_MAKE_PAYMENT); canMakePaymentPref.setOnPreferenceChangeListener(this); - ChromeSwitchPreference networkPredictionPref = - (ChromeSwitchPreference) findPreference(PREF_NETWORK_PREDICTIONS); - networkPredictionPref.setChecked( - PrivacyPreferencesManagerImpl.getInstance().getNetworkPredictionEnabled()); - networkPredictionPref.setOnPreferenceChangeListener(this); - networkPredictionPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate); + Preference preloadPagesPreference = findPreference(PREF_PRELOAD_PAGES); + preloadPagesPreference.setSummary( + PreloadPagesSettingsFragment.getPreloadPagesSummaryString(getContext())); ChromeSwitchPreference httpsFirstModePref = (ChromeSwitchPreference) findPreference(PREF_HTTPS_FIRST_MODE); @@ -171,9 +169,6 @@ if (PREF_CAN_MAKE_PAYMENT.equals(key)) { UserPrefs.get(Profile.getLastUsedRegularProfile()) .setBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED, (boolean) newValue); - } else if (PREF_NETWORK_PREDICTIONS.equals(key)) { - PrivacyPreferencesManagerImpl.getInstance().setNetworkPredictionEnabled( - (boolean) newValue); } else if (PREF_HTTPS_FIRST_MODE.equals(key)) { UserPrefs.get(Profile.getLastUsedRegularProfile()) .setBoolean(Pref.HTTPS_ONLY_MODE_ENABLED, (boolean) newValue); @@ -249,9 +244,7 @@ private ChromeManagedPreferenceDelegate createManagedPreferenceDelegate() { return preference -> { String key = preference.getKey(); - if (PREF_NETWORK_PREDICTIONS.equals(key)) { - return PrivacyPreferencesManagerImpl.getInstance().isNetworkPredictionManaged(); - } else if (PREF_HTTPS_FIRST_MODE.equals(key)) { + if (PREF_HTTPS_FIRST_MODE.equals(key)) { return UserPrefs.get(Profile.getLastUsedRegularProfile()) .isManagedPreference(Pref.HTTPS_ONLY_MODE_ENABLED); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/LensUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/share/LensUtils.java index 25d6be0..d7514a6c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/LensUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/LensUtils.java
@@ -389,6 +389,6 @@ public static boolean useSearchImageWithGoogleLensItemName() { return ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean( ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS, - USE_SEARCH_IMAGE_WITH_GOOGLE_LENS_ITEM_NAME_PARAM_NAME, false); + USE_SEARCH_IMAGE_WITH_GOOGLE_LENS_ITEM_NAME_PARAM_NAME, true); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java index 335a826..787f65d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
@@ -1646,8 +1646,13 @@ // 2. User-enabled request desktop site in site settings. Profile profile = IncognitoUtils.getProfileFromWindowAndroid(mWindowAndroid, isIncognito()); - boolean shouldRequestDesktopSite = getWebContents() != null - && TabUtils.isDesktopSiteEnabled(profile, getWebContents().getVisibleUrl()); + boolean shouldRequestDesktopSite; + if (ContentFeatureList.isEnabled(ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS)) { + shouldRequestDesktopSite = getWebContents() != null + && TabUtils.isDesktopSiteEnabled(profile, getWebContents().getVisibleUrl()); + } else { + shouldRequestDesktopSite = TabUtils.isDesktopSiteGlobalEnabled(profile); + } if (shouldRequestDesktopSite != currentRequestDesktopSite) { // TODO(crbug.com/1243758): Confirm if a new histogram should be used.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUtils.java index caeaee6..4a5d18f7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabUtils.java
@@ -126,6 +126,18 @@ * @param profile The profile of the tab. * Content settings have separate storage for incognito profiles. * For site-specific exceptions the actual profile is needed. + * @return Whether the desktop site should be requested. + */ + public static boolean isDesktopSiteGlobalEnabled(Profile profile) { + return WebsitePreferenceBridge.isCategoryEnabled( + profile, ContentSettingsType.REQUEST_DESKTOP_SITE); + } + + /** + * Check if Request Desktop Site global setting is enabled. + * @param profile The profile of the tab. + * Content settings have separate storage for incognito profiles. + * For site-specific exceptions the actual profile is needed. * @param url The URL for the current web content. * @return Whether the desktop site should be requested. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorController.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorController.java index c48fa69..29474e05 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorController.java
@@ -32,6 +32,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; import org.chromium.chrome.browser.vr.VrModuleProvider; +import org.chromium.components.browser_ui.styles.SemanticColorUtils; import org.chromium.ui.UiUtils; import org.chromium.ui.util.ColorUtils; import org.chromium.ui.vr.VrModeObserver; @@ -241,9 +242,10 @@ } private @ColorInt int getNavigationBarDividerColor(boolean forceDarkNavigationBar) { - return ApiCompatibilityUtils.getColor(mResources, - forceDarkNavigationBar ? R.color.bottom_system_nav_divider_color_light - : R.color.bottom_system_nav_divider_color); + return forceDarkNavigationBar + ? ApiCompatibilityUtils.getColor( + mResources, R.color.bottom_system_nav_divider_color_light) + : SemanticColorUtils.getBottomSystemNavDividerColor(mWindow.getContext()); } private @ColorInt int applyCurrentScrimToColor(@ColorInt int color) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java index c6c5676f..3c5717e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -234,6 +234,8 @@ * @param snackbarManagerSupplier Supplies the {@link SnackbarManager}. * @param activityType The {@link ActivityType} for the activity. * @param isInOverviewModeSupplier Supplies whether the app is in overview mode. + * @param shouldShowOverviewPageOnStartSupplier Supplies whether the overview page should be + * shown on start. * @param isWarmOnResumeSupplier Supplies whether the app was warm on resume. * @param appMenuDelegate The app menu delegate. * @param statusBarColorProvider Provides the status bar color. @@ -275,6 +277,7 @@ @NonNull OneshotSupplier<OverviewModeBehavior> overviewModeBehaviorSupplier, @NonNull Supplier<SnackbarManager> snackbarManagerSupplier, @ActivityType int activityType, @NonNull Supplier<Boolean> isInOverviewModeSupplier, + @NonNull Supplier<Boolean> shouldShowOverviewPageOnStartSupplier, @NonNull Supplier<Boolean> isWarmOnResumeSupplier, @NonNull AppMenuDelegate appMenuDelegate, @NonNull StatusBarColorProvider statusBarColorProvider, @@ -295,8 +298,9 @@ supportsFindInPage, tabCreatorManagerSupplier, fullscreenManager, compositorViewHolderSupplier, tabContentManagerSupplier, overviewModeBehaviorSupplier, snackbarManagerSupplier, activityType, - isInOverviewModeSupplier, isWarmOnResumeSupplier, appMenuDelegate, - statusBarColorProvider, intentRequestTracker, tabReparentingControllerSupplier, + isInOverviewModeSupplier, shouldShowOverviewPageOnStartSupplier, + isWarmOnResumeSupplier, appMenuDelegate, statusBarColorProvider, + intentRequestTracker, tabReparentingControllerSupplier, initializeUiWithIncognitoColors); mEphemeralTabCoordinatorSupplier = ephemeralTabCoordinatorSupplier; mControlContainerHeightResource = controlContainerHeightResource;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java index aaa0fc4..02af66f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
@@ -976,6 +976,11 @@ stream.writeInt(standardInfo.index + incognitoCount); Log.i(TAG, "Serializing tab lists; counts: " + standardCount + ", " + incognitoCount); + SharedPreferencesManager.getInstance().writeInt( + ChromePreferenceKeys.REGULAR_TAB_COUNT, standardCount); + SharedPreferencesManager.getInstance().writeInt( + ChromePreferenceKeys.INCOGNITO_TAB_COUNT, incognitoCount); + // Save incognito state first, so when we load, if the incognito files are unreadable // we can fall back easily onto the standard selected tab. for (int i = 0; i < incognitoCount; i++) {
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 ccb73c3..d877564c5 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
@@ -17,7 +17,6 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.IntentUtils; import org.chromium.base.Log; -import org.chromium.base.StrictModeContext; import org.chromium.base.TimeUtils; import org.chromium.base.TraceEvent; import org.chromium.base.library_loader.LibraryLoader; @@ -27,7 +26,6 @@ import org.chromium.chrome.browser.ChromeInactivityTracker; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.app.ChromeActivity; -import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.IntCachedFieldTrialParameter; import org.chromium.chrome.browser.homepage.HomepageManager; @@ -43,7 +41,6 @@ import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModelSelector; -import org.chromium.chrome.browser.tasks.pseudotab.PseudoTab; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; @@ -60,7 +57,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.List; /** * This is a utility class for managing experiments related to returning to Chrome. @@ -470,22 +466,17 @@ } /** - * - * @param context The activity context. * @param tabModelSelector The tab model selector. * @return the total tab count, and works before native initialization. */ - public static int getTotalTabCount(Context context, TabModelSelector tabModelSelector) { - if ((CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START) - || CachedFeatureFlags.isEnabled( - ChromeFeatureList.PAINT_PREVIEW_SHOW_ON_STARTUP)) - && !tabModelSelector.isTabStateInitialized()) { - List<PseudoTab> allTabs; - try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) { - allTabs = PseudoTab.getAllPseudoTabsFromStateFile(context); - } - return allTabs != null ? allTabs.size() : 0; + public static int getTotalTabCount(TabModelSelector tabModelSelector) { + if (!tabModelSelector.isTabStateInitialized()) { + return SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.REGULAR_TAB_COUNT) + + SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.INCOGNITO_TAB_COUNT); } + return tabModelSelector.getTotalTabCount(); } @@ -514,7 +505,7 @@ } if (ReturnToChromeExperimentsUtil.isStartSurfaceEnabled(context) && IntentUtils.isMainIntentFromLauncher(intent) - && ReturnToChromeExperimentsUtil.getTotalTabCount(context, tabModelSelector) <= 0) { + && ReturnToChromeExperimentsUtil.getTotalTabCount(tabModelSelector) <= 0) { // Handle initial tab creation. return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index eb4268f..5729509 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -356,6 +356,7 @@ * be fulfilled when feature TOOLBAR_IPH_ANDROID is enabled. * @param windowAndroid The {@link WindowAndroid} associated with the ToolbarManager. * @param isInOverviewModeSupplier Supplies whether the app is currently in overview mode. + * @param shouldShowOverviewPageOnStart Whether the overview page should be shown on start. * @param modalDialogManagerSupplier Supplies the {@link ModalDialogManager}. * @param statusBarColorController The {@link StatusBarColorController} for the app. * @param appMenuDelegate Allows interacting with the app menu. @@ -393,7 +394,7 @@ ObservableSupplier<Boolean> omniboxFocusStateSupplier, OneshotSupplier<ToolbarIntentMetadata> intentMetadataOneshotSupplier, OneshotSupplier<Boolean> promoShownOneshotSupplier, WindowAndroid windowAndroid, - Supplier<Boolean> isInOverviewModeSupplier, + Supplier<Boolean> isInOverviewModeSupplier, boolean shouldShowOverviewPageOnStart, Supplier<ModalDialogManager> modalDialogManagerSupplier, StatusBarColorController statusBarColorController, AppMenuDelegate appMenuDelegate, ActivityLifecycleDispatcher activityLifecycleDispatcher, @@ -565,7 +566,7 @@ browsingModeThemeColorProvider, mCompositorViewHolder.getInvalidator(), identityDiscController, isGridTabSwitcherEnabled, isTabToGtsAnimationEnabled, mIsStartSurfaceEnabled, isTabGroupsAndroidContinuationEnabled, - initializeWithIncognitoColors); + initializeWithIncognitoColors, shouldShowOverviewPageOnStart); mActionModeController = new ActionModeController(mActivity, mActionBarDelegate, toolbarActionModeCallback); @@ -997,7 +998,8 @@ ThemeColorProvider browsingModeThemeColorProvider, Invalidator invalidator, IdentityDiscController identityDiscController, boolean isGridTabSwitcherEnabled, boolean isTabToGtsAnimationEnabled, boolean isStartSurfaceEnabled, - boolean isTabGroupsAndroidContinuationEnabled, boolean initializeWithIncognitoColors) { + boolean isTabGroupsAndroidContinuationEnabled, boolean initializeWithIncognitoColors, + boolean shouldHideToolbarLayoutOnStart) { // clang-format off TopToolbarCoordinator toolbar = new TopToolbarCoordinator(controlContainer, toolbarLayout, mLocationBarModel, mToolbarTabController, @@ -1019,7 +1021,8 @@ isGridTabSwitcherEnabled, isTabToGtsAnimationEnabled, isStartSurfaceEnabled, isTabGroupsAndroidContinuationEnabled, HistoryManagerUtils::showHistoryManager, PartnerBrowserCustomizations.getInstance()::isHomepageProviderAvailableAndEnabled, - DownloadUtils::downloadOfflinePage, initializeWithIncognitoColors); + DownloadUtils::downloadOfflinePage, initializeWithIncognitoColors, + shouldHideToolbarLayoutOnStart); // clang-format on mHomepageStateListener = () -> { Boolean wasHomepageEnabled = mHomepageEnabledSupplier.get();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java index e8ae4f3..7e9dbc7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -242,6 +242,7 @@ protected final Supplier<SnackbarManager> mSnackbarManagerSupplier; protected final @ActivityType int mActivityType; protected final Supplier<Boolean> mIsInOverviewModeSupplier; + protected final Supplier<Boolean> mShouldShowOverviewPageOnStartSupplier; private final Supplier<Boolean> mIsWarmOnResumeSupplier; private final AppMenuDelegate mAppMenuDelegate; private final StatusBarColorProvider mStatusBarColorProvider; @@ -284,6 +285,8 @@ * @param snackbarManagerSupplier Supplies the {@link SnackbarManager}. * @param activityType The {@link ActivityType} for the activity. * @param isInOverviewModeSupplier Supplies whether the app is in overview mode. + * @param shouldShowOverviewPageOnStartSupplier Supplies whether the overview page should be + * shown on start. * @param isWarmOnResumeSupplier Supplies whether the app was warm on resume. * @param appMenuDelegate The app menu delegate. * @param statusBarColorProvider Provides the status bar color. @@ -320,6 +323,7 @@ @NonNull OneshotSupplier<OverviewModeBehavior> overviewModeBehaviorSupplier, @NonNull Supplier<SnackbarManager> snackbarManagerSupplier, @ActivityType int activityType, @NonNull Supplier<Boolean> isInOverviewModeSupplier, + @NonNull Supplier<Boolean> shouldShowOverviewPageOnStartSupplier, @NonNull Supplier<Boolean> isWarmOnResumeSupplier, @NonNull AppMenuDelegate appMenuDelegate, @NonNull StatusBarColorProvider statusBarColorProvider, @@ -347,6 +351,7 @@ mSnackbarManagerSupplier = snackbarManagerSupplier; mActivityType = activityType; mIsInOverviewModeSupplier = isInOverviewModeSupplier; + mShouldShowOverviewPageOnStartSupplier = shouldShowOverviewPageOnStartSupplier; mIsWarmOnResumeSupplier = isWarmOnResumeSupplier; mAppMenuDelegate = appMenuDelegate; mStatusBarColorProvider = statusBarColorProvider; @@ -914,6 +919,10 @@ AdaptiveToolbarButtonVariant.VOICE, voiceToolbarButtonController); mButtonDataProviders = Arrays.asList(mIdentityDiscController, adaptiveToolbarButtonController); + + // mShouldShowOverviewPageOnStartSupplier.get() should already be ready because + // ChromeTabbedActivity#mInactivityTracker and getTabModelSelector() have been set up by + // performPostInflationStartup before this method. mToolbarManager = new ToolbarManager(mActivity, mBrowserControlsManager, mFullscreenManager, toolbarContainer, mCompositorViewHolderSupplier.get(), urlFocusChangedCallback, mTopUiThemeColorProvider, @@ -925,9 +934,9 @@ shouldShowMenuUpdateBadge(), mTabModelSelectorSupplier, mStartSurfaceSupplier, mOmniboxFocusStateSupplier, mIntentMetadataOneshotSupplier, mPromoShownOneshotSupplier, mWindowAndroid, mIsInOverviewModeSupplier, - mModalDialogManagerSupplier, mStatusBarColorController, mAppMenuDelegate, - mActivityLifecycleDispatcher, mStartSurfaceParentTabSupplier, - mBottomSheetController, mIsWarmOnResumeSupplier, + mShouldShowOverviewPageOnStartSupplier.get(), mModalDialogManagerSupplier, + mStatusBarColorController, mAppMenuDelegate, mActivityLifecycleDispatcher, + mStartSurfaceParentTabSupplier, mBottomSheetController, mIsWarmOnResumeSupplier, mTabContentManagerSupplier.get(), mTabCreatorManagerSupplier.get(), mOverviewModeBehaviorSupplier, mSnackbarManagerSupplier.get(), mJankTracker, getMerchantTrustSignalsCoordinatorSupplier(), mTabReparentingControllerSupplier,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java index d7b5b60..795890e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java
@@ -158,7 +158,8 @@ mockActivity.getTabContentManagerSupplier(), mockActivity.getOverviewModeBehaviorSupplier(), mockActivity::getSnackbarManager, mockActivity.getActivityType(), - mockActivity::isInOverviewMode, mockActivity::isWarmOnResume, + mockActivity::isInOverviewMode, mockActivity::shouldShowOverviewPageOnStart, + mockActivity::isWarmOnResume, /* appMenuDelegate= */ mockActivity, /* statusBarColorProvider= */ mockActivity, mockActivity.getIntentRequestTracker(), new OneshotSupplierImpl<>(), false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java index 3af563d3..05b4f89 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -844,7 +844,8 @@ @Feature({"Browser", "ContextMenu"}) @CommandLineFlags.Add({"enable-features=" + ChromeFeatureList.CONTEXT_MENU_SEARCH_WITH_GOOGLE_LENS + "<FakeStudyName", - "force-fieldtrials=FakeStudyName/Enabled"}) + "force-fieldtrials=FakeStudyName/Enabled", + "force-fieldtrial-params=FakeStudyName.Enabled:useSearchImageWithGoogleLensItemName/false"}) @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) public void testSearchWithGoogleLensMenuItemName() throws Throwable {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java index 89af12b..5b56c39 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadTest.java
@@ -31,6 +31,7 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.UrlUtils; @@ -242,6 +243,7 @@ @Test @MediumTest @Feature({"Downloads"}) + @DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.N, message = "crbug.com/1270871") public void testDangerousDownload() throws Exception { mDownloadTestRule.loadUrl(mTestServer.getURL(TEST_DOWNLOAD_DIRECTORY + "dangerous.html")); waitForFocus();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java index e61e6ce..26028a1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderTest.java
@@ -17,6 +17,7 @@ import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.DisabledTest; +import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; @@ -40,6 +41,16 @@ "Startup.Android.StartupTabPreloader.TabLoaded"; private static final String TAB_TAKEN_HISTOGRAM = "Startup.Android.StartupTabPreloader.TabTaken"; + private static final String FIRST_COMMIT_HISTOGRAM = + "Startup.Android.Cold.TimeToFirstNavigationCommit" + + ChromeTabbedActivity.STARTUP_UMA_HISTOGRAM_SUFFIX; + private static final String FIRST_CONTENTFUL_PAINT_HISTOGRAM = + "Startup.Android.Cold.TimeToFirstContentfulPaint" + + ChromeTabbedActivity.STARTUP_UMA_HISTOGRAM_SUFFIX; + private static final String FIRST_VISIBLE_CONTENT_HISTOGRAM = + "Startup.Android.Cold.TimeToFirstVisibleContent"; + private static final String VISIBLE_CONTENT_HISTOGRAM = + "Startup.Android.Cold.TimeToVisibleContent"; @Rule public ChromeTabbedActivityTestRule mActivityRule = new ChromeTabbedActivityTestRule(); @@ -65,6 +76,71 @@ @Test @LargeTest + @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP) + public void testStartupTabPreloaderStartupLoadingMetricsRecordedWhenTabTaken() + throws Exception { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + mActivityRule.startMainActivityFromIntent( + intent, mServerRule.getServer().getURL(TEST_PAGE)); + + // The StartupTabPreloader should have loaded a url. + Assert.assertEquals( + 1, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1)); + Assert.assertEquals( + 1, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1)); + + // First contentful paint should be recorded. + CriteriaHelper.pollUiThread(() + -> RecordHistogram.getHistogramTotalCountForTesting( + FIRST_CONTENTFUL_PAINT_HISTOGRAM) + == 1); + // First contentful paint is the last startup metric to be recorded, so the other startup + // metrics should also have been recorded at this point. + Assert.assertEquals( + 1, RecordHistogram.getHistogramTotalCountForTesting(FIRST_COMMIT_HISTOGRAM)); + Assert.assertEquals(1, + RecordHistogram.getHistogramTotalCountForTesting(FIRST_VISIBLE_CONTENT_HISTOGRAM)); + Assert.assertEquals( + 1, RecordHistogram.getHistogramTotalCountForTesting(VISIBLE_CONTENT_HISTOGRAM)); + } + + @Test + @LargeTest + @DisableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP) + public void testStartupTabPreloaderStartupLoadingMetricsRecordedWhenTabDropped() + throws Exception { + StartupTabPreloader.failNextTabMatchForTesting(); + + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + mActivityRule.startMainActivityFromIntent( + intent, mServerRule.getServer().getURL(TEST_PAGE)); + + // The StartupTabPreloader should have loaded a url, but it should not have been taken. + Assert.assertEquals( + 1, RecordHistogram.getHistogramValueCountForTesting(TAB_LOADED_HISTOGRAM, 1)); + Assert.assertEquals( + 0, RecordHistogram.getHistogramValueCountForTesting(TAB_TAKEN_HISTOGRAM, 1)); + + // First contentful paint should be recorded. + CriteriaHelper.pollUiThread(() + -> RecordHistogram.getHistogramTotalCountForTesting( + FIRST_CONTENTFUL_PAINT_HISTOGRAM) + == 1); + + // First contentful paint is the last startup metric to be recorded, so the other startup + // metrics should also have been recorded at this point. + Assert.assertEquals( + 1, RecordHistogram.getHistogramTotalCountForTesting(FIRST_COMMIT_HISTOGRAM)); + Assert.assertEquals(1, + RecordHistogram.getHistogramTotalCountForTesting(FIRST_VISIBLE_CONTENT_HISTOGRAM)); + Assert.assertEquals( + 1, RecordHistogram.getHistogramTotalCountForTesting(VISIBLE_CONTENT_HISTOGRAM)); + } + + @Test + @LargeTest @EnableFeatures(ChromeFeatureList.ELIDE_TAB_PRELOAD_AT_STARTUP) @DisabledTest(message = "https://crbug.com/1012479") public void testStartupTabPreloaderWithViewIntentFeatureDisabled() throws Exception {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java index e21c85a0..6ac908a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/init/StartupTabPreloaderUnitTest.java
@@ -15,12 +15,16 @@ import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.Callback; +import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.metrics.ActivityTabStartupMetricsTracker; import org.chromium.chrome.browser.tabmodel.ChromeTabCreator; import org.chromium.chrome.browser.tabmodel.TabCreator; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.document.TabDelegate; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.browser.Features; @@ -180,7 +184,21 @@ } }, new ActivityLifecycleDispatcherImpl(null), null, tabCreatorManager, - new IntentHandler(null, null)); + new IntentHandler(null, null), + new ActivityTabStartupMetricsTracker(new ObservableSupplier<TabModelSelector>() { + @Override + public TabModelSelector addObserver(Callback<TabModelSelector> obs) { + return null; + } + + @Override + public void removeObserver(Callback<TabModelSelector> obs) {} + + @Override + public TabModelSelector get() { + return null; + } + })); } private static class ChromeTabCreatorManager implements TabCreatorManager {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/RequestDesktopSiteTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/RequestDesktopSiteTest.java index c615b47..8cdd0c0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/RequestDesktopSiteTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/RequestDesktopSiteTest.java
@@ -51,7 +51,7 @@ @Batch(Batch.PER_CLASS) @Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) -@Features.EnableFeatures(ContentFeatureList.REQUEST_DESKTOP_SITE_GLOBAL) +@Features.EnableFeatures(ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS) public class RequestDesktopSiteTest { private static final String URL_1 = "https://www.chromium.org/"; private static final String URL_2 = "https://www.example.com/";
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java index bfdec2d3..565cac067 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabPersistentStoreUnitTest.java
@@ -35,6 +35,8 @@ import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabImpl; import org.chromium.chrome.browser.tab.TabLaunchType; @@ -339,6 +341,13 @@ metadata.incognitoModelMetadata.urls.get(0)); Assert.assertEquals("Incorrect URL for second incognito tab.", INCOGNITO_TAB_STRING_2, metadata.incognitoModelMetadata.urls.get(1)); + + Assert.assertEquals("Incorrect number of cached normal tab count.", 1, + SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.REGULAR_TAB_COUNT)); + Assert.assertEquals("Incorrect number of cached incognito tab count.", 2, + SharedPreferencesManager.getInstance().readInt( + ChromePreferenceKeys.INCOGNITO_TAB_COUNT)); } @Test @@ -405,6 +414,8 @@ when(incognitoTab2.getUrl()).thenReturn(gurl); when(incognitoTab2.isIncognito()).thenReturn(true); when(mIncognitoTabModel.getTabAt(1)).thenReturn(incognitoTab2); + + when(mTabModelSelector.getTotalTabCount()).thenReturn(3); } private static class LoadUrlParamsUrlMatcher implements ArgumentMatcher<LoadUrlParams> {
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index e026f94..f3c3e67 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -3841,129 +3841,129 @@ Loading... </message> - <!-- Consolidated Consent OOBE screen. --> - <!-- TODO(crbug.com/1249479): Remove translateable tags when strings are finalized. --> - <message name="IDS_CONSOLIDATED_CONSENT_HEADER" desc="Title of the consolidated consent screen." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_HEADER" desc="Title of the consolidated consent screen."> Review these terms and control your data </message> - <message name="IDS_CONSOLIDATED_CONSENT_HEADER_CHILD" desc="Title of the consolidated consent screen for child account." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_HEADER_CHILD" desc="Title of the consolidated consent screen for child account."> Review these terms and control your child's data </message> - <message name="IDS_CONSOLIDATED_CONSENT_SUBHEADER" desc="Subtitle of the consolidated consent screen." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_SUBHEADER" desc="Subtitle of the consolidated consent screen."> You can control what data is shared with Google. You can change this anytime in Settings. Data will be used according to Google's <ph name="BEGIN_LINK"><a id="privacyPolicyLink"></ph>Privacy Policy<ph name="END_LINK"></a></ph>. </message> - <message name="IDS_CONSOLIDATED_CONSENT_TERMS_TITLE" desc="Title of the main terms and conditions to be accepted in the consolidated consent screen" translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_TERMS_TITLE" desc="Title of the main terms and conditions to be accepted in the consolidated consent screen"> Terms and conditions </message> - <message name="IDS_CONSOLIDATED_CONSENT_TERMS" desc="Main terms to be accepted in the consolidated consent screen." translateable="false"> - I have read and agree to the <ph name="BEGIN_LINK1"><a id="googleEulaLink"></ph>Google Terms of Service<ph name="END_LINK1"></a></ph>, <ph name="BEGIN_LINK2"><a id="crosEulaLink"></ph>Chrome and Chrome OS Additional Terms of Service<ph name="END_LINK2"></a></ph>, and <ph name="BEGIN_LINK3"><a id="arcTosLink"></ph>Play Terms of Service<ph name="END_LINK3"></a></ph>. + <message name="IDS_CONSOLIDATED_CONSENT_TERMS" desc="Main terms to be accepted in the consolidated consent screen."> + I have read and agree to the <ph name="BEGIN_LINK1"><a id="googleEulaLink"></ph>Google Terms of Service<ph name="END_LINK1"></a></ph>, <ph name="BEGIN_LINK2"><a id="crosEulaLink"></ph>Chrome and ChromeOS Additional Terms of Service<ph name="END_LINK2"></a></ph> and <ph name="BEGIN_LINK3"><a id="arcTosLink"></ph>Play Terms of Service<ph name="END_LINK3"></a></ph>. </message> - <message name="IDS_CONSOLIDATED_CONSENT_TERMS_ARC_DISABLED" desc="Main terms to be accepted in the consolidated consent screen when arc is disabled." translateable="false"> - I have read and agree to the <ph name="BEGIN_LINK1"><a id="googleEulaLinkArcDisabled"></ph>Google Terms of Service<ph name="END_LINK1"></a></ph> and <ph name="BEGIN_LINK2"><a id="crosEulaLinkArcDisabled"></ph>Chrome and Chrome OS Additional Terms of Service<ph name="END_LINK2"></a></ph>. + <message name="IDS_CONSOLIDATED_CONSENT_TERMS_ARC_DISABLED" desc="Main terms to be accepted in the consolidated consent screen when arc is disabled."> + I have read and agree to the <ph name="BEGIN_LINK1"><a id="googleEulaLinkArcDisabled"></ph>Google Terms of Service<ph name="END_LINK1"></a></ph> and <ph name="BEGIN_LINK2"><a id="crosEulaLinkArcDisabled"></ph>Chrome and ChromeOS Additional Terms of Service<ph name="END_LINK2"></a></ph>. </message> - <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_TITLE" desc="Title for the message in the consolidated consent screen to opt-in for metrics for accounts." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_TITLE" desc="Title for the message in the consolidated consent screen to opt-in for metrics for accounts."> Send usage and diagnostic data. </message> - <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN" desc="Message in the consolidated consent screen to opt-in for metrics." translateable="false"> - Help improve Chrome OS features and performance by automatically sending crash reports as well as diagnostic and usage data to Google. Some aggregate data will also help Android apps and Google partners. If the Web & App Activity setting is turned on for your Google Account, your Android data may be saved to your Google Account. + <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN" desc="Message in the consolidated consent screen to opt-in for metrics."> + Help improve Chrome and ChromeOS features and performance by automatically sending crash reports as well as diagnostic and usage data to Google. Some aggregate data will also help Android apps and Google partners. If the Web & App Activity setting is turned on for your Google Account, your Android data may be saved to your Google Account. </message> - <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_CHILD" desc="Message in the consolidated consent screen to opt-in for metrics for a child account." translateable="false"> - Help improve Chrome OS features and performance by automatically sending crash reports as well as diagnostic and usage data to Google. Some aggregate data will also help Android apps and Google partners. If the Web & App Activity setting is turned on for your child's Google Account, your child's Android data may be saved to your child's Google Account. + <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_CHILD" desc="Message in the consolidated consent screen to opt-in for metrics for a child account."> + Help improve Chrome and ChromeOS features and performance by automatically sending crash reports as well as diagnostic and usage data to Google. Some aggregate data will also help Android apps and Google partners. If the Web & App Activity setting is turned on for your child's Google Account, your child's Android data may be saved to your child's Google Account. </message> - <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_ARC_DISABLED" desc="Message in the consolidated consent screen to opt-in for metrics when ARC is disabled." translateable="false"> - Help improve Chrome OS features and performance by automatically sending crash reports as well as diagnostic and usage data to Google. + <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_ARC_DISABLED" desc="Message in the consolidated consent screen to opt-in for metrics when ARC is disabled."> + Help improve Chrome and ChromeOS features and performance by automatically sending crash reports as well as diagnostic and usage data to Google. </message> - <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for metrics opt-in." translateable="false"> - <ph name="BEGIN_PARAGRAPH1"><p></ph>Allowing your Chrome OS devices to send automatic reports helps us prioritize what to fix and improve in Chrome OS. These reports can include things like when Chrome OS crashes, which features you use, how much memory you typically use, and Android app diagnostic and usage data. Some aggregate data will also help Google apps and partners, such as Android developers.<ph name="END_PARAGRAPH1"></p></ph> - <ph name="BEGIN_PARAGRAPH2"><p></ph>You can start or stop allowing these reports any time in your Chrome OS device settings. If you’re a domain administrator, you can change this setting in the admin console.<ph name="END_PARAGRAPH2"></p></ph> + <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for metrics opt-in."> + <ph name="BEGIN_PARAGRAPH1"><p></ph>Help improve Chrome and ChromeOS features and performance by automatically sending crash reports as well as diagnostic and usage data to Google.<ph name="END_PARAGRAPH1"></p></ph> + <ph name="BEGIN_PARAGRAPH2"><p></ph>You can start or stop allowing these reports any time in your ChromeOS device settings. If you're a domain administrator, you can change this setting in the admin console.<ph name="END_PARAGRAPH2"></p></ph> <ph name="BEGIN_PARAGRAPH3"><p></ph>Turning off this feature doesn't affect your device's ability to send the information needed for essential services such as system updates and security.<ph name="END_PARAGRAPH3"></p></ph> <ph name="BEGIN_PARAGRAPH4"><p></ph>If the Web & App Activity setting is turned on for your Google Account, your Android data may be saved to your Google Account. You can see your data, delete it, and change your account settings at account.google.com.<ph name="END_PARAGRAPH4"></p></ph> </message> - <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_CHILD" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for metrics opt-in for a child account." translateable="false"> - <ph name="BEGIN_PARAGRAPH1"><p></ph>Allowing Chrome OS devices to send automatic reports helps us prioritize what to fix and improve in Chrome OS. These reports can include things like when Chrome OS crashes, which features were used, how much memory was typically used, and Android app diagnostic and usage data. Some aggregate data will also help Google apps and partners, such as Android developers.<ph name="END_PARAGRAPH1"></p></ph> - <ph name="BEGIN_PARAGRAPH2"><p></ph>You can start or stop allowing these reports any time in your child's Chrome OS device settings. If you're a domain administrator, you can change this setting in the admin console.<ph name="END_PARAGRAPH2"></p></ph> + <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_CHILD" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for metrics opt-in for a child account."> + <ph name="BEGIN_PARAGRAPH1"><p></ph>Allowing ChromeOS devices to send automatic reports helps us prioritize what to fix and improve in ChromeOS. These reports can include things like when ChromeOS crashes, which features were used, how much memory was typically used, and Android app diagnostic and usage data. Some aggregate data will also help Google apps and partners, such as Android developers.<ph name="END_PARAGRAPH1"></p></ph> + <ph name="BEGIN_PARAGRAPH2"><p></ph>You can start or stop allowing these reports any time in your child's ChromeOS device settings. If you're a domain administrator, you can change this setting in the admin console.<ph name="END_PARAGRAPH2"></p></ph> <ph name="BEGIN_PARAGRAPH3"><p></ph>Turning off this feature doesn't affect this device's ability to send the information needed for essential services such as system updates and security.<ph name="END_PARAGRAPH3"></p></ph> - <ph name="BEGIN_PARAGRAPH4"><p></ph>If the Web & App Activity setting is turned on for your child’s Google Account, your child’s Android data may be saved to their Google Account. Learn more about these settings and how to adjust them at families.google.com.<ph name="END_PARAGRAPH4"></p></ph> + <ph name="BEGIN_PARAGRAPH4"><p></ph>If the Web & App Activity setting is turned on for your child's Google Account, your child's data may be saved to their Google Account. Learn more about these settings and how to adjust them at families.google.com.<ph name="END_PARAGRAPH4"></p></ph> </message> - <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_ARC_DISABLED" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for metrics opt-in when ARC is disabled." translateable="false"> - <ph name="BEGIN_PARAGRAPH1"><p></ph>Allowing Chrome OS devices to send automatic reports helps us prioritize what to fix and improve in Chrome OS. These reports can include things like when Chrome OS crashes, which features were used, how much memory was typically used.<ph name="END_PARAGRAPH1"></p></ph> + <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_ARC_DISABLED" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for metrics opt-in when ARC is disabled."> + <ph name="BEGIN_PARAGRAPH1"><p></ph>Allowing ChromeOS devices to send automatic reports helps us prioritize what to fix and improve in ChromeOS. These reports can include things like when ChromeOS crashes, which features were used, and how much memory was typically used.<ph name="END_PARAGRAPH1"></p></ph> <ph name="BEGIN_PARAGRAPH2"><p></ph>You can start or stop allowing these reports any time in your Chrome device settings. If you’re a domain administrator, you can change this setting in the admin console.<ph name="END_PARAGRAPH2"></p></ph> + <ph name="BEGIN_PARAGRAPH3"><p></ph>Turning off this feature doesn't affect your device's ability to send the information needed for essential services such as system updates and security.<ph name="END_PARAGRAPH3"></p></ph> </message> - <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_ARC_DISABLED_CHILD" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for metrics opt-in when ARC is disabled in a child account." translateable="false"> - <ph name="BEGIN_PARAGRAPH1"><p></ph>Allowing Chrome OS devices to send automatic reports helps us prioritize what to fix and improve in Chrome OS. These reports can include things like when Chrome OS crashes, which features were used, how much memory was typically used, and Android app diagnostic and usage data. Some aggregate data will also help Google apps and partners, such as Android developers.<ph name="END_PARAGRAPH1"></p></ph> - <ph name="BEGIN_PARAGRAPH2"><p></ph>You can start or stop allowing these reports any time in your child's Chrome OS device settings. If you're a domain administrator, you can change this setting in the admin console.<ph name="END_PARAGRAPH2"></p></ph> + <message name="IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_ARC_DISABLED_CHILD" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for metrics opt-in when ARC is disabled in a child account."> + <ph name="BEGIN_PARAGRAPH1"><p></ph>Allowing ChromeOS devices to send automatic reports helps us prioritize what to fix and improve in ChromeOS. These reports can include things like when ChromeOS crashes, which features were used, and how much memory was typically used.<ph name="END_PARAGRAPH1"></p></ph> + <ph name="BEGIN_PARAGRAPH2"><p></ph>You can start or stop allowing these reports any time in your child's ChromeOS device settings. If you're a domain administrator, you can change this setting in the admin console.<ph name="END_PARAGRAPH2"></p></ph> + <ph name="BEGIN_PARAGRAPH3"><p></ph>Turning off this feature doesn't affect this device's ability to send the information needed for essential services such as system updates and security.<ph name="END_PARAGRAPH3"></p></ph> </message> - <message name="IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_TITLE" desc="Title for the message in the consolidated consent screen to opt-in for back-up." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_TITLE" desc="Title for the message in the consolidated consent screen to opt-in for back-up."> Back up Android apps to Google Drive. </message> - <message name="IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN" desc="Message in the consolidated consent screen to opt-in for back-up." translateable="false"> - Easily restore your data or switch device at any time. Your backups are uploaded to Google and encrypted using your Google Account password. + <message name="IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN" desc="Message in the consolidated consent screen to opt-in for back-up."> + Easily restore your data or switch devices at any time. Your backups are uploaded to Google and encrypted using your Google Account password. </message> - <message name="IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_CHILD" desc="Message in the consolidated consent screen to opt-in for back-up for a child account." translateable="false"> - Easily restore your data or switch devices at any time. Backups are uploaded to Google and encrypted using your child’s Google Account password + <message name="IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_CHILD" desc="Message in the consolidated consent screen to opt-in for back-up for a child account."> + Easily restore data or switch devices at any time. Backups are uploaded to Google and encrypted using your child's Google Account password. </message> - <message name="IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_LEARN_MORE" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for back-up opt-in." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_LEARN_MORE" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for back-up opt-in."> <ph name="BEGIN_PARAGRAPH1"><p></ph>App data can be any data that an app has saved (based on developer settings), including data such as contacts, messages, and photos. Backup data will not count toward your Drive storage quota.<ph name="END_PARAGRAPH1"></p></ph> <ph name="BEGIN_PARAGRAPH2"><p></ph>You can turn this service off in Settings.<ph name="END_PARAGRAPH2"></p></ph> </message> - <message name="IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_LEARN_MORE_CHILD" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for back-up opt-in for a child account." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_LEARN_MORE_CHILD" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for back-up opt-in for a child account."> <ph name="BEGIN_PARAGRAPH1"><p></ph>App data can be any data that an app has saved (based on developer settings), including data such as contacts, messages, and photos. Backup data will not count toward your child's Drive storage quota.<ph name="END_PARAGRAPH1"></p></ph> <ph name="BEGIN_PARAGRAPH2"><p></ph>You can turn this service off in Settings.<ph name="END_PARAGRAPH2"></p></ph> </message> - <message name="IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_TITLE" desc="Title for the message in the consolidated consent screen to opt-in for location services." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_TITLE" desc="Title for the message in the consolidated consent screen to opt-in for location services."> Use location for Android apps and services. </message> - <message name="IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN" desc="Message in the consolidated consent screen to opt-in for location services." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN" desc="Message in the consolidated consent screen to opt-in for location services."> Allow Android apps and services with location permission to use your device's location. Google may collect location data periodically and use this data in an anonymous way to improve location accuracy and location-based services. </message> - <message name="IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_CHILD" desc="Message in the consolidated consent screen to opt-in for location services for child accounts." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_CHILD" desc="Message in the consolidated consent screen to opt-in for location services for child accounts."> Allow Android apps and services with location permission to use this device's location. Google may collect location data periodically and use this data in an anonymous way to improve location accuracy and location-based services. </message> - <message name="IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_LEARN_MORE" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for location services opt-in." translateable="false"> - <ph name="BEGIN_PARAGRAPH1"><p></ph>Google's location service uses sources like Wi-Fi, mobile networks, and sensors to help estimate your device’s location.<ph name="END_PARAGRAPH1"></p></ph> - <ph name="BEGIN_PARAGRAPH2"><p></ph>You can turn off Android location on your device at any time by going to Settings > Apps > Google Play Store > Manage Android preferences > Security & location > Location. You can also turn off the use of Wi-Fi, mobile networks, and sensors by turning off “Google Location Accuracy” in the same menu.<ph name="END_PARAGRAPH2"></p></ph> + <message name="IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_LEARN_MORE" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for location services opt-in."> + <ph name="BEGIN_PARAGRAPH1"><p></ph>Google's location service uses sources like Wi-Fi, mobile networks, and sensors to help estimate your device's location.<ph name="END_PARAGRAPH1"></p></ph> + <ph name="BEGIN_PARAGRAPH2"><p></ph>You can turn off Android location on your device at any time by going to Settings > Apps > Google Play Store > Manage Android preferences > Security & location > Location. You can also turn off the use of Wi-Fi, mobile networks, and sensors for Android location by turning off “Google Location Accuracy” in the same menu.<ph name="END_PARAGRAPH2"></p></ph> </message> - <message name="IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_LEARN_MORE_CHILD" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for location services opt-in. for a child account" translateable="false"> - <ph name="BEGIN_PARAGRAPH1"><p></ph>Google's location service uses sources like Wi-Fi, mobile networks, and sensors to help estimate this device’s location.<ph name="END_PARAGRAPH1"></p></ph> - <ph name="BEGIN_PARAGRAPH2"><p></ph>You can turn off Android location on this device at any time by going to Settings > Apps > Google Play Store > Manage Android preferences > Security & location > Location. You can also turn off the use of Wi-Fi, mobile networks, and sensors by turning off “Google Location Accuracy” in the same menu.<ph name="END_PARAGRAPH2"></p></ph> + <message name="IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_LEARN_MORE_CHILD" desc="Text shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more for location services opt-in. for a child account"> + <ph name="BEGIN_PARAGRAPH1"><p></ph>Google's location service uses sources like Wi-Fi, mobile networks, and sensors to help estimate this device's location.<ph name="END_PARAGRAPH1"></p></ph> + <ph name="BEGIN_PARAGRAPH2"><p></ph>You can turn off Android location on this device at any time by going to Settings > Apps > Google Play Store > Manage Android preferences > Security & location > Location. You can also turn off the use of Wi-Fi, mobile networks, and sensors for Android location by turning off “Google Location Accuracy” in the same menu.<ph name="END_PARAGRAPH2"></p></ph> </message> - <message name="IDS_CONSOLIDATED_CONSENT_FOOTER" desc="Message in the footer of the consolidated consent screen." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_FOOTER" desc="Message in the footer of the consolidated consent screen."> By continuing, you agree that this device may also automatically download and install updates and apps from Google, your carrier, and your device's manufacturer, possibly using cellular data. Some of these apps may offer in-app purchases. </message> - <message name="IDS_CONSOLIDATED_CONSENT_FOOTER_CHILD" desc="Message in the footer of the consolidated consent screen for a child account." translateable="false"> - By continuing, you agree that this device may also automatically download and install updates and apps from Google, your child’s carrier, and this device's manufacturer, possibly using cellular data. Some of these apps may offer in-app purchases. + <message name="IDS_CONSOLIDATED_CONSENT_FOOTER_CHILD" desc="Message in the footer of the consolidated consent screen for a child account."> + By continuing, you agree that this device may also automatically download and install updates and apps from Google, your child's carrier, and this device's manufacturer, possibly using cellular data. Some of these apps may offer in-app purchases. </message> - <message name="IDS_CONSOLIDATED_CONSENT_FOOTER_LEARN_MORE" desc="Message shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more in the footer." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_FOOTER_LEARN_MORE" desc="Message shown in a pop-up dialog in the consolidated consent screen when the user clicks on the learn more in the footer."> To remove apps, go to Settings > Apps > Google Play Store > Manage Android preferences > Apps or Application manager. Then tap the app you want to uninstall (you may need to swipe right or left to find the app). Then tap Uninstall or Disable. </message> - <message name="IDS_CONSOLIDATED_CONSENT_LEARN_MORE" desc="Learn more link text in the consolidated consent screen." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_LEARN_MORE" desc="Learn more link text in the consolidated consent screen."> Learn more </message> - <message name="IDS_CONSOLIDATED_CONSENT_ACCEPT_AND_CONTINUE" desc="Accept and continue button in the consolidated consent screen." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_ACCEPT_AND_CONTINUE" desc="Accept and continue button in the consolidated consent screen."> Accept and continue </message> - <message name="IDS_CONSOLIDATED_CONSENT_OK" desc="Button for acknowledging in a dialog for terms of service." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_OK" desc="Button for acknowledging in a dialog for terms of service."> OK </message> - <message name="IDS_CONSOLIDATED_CONSENT_LOADING" desc="Message shown while the terms of service are being downloaded." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_LOADING" desc="Message shown while the terms of service are being downloaded."> Loading... </message> - <message name="IDS_CONSOLIDATED_CONSENT_TERMS_LOAD_ERROR" desc="Load error message of the consolidated consent dialog." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_TERMS_LOAD_ERROR" desc="Load error message of the consolidated consent dialog."> Terms of Service cannot be loaded. Please check your network connection and retry. </message> - <message name="IDS_CONSOLIDATED_CONSENT_RETRY" desc="Retry button of the consolidated consent dialog that reloads terms of service." translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_RETRY" desc="Retry button of the consolidated consent dialog that reloads terms of service."> Retry </message> - <message name="IDS_CONSOLIDATED_CONSENT_GOOGLE_EULA_TITLE" desc="Title of Google terms of service screen" translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_GOOGLE_EULA_TITLE" desc="Title of Google terms of service screen"> Google terms of service </message> - <message name="IDS_CONSOLIDATED_CONSENT_CROS_EULA_TITLE" desc="Title of Google Chrome and Chrome OS additional terms screen" translateable="false"> - Google Chrome and Chrome OS Additional Terms + <message name="IDS_CONSOLIDATED_CONSENT_CROS_EULA_TITLE" desc="Title of Google Chrome and Chrome OS additional terms screen"> + Google Chrome and ChromeOS Additional Terms </message> - <message name="IDS_CONSOLIDATED_CONSENT_ARC_TITLE" desc="Title of Goolge Play terms of service in opt-in screen" translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_ARC_TITLE" desc="Title of Goolge Play terms of service in opt-in screen"> Google Play terms of service </message> - <message name="IDS_CONSOLIDATED_CONSENT_PRIVACY_POLICY_TITLE" desc="Text of the Link to Goolge Privacy Policy in opt-in screen" translateable="false"> + <message name="IDS_CONSOLIDATED_CONSENT_PRIVACY_POLICY_TITLE" desc="Text of the Link to Goolge Privacy Policy in opt-in screen"> Google privacy policy </message> @@ -3975,7 +3975,7 @@ Terms and conditions </message> <message name="IDS_GUEST_TOS_TERMS" desc="Terms and conditions to be accepted before starting a guest session"> - I have read and agree to the <ph name="BEGIN_LINK1"><a id="googleEulaLink"></ph>Google Terms of Service<ph name="END_LINK1"></a></ph>, <ph name="BEGIN_LINK2"><a id="crosEulaLink"></ph>Chrome and Chrome OS Additional Terms of Service<ph name="END_LINK2"></a></ph>. + I have read and agree to the <ph name="BEGIN_LINK1"><a id="googleEulaLink"></ph>Google Terms of Service<ph name="END_LINK1"></a></ph>, <ph name="BEGIN_LINK2"><a id="crosEulaLink"></ph>Chrome and ChromeOS Additional Terms of Service<ph name="END_LINK2"></a></ph>. </message> <message name="IDS_GUEST_TOS_LOADING" desc="Message shown while the terms of service are being downloaded"> Loading... @@ -3990,21 +3990,20 @@ Google terms of service </message> <message name="IDS_GUEST_TOS_CROS_EULA_TITLE" desc="Title of Google Chrome and Chrome OS additional terms screen"> - Google Chrome and Chrome OS Additional Terms + Google Chrome and ChromeOS Additional Terms </message> - <!-- TODO(crbug.com/1241468): remove translateable="false" once the strings are finalized--> - <message name="IDS_GUEST_TOS_USAGE_OPT_IN_TITLE" desc="Title for the message in the guest terms of service screen to opt-in for metrics during the guest session." translateable="false"> + <message name="IDS_GUEST_TOS_USAGE_OPT_IN_TITLE" desc="Title for the message in the guest terms of service screen to opt-in for metrics during the guest session."> Send usage and diagnostic data. </message> - <message name="IDS_GUEST_TOS_USAGE_OPT_IN" desc="Message in the guest terms of service screen to opt-in for metrics during the guest session." translateable="false"> - Help improve Chrome and Chrome OS features and performance by automatically sending crash reports as well as diagnostic and usage data to Google. Some aggregate data will also help Android apps and Google partners. If the Web & App Activity setting is turned on for your Google Account, your Android data may be saved to your Google Account. + <message name="IDS_GUEST_TOS_USAGE_OPT_IN" desc="Message in the guest terms of service screen to opt-in for metrics during the guest session."> + Help improve Chrome and ChromeOS features and performance by automatically sending crash reports as well as diagnostic and usage data to Google. </message> - <message name="IDS_GUEST_TOS_LEARN_MORE" desc="Learn more link text in guest terms of service screen." translateable="false"> + <message name="IDS_GUEST_TOS_LEARN_MORE" desc="Learn more link text in guest terms of service screen."> Learn more </message> - <message name="IDS_GUEST_TOS_USAGE_OPT_IN_LEARN_MORE" desc="Text shown in a pop-up dialog in the guest terms of service screen when the user clicks on the learn more for metrics opt-in." translateable="false"> - <ph name="BEGIN_PARAGRAPH1"><p></ph>Allowing your Chrome OS devices to send automatic reports helps us prioritize what to fix and improve in Chrome OS. These reports can include things like when Chrome OS crashes, which features you use, how much memory you typically use, and Android app diagnostic and usage data. Some aggregate data will also help Google apps and partners, such as Android developers.<ph name="END_PARAGRAPH1"></p></ph> - <ph name="BEGIN_PARAGRAPH2"><p></ph>You can start or stop allowing these reports any time in your Chrome OS device settings. If you’re a domain administrator, you can change this setting in the admin console.<ph name="END_PARAGRAPH2"></p></ph> + <message name="IDS_GUEST_TOS_USAGE_OPT_IN_LEARN_MORE" desc="Text shown in a pop-up dialog in the guest terms of service screen when the user clicks on the learn more for metrics opt-in."> + <ph name="BEGIN_PARAGRAPH1"><p></ph>Allowing ChromeOS devices to send automatic reports helps us prioritize what to fix and improve in ChromeOS. These reports can include things like when ChromeOS crashes, which features were used, and how much memory was typically used.<ph name="END_PARAGRAPH1"></p></ph> + <ph name="BEGIN_PARAGRAPH2"><p></ph>You can start or stop allowing these reports any time in your Chrome device settings. If you’re a domain administrator, you can change this setting in the admin console.<ph name="END_PARAGRAPH2"></p></ph> <ph name="BEGIN_PARAGRAPH3"><p></ph>Turning off this feature doesn't affect your device's ability to send the information needed for essential services such as system updates and security.<ph name="END_PARAGRAPH3"></p></ph> </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_ACCEPT_AND_CONTINUE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_ACCEPT_AND_CONTINUE.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_ACCEPT_AND_CONTINUE.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_ARC_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_ARC_TITLE.png.sha1 new file mode 100644 index 0000000..90800b0b --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_ARC_TITLE.png.sha1
@@ -0,0 +1 @@ +caa1984381db43926599c1dffce503834fad593d \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_CHILD.png.sha1 new file mode 100644 index 0000000..285e5ae --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_CHILD.png.sha1
@@ -0,0 +1 @@ +26fc2f6897ae10dd0765236f6542df3d74d56e0c \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_LEARN_MORE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_LEARN_MORE.png.sha1 new file mode 100644 index 0000000..37ebd37 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_LEARN_MORE.png.sha1
@@ -0,0 +1 @@ +93d95c7f1882f7dc47730473833e4a141a203ff4 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_LEARN_MORE_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_LEARN_MORE_CHILD.png.sha1 new file mode 100644 index 0000000..04332a78 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_LEARN_MORE_CHILD.png.sha1
@@ -0,0 +1 @@ +d8797333c964e68698b60747fcce0cad9f0e8844 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_TITLE.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_BACKUP_OPT_IN_TITLE.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_CROS_EULA_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_CROS_EULA_TITLE.png.sha1 new file mode 100644 index 0000000..ade2b9a --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_CROS_EULA_TITLE.png.sha1
@@ -0,0 +1 @@ +a2d6df5aefc0752829e9dac84ce77eda06797d7f \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_FOOTER.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_FOOTER.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_FOOTER.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_FOOTER_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_FOOTER_CHILD.png.sha1 new file mode 100644 index 0000000..285e5ae --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_FOOTER_CHILD.png.sha1
@@ -0,0 +1 @@ +26fc2f6897ae10dd0765236f6542df3d74d56e0c \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_FOOTER_LEARN_MORE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_FOOTER_LEARN_MORE.png.sha1 new file mode 100644 index 0000000..48f85d52 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_FOOTER_LEARN_MORE.png.sha1
@@ -0,0 +1 @@ +605c0c53c9298fb6666b9c9778bfd6a32b1e8418 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_GOOGLE_EULA_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_GOOGLE_EULA_TITLE.png.sha1 new file mode 100644 index 0000000..3656d4f --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_GOOGLE_EULA_TITLE.png.sha1
@@ -0,0 +1 @@ +c2865ec769867bbcd02e33a03d0da031e410c0ed \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_HEADER.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_HEADER.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_HEADER.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_HEADER_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_HEADER_CHILD.png.sha1 new file mode 100644 index 0000000..285e5ae --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_HEADER_CHILD.png.sha1
@@ -0,0 +1 @@ +26fc2f6897ae10dd0765236f6542df3d74d56e0c \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LEARN_MORE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LEARN_MORE.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LEARN_MORE.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOADING.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOADING.png.sha1 new file mode 100644 index 0000000..bb1f5a9 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOADING.png.sha1
@@ -0,0 +1 @@ +e0788ab2cb777ae44aad19befed909dca7f4b30c \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_CHILD.png.sha1 new file mode 100644 index 0000000..285e5ae --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_CHILD.png.sha1
@@ -0,0 +1 @@ +26fc2f6897ae10dd0765236f6542df3d74d56e0c \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_LEARN_MORE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_LEARN_MORE.png.sha1 new file mode 100644 index 0000000..fba0d06 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_LEARN_MORE.png.sha1
@@ -0,0 +1 @@ +dda57bef355ced8e9ab4aedacbf3c08ff447fb19 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_LEARN_MORE_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_LEARN_MORE_CHILD.png.sha1 new file mode 100644 index 0000000..93302b4 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_LEARN_MORE_CHILD.png.sha1
@@ -0,0 +1 @@ +97376b8b5b28b335a91fef2632892c60fc4a20be \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_TITLE.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_LOCATION_OPT_IN_TITLE.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_OK.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_OK.png.sha1 new file mode 100644 index 0000000..3656d4f --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_OK.png.sha1
@@ -0,0 +1 @@ +c2865ec769867bbcd02e33a03d0da031e410c0ed \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_PRIVACY_POLICY_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_PRIVACY_POLICY_TITLE.png.sha1 new file mode 100644 index 0000000..83ae97bd --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_PRIVACY_POLICY_TITLE.png.sha1
@@ -0,0 +1 @@ +4e2136de56423ca456ed85db157e085444db178e \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_RETRY.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_RETRY.png.sha1 new file mode 100644 index 0000000..a262a5bf --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_RETRY.png.sha1
@@ -0,0 +1 @@ +2985e5a86e9d7dba1e0bacf3b54a2d670e909ce6 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_SUBHEADER.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_SUBHEADER.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_SUBHEADER.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS_ARC_DISABLED.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS_ARC_DISABLED.png.sha1 new file mode 100644 index 0000000..cd5c1c3 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS_ARC_DISABLED.png.sha1
@@ -0,0 +1 @@ +8b95ea832e533a6967a8c1af90b2021b554264ef \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS_LOAD_ERROR.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS_LOAD_ERROR.png.sha1 new file mode 100644 index 0000000..a262a5bf --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS_LOAD_ERROR.png.sha1
@@ -0,0 +1 @@ +2985e5a86e9d7dba1e0bacf3b54a2d670e909ce6 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS_TITLE.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_TERMS_TITLE.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_ARC_DISABLED.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_ARC_DISABLED.png.sha1 new file mode 100644 index 0000000..cd5c1c3 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_ARC_DISABLED.png.sha1
@@ -0,0 +1 @@ +8b95ea832e533a6967a8c1af90b2021b554264ef \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_CHILD.png.sha1 new file mode 100644 index 0000000..285e5ae --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_CHILD.png.sha1
@@ -0,0 +1 @@ +26fc2f6897ae10dd0765236f6542df3d74d56e0c \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE.png.sha1 new file mode 100644 index 0000000..d03a2c2 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE.png.sha1
@@ -0,0 +1 @@ +75ad18d7aed397b35c3d5a0c1360f9088d4302ab \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_ARC_DISABLED.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_ARC_DISABLED.png.sha1 new file mode 100644 index 0000000..0b5d342 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_ARC_DISABLED.png.sha1
@@ -0,0 +1 @@ +f8ffbfb330a414c7677c2ae9a958ab48269d62ca \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_ARC_DISABLED_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_ARC_DISABLED_CHILD.png.sha1 new file mode 100644 index 0000000..723b2160 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_ARC_DISABLED_CHILD.png.sha1
@@ -0,0 +1 @@ +9d166db640031b7dc250045dad2cfecab69dbef2 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_CHILD.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_CHILD.png.sha1 new file mode 100644 index 0000000..2ce95b4 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_LEARN_MORE_CHILD.png.sha1
@@ -0,0 +1 @@ +e471883cb17f731c8b09e8b398d0003289ff1398 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_TITLE.png.sha1 new file mode 100644 index 0000000..eabfac4c --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONSOLIDATED_CONSENT_USAGE_OPT_IN_TITLE.png.sha1
@@ -0,0 +1 @@ +360a6de3943e7dba1bf2b7cd428fa288bf16f581 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_CROS_EULA_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_CROS_EULA_TITLE.png.sha1 index 2c7f6553..1015c78 100644 --- a/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_CROS_EULA_TITLE.png.sha1 +++ b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_CROS_EULA_TITLE.png.sha1
@@ -1 +1 @@ -c845ea1ddf9439af739f2b27b7a3527eedf2c18a \ No newline at end of file +f9857181d3658f319a6e48e0b6e12b285351c8be \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_GOOGLE_EULA_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_GOOGLE_EULA_TITLE.png.sha1 index bb4e542e..f47e540 100644 --- a/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_GOOGLE_EULA_TITLE.png.sha1 +++ b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_GOOGLE_EULA_TITLE.png.sha1
@@ -1 +1 @@ -f7fca1356098e34e57ec232aa05d2985614c117c \ No newline at end of file +4bc25a0d954e9c6e7aa371b43155f51966bc634d \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_LEARN_MORE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_LEARN_MORE.png.sha1 new file mode 100644 index 0000000..7ec0f2b --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_LEARN_MORE.png.sha1
@@ -0,0 +1 @@ +ba340c5adc10ee2de718606756743208032f0c3a \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_TERMS.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_TERMS.png.sha1 index f1471630..7ec0f2b 100644 --- a/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_TERMS.png.sha1 +++ b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_TERMS.png.sha1
@@ -1 +1 @@ -eca0aa463a2b4dfa258dc16192709ffb24e00322 \ No newline at end of file +ba340c5adc10ee2de718606756743208032f0c3a \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_USAGE_OPT_IN.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_USAGE_OPT_IN.png.sha1 new file mode 100644 index 0000000..7ec0f2b --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_USAGE_OPT_IN.png.sha1
@@ -0,0 +1 @@ +ba340c5adc10ee2de718606756743208032f0c3a \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_USAGE_OPT_IN_LEARN_MORE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_USAGE_OPT_IN_LEARN_MORE.png.sha1 new file mode 100644 index 0000000..89df05b --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_USAGE_OPT_IN_LEARN_MORE.png.sha1
@@ -0,0 +1 @@ +cca947f1495d0c62b1602e052f66f2fda4d45a2f \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_USAGE_OPT_IN_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_USAGE_OPT_IN_TITLE.png.sha1 new file mode 100644 index 0000000..7ec0f2b --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_GUEST_TOS_USAGE_OPT_IN_TITLE.png.sha1
@@ -0,0 +1 @@ +ba340c5adc10ee2de718606756743208032f0c3a \ No newline at end of file
diff --git a/chrome/app/gmc_strings.grdp b/chrome/app/gmc_strings.grdp index 20cba3d..4ccedf1 100644 --- a/chrome/app/gmc_strings.grdp +++ b/chrome/app/gmc_strings.grdp
@@ -4,11 +4,11 @@ <message name="IDS_GLOBAL_MEDIA_CONTROLS_ICON_TOOLTIP_TEXT" desc="Tooltip for the Global Media Controls icon, which appears in the toolbar. The tooltip appears on mouseover of the icon."> Control your music, videos, and more </message> - <message name="IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL" desc="Label to prompt users to select an audio or cast device to play from."> - Select a device: + <message name="IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL_WITH_COLON" desc="Label to prompt users to select an audio or cast device to play from."> + Cast to a device: </message> - <message name="IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_BUTTON_LABEL" desc="Label for a button that opens a menu for picking an audio or cast device to play from."> - Select a device + <message name="IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL" desc="Label for a button that opens a menu for picking an audio or cast device to play from."> + Cast to a device </message> <message name="IDS_GLOBAL_MEDIA_CONTROLS_STOP_CASTING_BUTTON_LABEL" desc="Label for a button that stops the current cast session."> Stop casting
diff --git a/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_BUTTON_LABEL.png.sha1 b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_BUTTON_LABEL.png.sha1 deleted file mode 100644 index 8bf15c64..0000000 --- a/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_BUTTON_LABEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -53cb8e5c3e20f4e6dca7086416e8ce2c3264990e \ No newline at end of file
diff --git a/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL.png.sha1 b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL.png.sha1 index ad0b01e..56a8fe8e 100644 --- a/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL.png.sha1 +++ b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL.png.sha1
@@ -1 +1 @@ -75e86e7d76de87ad7abaca8c91e818bac71016d7 \ No newline at end of file +da5f115d6920ad9cf0e0adbe3bae3ff9bdd47e26 \ No newline at end of file
diff --git a/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL_WITH_COLON.png.sha1 b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL_WITH_COLON.png.sha1 new file mode 100644 index 0000000..0aceb6e --- /dev/null +++ b/chrome/app/gmc_strings_grdp/IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL_WITH_COLON.png.sha1
@@ -0,0 +1 @@ +dae6e2f4c245ccdf7d89b0182a754356253e7bf9 \ No newline at end of file
diff --git a/chrome/app/resources/chromium_strings_am.xtb b/chrome/app/resources/chromium_strings_am.xtb index fcd41a3..830ab50 100644 --- a/chrome/app/resources/chromium_strings_am.xtb +++ b/chrome/app/resources/chromium_strings_am.xtb
@@ -28,6 +28,7 @@ <translation id="1981611865800294956">&Chromium OSን ለማዘመን ዳግም ያስነሱት</translation> <translation id="2008474315282236005">ይሄ 1 ንጥል ከዚህ መሣሪያ ይሰርዛል። ውሂብዎን በኋላ ላይ ሰርስረው ለማውጣት እንደ <ph name="USER_EMAIL" /> ሆነው ወደ Chromium ይግቡ።</translation> <translation id="2020032459870799438">ሌሎች የእርስዎ ይለፍ ቃላት ከውሂብ ጥሰቶች እና ሌሎች የደህንነት ችግሮች ነጻ መሆናቸውን ለማረጋገጥ <ph name="BEGIN_LINK" />በመለያ ወደ Chromium ይግቡ<ph name="END_LINK" />።</translation> +<translation id="2049376729098081731">በGoogle አገልግሎቶች ውስጥ ተጨማሪ ግላዊነት የተላበሱ ተሞክሮዎችን ለማግኘት የChromium ታሪክን ለማካተት እና ላለማካተት ይምረጡ</translation> <translation id="2174178932569897599">Chromiumን አብጅ</translation> <translation id="2185166961232948079">Chromium - በአውታረ መረብ ወደ መለያ መግባት - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">ኮምፒውተር የሚጋሩ ከሆኑ ጓደኛዎች እና ቤተሰብ ተለይተው ሊያስሱ እና Chromiumን በሚፈልጉበት መንገድ ማዋቀር ይችላሉ።</translation> @@ -39,6 +40,7 @@ <translation id="2401032172288869980">Chromium ለዚህ ጣቢያ የካሜራ እና የማይክሮፎን ፈቃዶች ያስፈልጉታል</translation> <translation id="2483889755041906834">በChromium ውስጥ</translation> <translation id="2485422356828889247">አራግፍ</translation> +<translation id="251127392410688874">Chromium ክፍት ድርን በሚጠብቁበት ጊዜ እርስዎን ከጣቢያ-ተሻጋሪ መከታተያ ለመጠበቅ እንዴት እንደሚያቅድ ይመልከቱ</translation> <translation id="2535480412977113886">የመለያ መግቢያ ዝርዝሮችዎ ጊዜ ያለፈባቸው ስለሆኑ Chromium OS ውሂብዎን ማመሳሰል አልቻለም።</translation> <translation id="2560420686485554789">Chromium ፋይሎችን ለማውረድ የማከማቻ መዳረሻ ያስፈልገዋል</translation> <translation id="2572494885440352020">Chromium አጋዥ</translation> @@ -224,6 +226,7 @@ <translation id="7339898014177206373">አዲሰ መስኮት</translation> <translation id="734373864078049451">የእርስዎ ድር፣ ዕልባቶች እና ሌሎች የChromium ነገሮች እዚህ ይኖራሉ።</translation> <translation id="7349591376906416160">የእርስዎ ስርዓት አስተዳዳሪ Chromium <ph name="TARGET_URL_HOSTNAME" />ን ለመድረስ <ph name="ALTERNATIVE_BROWSER_NAME" />ን እንዲከፍት አዋቅሮታል።</translation> +<translation id="7398989605938454041">በChromium መገለጫዎች ሁሉንም የChromium ነገሮችዎን መለየት ይችላሉ። ይህ በስራ እና በመዝናኛ መካከል መከፋፈልን ቀላል ያደርገዋል።</translation> <translation id="7448255348454382571">Chromium OSን ዳግም አስጀምር</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> - Chromium ግንባታ</translation> <translation id="7451052299415159299">Chromium ለዚህ ጣቢያ የእርስዎን ካሜራ ለመድረስ ፈቃድ ያስፈልገዋል</translation> @@ -244,6 +247,7 @@ <translation id="7828947555739565424">ይህን መለያ ያለው አንድ የChromium መገለጫ አስቀድሞ በዚህ መሣሪያ ላይ አለ</translation> <translation id="7857220146454061152">የወደፊቱን የChromium ዝመኔዎችን ለማግኘት፣ OS X 10.11 ወይም ከዚያ በኋላ ያለው ያስፈልግዎታል። ይህ ኮምፒተር OS X 10.10 እየተጠቀመ ነው።</translation> <translation id="7867198900892795913">Chromium ወደ የቅርብ ጊዜው ስሪት ሊዘመን አልቻለም፣ ስለዚህ አዲስ ባህሪያት እና የደህንነት ጥገናዎች እያመለጡዎት ናቸው። Chromiumን ማዘመን አለብዎት።</translation> +<translation id="788352880609666695">የሚከተሉት መለያዎች ለዚህ Chromium መገለጫ ይገኛሉ</translation> <translation id="7898472181347242998">መሣሪያዎ የተዘመነ ከሆነ ለማየት ወደ <ph name="LINK_BEGIN" />የChromium OS ቅንብሮች ይሂዱ<ph name="LINK_END" /></translation> <translation id="7937630085815544518">እንደ <ph name="USER_EMAIL_ADDRESS" /> ሆነው ወደ Chromium ገብተዋል። እባክዎ እንደገና ለመግባት ተመሳሳዩን መለያ ይጠቀሙ።</translation> <translation id="7975919845073681630">ይሄ ሁለተኛ የChromium ጭነት ነው፣ እና ነባሪ አሳሽዎ ማድረግ አይቻልም።</translation> @@ -256,6 +260,7 @@ <translation id="8290862415967981663">ይህ ፋይል አደገኛ ሊሆን ስለሚችል Chromium አግዶታል።</translation> <translation id="8330519371938183845">Chromiumን በመላ መሣሪያዎችዎ ላይ ለማሳመር እና ግላዊነት ለማላበስ</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" /> ከዚህ ቀደም Chromiumን እየተጠቀመ ነበር</translation> +<translation id="8357820681460164151">በሁሉም መሣሪያዎችዎ ላይ የእርስዎን የChromium አሳሽ ነገሮች ለመድረስ ይግቡ፣ ከዚያ ስምረትን ያብሩ</translation> <translation id="8417404458978023919">{0,plural, =1{በአንድ ቀን ውስጥ Chromiumን ዳግም አስጀምር}one{በ# ቀኖች ውስጥ Chromiumን ዳግም አስጀምር}other{በ# ቀኖች ውስጥ Chromiumን ዳግም አስጀምር}}</translation> <translation id="8453117565092476964">የጫኚው መዝገብ ተበላሽቷል ወይም ትክክል አይደለም። እባክዎ Chromiumን እንደገና ያውርዱ።</translation> <translation id="8493179195440786826">Chromium ጊዜው አልፎበታል</translation>
diff --git a/chrome/app/resources/chromium_strings_as.xtb b/chrome/app/resources/chromium_strings_as.xtb index f7f43d9..4ab9ea97 100644 --- a/chrome/app/resources/chromium_strings_as.xtb +++ b/chrome/app/resources/chromium_strings_as.xtb
@@ -28,6 +28,7 @@ <translation id="1981611865800294956">&Chromium OS আপডে’ট কৰিবলৈ পুনৰ লঞ্চ কৰক</translation> <translation id="2008474315282236005">এইটোৱে এই ডিভাইচটোৰ পৰা ১টা বস্তু মচিব। আপোনাৰ ডেটা পাছত পুনৰুদ্ধাৰ কৰিবলৈ Chromiumত <ph name="USER_EMAIL" /> হিচাপে ছাইন ইন কৰক।</translation> <translation id="2020032459870799438">আপোনাৰ অন্য পাছৱৰ্ডসমূহ ডেটা উলংঘন আৰু আন সুৰক্ষা সম্পৰ্কীয় সমস্যাৰ পৰা নিৰাপদে আছেনে নাই পৰীক্ষা কৰিবলৈ <ph name="BEGIN_LINK" />Chromiumত ছাইন ইন কৰক<ph name="END_LINK" />।</translation> +<translation id="2049376729098081731">Google সেৱাসমূহত অধিক ব্যক্তিগতকৃত অভিজ্ঞতা লাভ কৰিবলৈ Chromiumৰ ইতিহাস অন্তৰ্ভুক্ত কৰিবনে নকৰে সেয়া বাছনি কৰক</translation> <translation id="2174178932569897599">Chromium কাষ্টমাইজ কৰক</translation> <translation id="2185166961232948079">Chromium - নেটৱর্কত ছাইন ইন - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">আপুনি যদি কোনো কম্পিউটাৰ শ্বেয়াৰ কৰে, আপোনাৰ বন্ধুবৰ্গ আৰু পৰিয়ালে পৃথককৈ ব্ৰাউজ কৰিব পাৰে আৰু তেওঁলোকে বিচৰা ধৰণে Chromium ছেট আপ কৰিব পাৰে।</translation> @@ -39,6 +40,7 @@ <translation id="2401032172288869980">Chromiumক এই ছাইটটোৰ বাবে মাইক্ৰ’ফ’ন আৰু কেমেৰাৰ অনুমতিৰ আৱশ্যক</translation> <translation id="2483889755041906834">Chromiumত</translation> <translation id="2485422356828889247">আনইনষ্টল কৰক</translation> +<translation id="251127392410688874">মুক্ত ৱেব সুৰক্ষিত কৰি ৰাখি ক্ৰছ-ছাইট ট্ৰেকিঙৰ পৰা আপোনাক সুৰক্ষা প্ৰদান কৰিবলৈ Chromiumএ কেনেকৈ পৰিকল্পনা কৰে সেয়া চাওক</translation> <translation id="2535480412977113886">আপোনাৰ একাউণ্টৰ ছাইন ইনৰ সবিশেষ তথ্যৰ ম্যাদ উকলি যোৱাৰ বাবে Chromium OS আপোনাৰ ডেটা ছিংক কৰিব নোৱাৰিলে।</translation> <translation id="2560420686485554789">ফাইল ডাউনল'ড কৰিবলৈ Chromiumক ষ্ট'ৰেজৰ এক্সেছৰ আৱশ্যক</translation> <translation id="2572494885440352020">Chromium সহায়ক</translation> @@ -225,6 +227,7 @@ <translation id="7339898014177206373">নতুন ৱিণ্ড'</translation> <translation id="734373864078049451">আপোনাৰ ৱেব, বুকমার্ক আৰু আন Chromium বস্তুবোৰ ইয়াত থাকে।</translation> <translation id="7349591376906416160">আপোনাৰ ছিষ্টেমৰ প্ৰশাসকে Chromiumক <ph name="TARGET_URL_HOSTNAME" /> এক্সেছ কৰিবলৈ <ph name="ALTERNATIVE_BROWSER_NAME" /> খুলিবলৈ কনফিগাৰ কৰিছে।</translation> +<translation id="7398989605938454041">Chromiumৰ প্ৰ’ফাইলৰ জৰিয়তে আপুনি নিজৰ আটাইবোৰ Chromiumৰ বস্তু পৃথক কৰিব পাৰে। এইটোৱে কৰ্মস্থান আৰু মনোৰঞ্জনৰ মাজত বিভাজন কৰাটো অধিক সহজ কৰি তোলে।</translation> <translation id="7448255348454382571">Chromium OS ৰিষ্টার্ট কৰক</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> - Chromium Dev</translation> <translation id="7451052299415159299">এই ছাইটটোৰ বাবে আপোনাৰ কেমেৰালৈ এক্সেছ পাবলৈ Chromiumক অনুমতিৰ আৱশ্যক</translation> @@ -245,6 +248,7 @@ <translation id="7828947555739565424">এই ডিভাইচটোত এই একাউণ্টটোৰ সৈতে এটা Chromium প্ৰ’ফাইল ইতিমধ্যে আছে</translation> <translation id="7857220146454061152">Chromiumৰ ভৱিষ্যতৰ আপডে’টসমূহ পাবলৈ আপোনাক OS X 10.11 অথবা তাৰ পাছৰ সংস্কৰণৰ আৱশ্যক হ’ব। এই কম্পিউটাৰটোৱে OS X 10.10 ব্যৱহাৰ কৰি আছে।</translation> <translation id="7867198900892795913">Chromiumক শেহতীয়া সংস্কৰণলৈ আপডে’ট কৰিব পৰা নগ’ল, গতিকে আপুনি নতুন সুবিধা আৰু সমস্যা সমাধানৰ উপায়সমূহ লাভ কৰা নাই।</translation> +<translation id="788352880609666695">এই Chromium প্ৰ’ফাইলটোৰ বাবে তলত দিয়া একাউণ্টসমূহ উপলব্ধ</translation> <translation id="7898472181347242998">আপোনাৰ ডিভাইচটো আপ-টু-ডে’ট হৈ আছেনে নাই সেয়া চাবলৈ <ph name="LINK_BEGIN" />Chromium OSৰ ছেটিংসমূহ<ph name="LINK_END" />লৈ যাওক</translation> <translation id="7937630085815544518">আপুনি Chromiumত <ph name="USER_EMAIL_ADDRESS" /> হিচাপে ছাইন ইন হৈ আছিল। আকৌ ছাইন ইন কৰিবলৈ অনুগ্ৰহ কৰি সেই একেটা একাউণ্ট ব্যৱহাৰ কৰক।</translation> <translation id="7975919845073681630">এয়া Chromiumৰ এক গৌণ ইনষ্টলেশ্বন আৰু ইয়াক আপোনাৰ ডিফ’ল্ট ব্ৰাউজাৰ কৰিব নোৱাৰি।</translation> @@ -257,6 +261,7 @@ <translation id="8290862415967981663">এই ফাইলটো ক্ষতিকাৰক হ'ব পাৰে বাবে Chromiumএ ফাইলটো অৱৰোধ কৰিছে।</translation> <translation id="8330519371938183845">Chromiumক আপোনাৰ সকলো ডিভাইচতে ছিংক আৰু ব্যক্তিকৃত কৰিবলৈ ছাইন ইন কৰক</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" />এ আগতে Chromium ব্যৱহাৰ কৰি আছিল</translation> +<translation id="8357820681460164151">আপোনাৰ আটাইবোৰ ডিভাইচত আপোনাৰ Chromium ব্ৰাউজাৰৰ বস্তু এক্সেছ কৰিবলৈ, ছাইন ইন কৰি তাৰ পাছত ছিংক অন কৰক</translation> <translation id="8417404458978023919">{0,plural, =1{এদিনৰ ভিতৰত Chromium পুনৰ লঞ্চ কৰক}one{# দিনৰ ভিতৰত Chromium পুনৰ লঞ্চ কৰক}other{# দিনৰ ভিতৰত Chromium পুনৰ লঞ্চ কৰক}}</translation> <translation id="8453117565092476964">ইনষ্টলাৰ আৰ্কাইভটো ব্যৱহাৰযোগ্য নহয় বা অমান্য। অনুগ্ৰহ কৰি Chromium আকৌ ডাউনল’ড কৰক।</translation> <translation id="8493179195440786826">Chromiumটো অতি পুৰণি</translation>
diff --git a/chrome/app/resources/chromium_strings_bn.xtb b/chrome/app/resources/chromium_strings_bn.xtb index f5bb5f9..52cf7ca 100644 --- a/chrome/app/resources/chromium_strings_bn.xtb +++ b/chrome/app/resources/chromium_strings_bn.xtb
@@ -26,6 +26,7 @@ <translation id="1981611865800294956">&Chromium OS আপডেট করতে আবার লঞ্চ করুন</translation> <translation id="2008474315282236005">এটি এই ডিভাইস থেকে ১টি আইটেম মুছে দেবে। আপনার ডেটা পরে পুনরুদ্ধার করার জন্য, Chromium-এ <ph name="USER_EMAIL" /> হিসেবে সাইন-ইন করুন।</translation> <translation id="2020032459870799438">আপনার অন্যান্য পাসওয়ার্ড ডেটার নিরাপত্তা লঙ্ঘন এবং অন্যান্য নিরাপত্তা সংক্রান্ত সমস্যা থেকে সুরক্ষিত কিনা তা চেক করতে <ph name="BEGIN_LINK" />Chromium-এ সাইন-ইন করুন<ph name="END_LINK" />।</translation> +<translation id="2049376729098081731">Google পরিষেবাতে আরও পছন্দমতো অভিজ্ঞতার জন্য Chromium ইতিহাস অন্তর্ভুক্ত করবেন কিনা তা বেছে নিন</translation> <translation id="2174178932569897599">Chromium কাস্টমাইজ করুন</translation> <translation id="2185166961232948079">Chromium - নেটওয়ার্ক সাইন-ইন - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">যদি আপনি একটি কম্পিউটার শেয়ার করেন, তাহলে বন্ধু ও পরিবারের লোকজন পৃথকভাবে ব্রাউজ করতে পারবেন এবং তাদের ইচ্ছা অনুযায়ী Chromium-এর সেট-আপ করতে পারবেন৷</translation> @@ -37,6 +38,7 @@ <translation id="2401032172288869980">এই সাইটের জন্য Chromium-এর ক্যামেরা ও মাইক্রোফোন অ্যাক্সেসের অনুমতি প্রয়োজন</translation> <translation id="2483889755041906834">Chromium এ</translation> <translation id="2485422356828889247">আনইনস্টল</translation> +<translation id="251127392410688874">Chromium কীভাবে আপনাকে ওপেন ওয়েব সুরক্ষিত করার মাধ্যমে ক্রস-সাইট ট্র্যাক করা থেকে রক্ষা করে তা দেখুন</translation> <translation id="2535480412977113886">আপনার অ্যাকাউন্টের সাইন-ইনের বিবরণটি পুরনো হওয়ায় Chromium OS আপনার ডেটা সিঙ্ক করতে পারেনি৷</translation> <translation id="2560420686485554789">ফাইল ডাউনলোড করতে Chromium-এর জন্য স্টোরেজের অ্যাক্সেস প্রয়োজন</translation> <translation id="2572494885440352020">Chromium সহায়ক</translation> @@ -221,6 +223,7 @@ <translation id="7339898014177206373">নতুন উইন্ডো</translation> <translation id="734373864078049451">আপনার ওয়েব, বুকমার্ক এবং Chromium-এর অন্যান্য জিনিস এখানে রয়েছে৷</translation> <translation id="7349591376906416160"><ph name="TARGET_URL_HOSTNAME" /> অ্যাক্সেস করতে <ph name="ALTERNATIVE_BROWSER_NAME" /> ব্যবহার করার জন্য আপনার সিস্টেম অ্যাডমিনিস্ট্রেটর Chromium কনফিগার করেছে।</translation> +<translation id="7398989605938454041">Chromium প্রোফাইল থেকে আপনার সব Chromium-এ থাকা ডেটা আলাদা করতে পারবেন। এর ফলে সহজেই অফিস এবং বিনোদনের প্রোফাইল আলাদা করা যায়।</translation> <translation id="7448255348454382571">Chromium OS রিস্টার্ট করুন</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> - Chromium Dev</translation> <translation id="7451052299415159299">এই সাইটটির জন্য Chromium কে আপনার ক্যামেরায় অ্যাক্সেস দিতে হবে</translation> @@ -241,6 +244,7 @@ <translation id="7828947555739565424">এই ডিভাইসে এই অ্যাকাউন্টের সাথে Chromium প্রোফাইল আগে থেকেই আছে</translation> <translation id="7857220146454061152">ভবিষ্যতে Chromium আপডেট পেতে হলে, আপনার কম্পিউটারে OS X 10.11 বা এর পরবর্তী যেকোনও ভার্সন থাকতে হবে। এই কম্পিউটারে OS X 10.10 ভার্সন ব্যবহার করা হচ্ছে।</translation> <translation id="7867198900892795913">Chromium লেটেস্ট ভার্সনে আপডেট করা যাচ্ছে না, তাই আপনি নতুন বৈশিষ্ট্য এবং সুরক্ষা সমাধানগুলি পাচ্ছেন না।</translation> +<translation id="788352880609666695">এই Chromium প্রোফাইলের জন্য নিম্নলিখিত অ্যাকাউন্ট উপলভ্য</translation> <translation id="7898472181347242998">আপনার ডিভাইস আপ-টু-ডেট আছে কিনা তা দেখতে <ph name="LINK_BEGIN" />Chromium OS সেটিংস<ph name="LINK_END" /> বিকল্পে যান</translation> <translation id="7937630085815544518">আপনি <ph name="USER_EMAIL_ADDRESS" /> হিসাবে Chromium-এ প্রবেশ করেছেন৷ আবার সাইন-ইন করতে একই অ্যাকাউন্ট ব্যবহার করুন৷</translation> <translation id="7975919845073681630">এটা Chromium এর সেকেন্ডারি ইনস্টলেশন এবং একে আপনার ডিফল্ট ব্রাউজার করা যাবে না।</translation> @@ -253,6 +257,7 @@ <translation id="8290862415967981663">এই ফাইলটি বিপজ্জনক হতে পারে, তাই Chromium এটিকে অবরুদ্ধ করেছে।</translation> <translation id="8330519371938183845">আপনার সব ডিভাইস জুড়ে Chromium সিঙ্ক করতে এবং নিজের মতো সাজিয়ে নিতে সাইন-ইন করুন</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" /> পূর্বে Chromium ব্যবহার করছিলেন</translation> +<translation id="8357820681460164151">সব ডিভাইস জুড়ে Chromium ব্রাউজারে থাকা ডেটা অ্যাক্সেস করতে, প্রথমে সাইন-ইন করে সিঙ্ক চালু করুন</translation> <translation id="8417404458978023919">{0,plural, =1{Chromium এক দিনের মধ্যে আবার লঞ্চ করুন}one{Chromium # দিনের মধ্যে আবার লঞ্চ করুন}other{Chromium # দিনের মধ্যে আবার লঞ্চ করুন}}</translation> <translation id="8453117565092476964">ইনস্টলার আর্কাইভ অবিশুদ্ধ বা ভুল৷ Chromium পুনরায় ডাউনলোড করুন৷</translation> <translation id="8493179195440786826">Chromium পুরানো হয়ে গেছে</translation>
diff --git a/chrome/app/resources/chromium_strings_el.xtb b/chrome/app/resources/chromium_strings_el.xtb index 11a2e54..1e6ae352 100644 --- a/chrome/app/resources/chromium_strings_el.xtb +++ b/chrome/app/resources/chromium_strings_el.xtb
@@ -26,6 +26,7 @@ <translation id="1981611865800294956">Επανεκκίνηση για ενημέρωση του &Chromium OS</translation> <translation id="2008474315282236005">Με αυτήν την ενέργεια θα διαγραφεί 1 στοιχείο από αυτήν τη συσκευή. Για να ανακτήσετε τα δεδομένα σας αργότερα, συνδεθείτε στο Chromium ως <ph name="USER_EMAIL" />.</translation> <translation id="2020032459870799438">Για να ελέγξετε αν οι άλλοι κωδικοί πρόσβασής σας είναι ασφαλείς από παραβιάσεις δεδομένων και άλλα ζητήματα ασφαλείας, <ph name="BEGIN_LINK" />συνδεθείτε στο Chromium<ph name="END_LINK" />.</translation> +<translation id="2049376729098081731">Επιλέξτε αν θέλετε να συμπεριλαμβάνεται το ιστορικό Chromium για πιο εξατομικευμένες εμπειρίες στις υπηρεσίες Google.</translation> <translation id="2174178932569897599">Προσαρμογή του Chromium</translation> <translation id="2185166961232948079">Chromium - Σύνδεση δικτύου - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">Αν χρησιμοποιείτε έναν υπολογιστή από κοινού με άλλα άτομα, οι φίλοι και τα μέλη της οικογένειάς σας μπορούν να περιηγούνται αυτόνομα και να ρυθμίζουν το Chromium ακριβώς όπως θέλουν.</translation> @@ -37,6 +38,7 @@ <translation id="2401032172288869980">Το Chromium χρειάζεται άδεια μικροφώνου και κάμερας για αυτόν τον ιστότοπο.</translation> <translation id="2483889755041906834">Στο Chromium</translation> <translation id="2485422356828889247">Απεγκατάσταση</translation> +<translation id="251127392410688874">Δείτε πώς το Chromium θα σας προστατέψει από την παρακολούθηση μεταξύ ιστοτόπων, διατηρώντας παράλληλα τον ανοικτό ιστό.</translation> <translation id="2535480412977113886">Το Chromium OS δεν μπόρεσε να συγχρονίσει τα δεδομένα σας, επειδή τα στοιχεία σύνδεσης στο λογαριασμό σας δεν είναι ενημερωμένα.</translation> <translation id="2560420686485554789">Το Chromium χρειάζεται πρόσβαση στον αποθηκευτικό χώρο για τη λήψη αρχείων</translation> <translation id="2572494885440352020">Πρόγραμμα βοήθειας Chromium</translation> @@ -223,6 +225,7 @@ <translation id="7339898014177206373">Νέο παράθυρο</translation> <translation id="734373864078049451">Εδώ μπορείτε να βρείτε τις ιστοσελίδες, τους σελιδοδείκτες σας και άλλα δεδομένα του Chromium.</translation> <translation id="7349591376906416160">Ο διαχειριστής συστήματος έχει διαμορφώσει το Chromium ώστε να ανοίγει το <ph name="ALTERNATIVE_BROWSER_NAME" /> για την πρόσβαση σε <ph name="TARGET_URL_HOSTNAME" />.</translation> +<translation id="7398989605938454041">Με τα προφίλ του Chromium μπορείτε να διαχωρίσετε όλο το περιεχόμενό σας στο Chromium. Αυτό σας βοηθά να διαχωρίζετε την εργασία από την ψυχαγωγία.</translation> <translation id="7448255348454382571">Επανεκκίνηση Chromium OS</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> - Chromium Dev</translation> <translation id="7451052299415159299">Το Chromium χρειάζεται άδεια, για να αποκτήσει πρόσβαση στην κάμερα για αυτόν τον ιστότοπο</translation> @@ -243,6 +246,7 @@ <translation id="7828947555739565424">Υπάρχει ήδη σε αυτήν τη συσκευή ένα προφίλ Chromium με αυτόν τον λογαριασμό</translation> <translation id="7857220146454061152">Για τη λήψη των μελλοντικών ενημερώσεων του Chromium, θα χρειαστείτε το OS X 10.11 ή νεότερη έκδοση. Αυτός ο υπολογιστής χρησιμοποιεί το OS X 10.10.</translation> <translation id="7867198900892795913">Δεν ήταν δυνατή η ενημέρωση του Chromium στην τελευταία έκδοση και έτσι δεν θα έχετε πρόσβαση στις νέες λειτουργίες και στις επιδιορθώσεις ασφαλείας.</translation> +<translation id="788352880609666695">Οι παρακάτω λογαριασμοί είναι διαθέσιμοι για αυτό το προφίλ Chromium</translation> <translation id="7898472181347242998">Για να διαπιστώσετε εάν η συσκευή σας είναι ενημερωμένη, μεταβείτε στις <ph name="LINK_BEGIN" />Ρυθμίσεις του Chromium OS<ph name="LINK_END" /></translation> <translation id="7937630085815544518">Συνδεθήκατε στο Chromium ως <ph name="USER_EMAIL_ADDRESS" />. Χρησιμοποιήστε τον ίδιο λογαριασμό για να συνδεθείτε ξανά.</translation> <translation id="7975919845073681630">Αυτή είναι μια δευτερεύουσα εγκατάσταση του Chromium και δεν μπορεί να γίνει το προεπιλεγμένο πρόγραμμα περιήγησης.</translation> @@ -255,6 +259,7 @@ <translation id="8290862415967981663">Αυτό το αρχείο ενδέχεται να είναι επικίνδυνο και έχει αποκλειστεί από το Chromium.</translation> <translation id="8330519371938183845">Συνδεθείτε, για να συγχρονίσετε και να εξατομικεύσετε το Chromium στις συσκευές σας</translation> <translation id="8340674089072921962">Η διεύθυνση <ph name="USER_EMAIL_ADDRESS" /> χρησιμοποιούσε το Chromium στο παρελθόν</translation> +<translation id="8357820681460164151">Για να έχετε πρόσβαση από όλες τις συσκευές σας στο περιεχόμενο που διαθέτετε στο πρόγραμμα περιήγησης Chromium, συνδεθείτε και, στη συνέχεια, ενεργοποιήστε τον συγχρονισμό.</translation> <translation id="8417404458978023919">{0,plural, =1{Επανεκκίνηση του Chromium σε μία ημέρα}other{Επανεκκίνηση του Chromium σε # ημέρες}}</translation> <translation id="8453117565092476964">Το αρχείο του προγράμματος εγκατάστασης είναι κατεστραμμένο ή μη έγκυρο. Κατεβάστε το Chromium ξανά.</translation> <translation id="8493179195440786826">Το Chromium δεν είναι ενημερωμένο</translation>
diff --git a/chrome/app/resources/chromium_strings_eu.xtb b/chrome/app/resources/chromium_strings_eu.xtb index 1933dc63..41073a3 100644 --- a/chrome/app/resources/chromium_strings_eu.xtb +++ b/chrome/app/resources/chromium_strings_eu.xtb
@@ -28,6 +28,7 @@ <translation id="1981611865800294956">Abiaraz ezazu berriro &Chromium OS eguneratzeko</translation> <translation id="2008474315282236005">Gailuko elementu bat ezabatuko da. Geroago datuak eskuratu nahi izanez gero, hasi saioa Chromium-en <ph name="USER_EMAIL" /> gisa.</translation> <translation id="2020032459870799438">Gainerako pasahitzak datuen isilpekotasunaren urratzeen eta beste segurtasun-arazoen aurka babestuta dauden egiaztatzeko, <ph name="BEGIN_LINK" />hasi saioa Chromium-en<ph name="END_LINK" />.</translation> +<translation id="2049376729098081731">Aukeratu ea Chromium-eko historia kontuan hartu nahi duzun ala ez Google-ren zerbitzuak modu pertsonalizatuago batean erabiltzeko</translation> <translation id="2174178932569897599">Pertsonalizatu Chromium</translation> <translation id="2185166961232948079">Chromium - Hasi saioa sarean - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">Ordenagailua partekatzen baduzu, lagunek eta familiako kideek euren kontuak erabilita ibil daitezke Interneten, nahi duten moduan.</translation> @@ -39,6 +40,7 @@ <translation id="2401032172288869980">Chromium-ek kamera eta mikrofonoa atzitzeko baimenak behar ditu webgune honetan</translation> <translation id="2483889755041906834">Chromium-en</translation> <translation id="2485422356828889247">Desinstalatu</translation> +<translation id="251127392410688874">Ikusi zer egin nahi duen Chromium-ek sare irekia mantendu bitartean zu webguneen arteko jarraipenetik babesteko</translation> <translation id="2535480412977113886">Chromium OS sistemak ezin izan ditu zure datuak sinkronizatu kontuan saioa hasteko datuak iraungi egin direlako.</translation> <translation id="2560420686485554789">Chromium-ek fitxategiak deskargatzearren memorian sartzeko baimena behar du</translation> <translation id="2572494885440352020">Chromium laguntzailea</translation> @@ -224,6 +226,7 @@ <translation id="7339898014177206373">Leiho berria</translation> <translation id="734373864078049451">Webguneak, laster-markak eta Chromium-eko beste gauzak hemen daude.</translation> <translation id="7349591376906416160">Sistemaren administratzailearen konfigurazioaren arabera, Chromium-ek <ph name="ALTERNATIVE_BROWSER_NAME" /> arakatzailea ireki behar du <ph name="TARGET_URL_HOSTNAME" /> helbidera joateko.</translation> +<translation id="7398989605938454041">Chromium-eko profilekin, Chromium-en dituzun gauza guztiak bereiz ditzakezu. Hala, errazago edukiko dituzu bananduta gauza pertsonalak eta lanekoak.</translation> <translation id="7448255348454382571">Berrabiarazi Chromium OS</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> - Chromium Dev</translation> <translation id="7451052299415159299">Chromium-ek webgune honen izenean kamera atzitzeko baimena behar du</translation> @@ -244,6 +247,7 @@ <translation id="7828947555739565424">Badago kontu honen Chromium-eko profil bat gailu honetan</translation> <translation id="7857220146454061152">Etorkizunean Chromium-en eguneratzeak eskuratzeko, OS X 10.11 edo bertsio berriago bat beharko duzu. Ordenagailu hau OS X 10.10 erabiltzen ari da.</translation> <translation id="7867198900892795913">Ezin izan da eguneratu Chromium azken bertsiora; beraz, ez dituzu erabilgarri eginbide berriak eta segurtasun-konponketak.</translation> +<translation id="788352880609666695">Kontu hauek erabil daitezke Chromium-eko profil honekin:</translation> <translation id="7898472181347242998">Gailua eguneratuta dagoen ikusteko, joan <ph name="LINK_BEGIN" />Chromium OS sistemaren ezarpenetara<ph name="LINK_END" /></translation> <translation id="7937630085815544518">Chromium-en <ph name="USER_EMAIL_ADDRESS" /> gisa hasi duzu saioa. Saioa berriro hasteko, erabili hasiera batean erabilitako kontu bera.</translation> <translation id="7975919845073681630">Chromium-en bigarren mailako instalazio bat da hau; beraz, ezin duzu ezarri arakatzaile lehenetsi gisa.</translation> @@ -256,6 +260,7 @@ <translation id="8290862415967981663">Baliteke fitxategia arriskutsua izatea; horregatik, blokeatu egin du Chromium-ek.</translation> <translation id="8330519371938183845">Hasi saioa Chromium gailu guztietan sinkronizatu eta pertsonalizatzeko</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" /> Chromium erabiltzen ari da lehendik ere</translation> +<translation id="8357820681460164151">Chromium arakatzaileko gauzak gailu guztietan atzitzeko, hasi saioa eta aktibatu sinkronizazioa</translation> <translation id="8417404458978023919">{0,plural, =1{Berrabiarazi Chromium egun bateko epean}other{Berrabiarazi Chromium # eguneko epean}}</translation> <translation id="8453117565092476964">Instalatzailearen artxiboa hondatuta dago edo baliogabea da. Deskargatu Chromium berriro.</translation> <translation id="8493179195440786826">Chromium zaharkituta dago</translation>
diff --git a/chrome/app/resources/chromium_strings_fa.xtb b/chrome/app/resources/chromium_strings_fa.xtb index 999d5865..793b954 100644 --- a/chrome/app/resources/chromium_strings_fa.xtb +++ b/chrome/app/resources/chromium_strings_fa.xtb
@@ -26,6 +26,7 @@ <translation id="1981611865800294956">راهاندازی مجدد برای بهروزرسانی Chromium OS</translation> <translation id="2008474315282236005">این کار یک مورد را از این دستگاه حذف میکند. برای بازیابی دادههایتان در فرصتی دیگر، با <ph name="USER_EMAIL" /> به سیستم Chromium وارد شوید.</translation> <translation id="2020032459870799438">برای بررسی اینکه از دیگر گذرواژههایتان دربرابر نقض داده یا دیگر مشکلات امنیتی محافظت میشود، <ph name="BEGIN_LINK" />به سیستم Chromium وارد شوید<ph name="END_LINK" />.</translation> +<translation id="2049376729098081731">انتخاب کنید که آیا سابقه Chromium برای تجربههای شخصیشدهتر در سرویسهای Google لحاظ شود یا نه</translation> <translation id="2174178932569897599">سفارشی کردن Chromium</translation> <translation id="2185166961232948079">Chromium - ورود به سیستم شبکه - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">اگر رایانهای را به صورت مشترک استفاده میکنید، دوستان و خانواده میتوانند به صورت جداگانه مرور کنند و Chromium را به صورتی که مایلند تنظیم کنند.</translation> @@ -37,6 +38,7 @@ <translation id="2401032172288869980">Chromium برای این سایت به اجازه دوربین و میکروفون نیاز دارد</translation> <translation id="2483889755041906834">در Chromium</translation> <translation id="2485422356828889247">حذف نصب</translation> +<translation id="251127392410688874">ببینید Chromium چگونه قصد دارد با حفظ وبِ باز، از شما دربرابر ردیابی بینسایتی محافظت کند</translation> <translation id="2535480412977113886">سیستمعامل Chromium قادر به همگامسازی دادههای شما نبود زیرا جزئیات ورود به حساب شما بهروز نیست.</translation> <translation id="2560420686485554789">Chromium برای بارگیری فایلها باید به حافظه دسترسی داشته باشد</translation> <translation id="2572494885440352020">Chromium Helper</translation> @@ -221,6 +223,7 @@ <translation id="7339898014177206373">پنجرهٔ جدید</translation> <translation id="734373864078049451">وب، نشانکها و موارد دیگر Chromium شما در اینجا هستند.</translation> <translation id="7349591376906416160">سرپرست سیستم برای باز شدن <ph name="ALTERNATIVE_BROWSER_NAME" /> جهت دسترسی به <ph name="TARGET_URL_HOSTNAME" />، Chromium را پیکربندی کرده است.</translation> +<translation id="7398989605938454041">با نمایههای Chromium میتوانید همهچیزتان را در Chromium جدا کنید. با این کار، راحتتر میتوان کار و سرگرمی را ازهم جدا کرد.</translation> <translation id="7448255348454382571">بازراهاندازی سیستمعامل Chromium</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> - Chromium Dev</translation> <translation id="7451052299415159299">Chromium برای این سایت به مجوز دسترسی به دوربین نیاز دارد</translation> @@ -241,6 +244,7 @@ <translation id="7828947555739565424">درحالحاضر یک نمایه Chromium با این حساب در این دستگاه وجود دارد</translation> <translation id="7857220146454061152">برای دریافت بهروزرسانیهای آتی Chromium، باید OS X نسخه ۱۰.۱۱ یا بالاتر داشته باشید. این رایانه از OS X نسخه ۱۰.۱۰ استفاده میکند.</translation> <translation id="7867198900892795913">Chromium به جدیدترین نسخه بهروزرسانی نشد، بنابراین قابلیتهای جدید و رفع اشکالهای امنیتی را ندارید.</translation> +<translation id="788352880609666695">حسابهای زیر برای این نمایه Chromium دردسترس هستند</translation> <translation id="7898472181347242998">برای اینکه ببینید دستگاهتان بهروز است یا نه، به <ph name="LINK_BEGIN" />تنظیمات سیستمعامل Chromium<ph name="LINK_END" /> بروید</translation> <translation id="7937630085815544518">شما بعنوان <ph name="USER_EMAIL_ADDRESS" /> وارد سیستم Chromium شدهاید. لطفاً برای ورود به سیستم مجدد از همان حساب استفاده کنید.</translation> <translation id="7975919845073681630">این نصب ثانویه Chromium است و نمیتواند مرورگر پیشفرضتان شود.</translation> @@ -253,6 +257,7 @@ <translation id="8290862415967981663">این فایل ممکن است خطرناک باشد، بنابراین Chromium آن را مسدود کرده است.</translation> <translation id="8330519371938183845">برای همگامسازی و شخصیسازی Chromium در همه دستگاههایتان، به سیستم وارد شوید</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" /> قبلاً از Chromium استفاده میکرد</translation> +<translation id="8357820681460164151">برای دسترسی به چیزهایتان در مرورگر Chromium در همه دستگاههایتان، به سیستم وارد شوید، سپس همگامسازی را روشن کنید</translation> <translation id="8417404458978023919">{0,plural, =1{Chromium را ظرف یک روز راهاندازی مجدد کنید}one{Chromium را ظرف # روز راهاندازی مجدد کنید}other{Chromium را ظرف # روز راهاندازی مجدد کنید}}</translation> <translation id="8453117565092476964">بایگانی نصبکننده خراب یا نامعتبر است. لطفاً Chromium را دوباره را بارگیری کنید.</translation> <translation id="8493179195440786826">نسخه Chromium قدیمی است</translation>
diff --git a/chrome/app/resources/chromium_strings_hr.xtb b/chrome/app/resources/chromium_strings_hr.xtb index 3d84bca1..e2d5d73 100644 --- a/chrome/app/resources/chromium_strings_hr.xtb +++ b/chrome/app/resources/chromium_strings_hr.xtb
@@ -26,6 +26,7 @@ <translation id="1981611865800294956">Ponovo pokrenite da biste ažurirali OS &Chromium</translation> <translation id="2008474315282236005">Time će se izbrisati jedna stavka s uređaja. Da biste kasnije dohvatili svoje podatke, prijavite se na Chromium kao <ph name="USER_EMAIL" />.</translation> <translation id="2020032459870799438">Da biste provjerili jesu li vaše druge zaporke sigurne od povrede podataka i drugih poteškoća sa sigurnošću, <ph name="BEGIN_LINK" />prijavite se na Chromium<ph name="END_LINK" />.</translation> +<translation id="2049376729098081731">Odaberite želite li uključiti povijest na Chromiumu za prilagođenije doživljaje na Googleovim uslugama</translation> <translation id="2174178932569897599">Prilagodi Chromium</translation> <translation id="2185166961232948079">Chromium – Prijava na mrežu – <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">Ako dijelite računalo, prijatelji i članovi obitelji mogu zasebno pregledavati i postaviti Chromium prema svojim željama.</translation> @@ -37,6 +38,7 @@ <translation id="2401032172288869980">Chromium treba dopuštenje za fotoaparat i mikrofon za ovu web-lokaciju</translation> <translation id="2483889755041906834">U Chromiumu</translation> <translation id="2485422356828889247">Deinstaliraj</translation> +<translation id="251127392410688874">Pogledajte kako vas Chromium planira štititi od praćenja na različitim web-lokacijama, a istovremeno očuvati otvorenost weba</translation> <translation id="2535480412977113886">OS Chromium nije mogao sinkronizirati podatke vašeg računa jer su pojedinosti prijave na račun zastarjele.</translation> <translation id="2560420686485554789">Chromium treba pristup pohrani radi preuzimanja datoteka</translation> <translation id="2572494885440352020">Chromium Helper</translation> @@ -223,6 +225,7 @@ <translation id="7339898014177206373">Novi prozor</translation> <translation id="734373864078049451">Ovdje se nalaze vaš web, oznake i ostali sadržaji u Chromiumu.</translation> <translation id="7349591376906416160">Vaš administrator sustava konfigurirao je Chromium da otvara <ph name="ALTERNATIVE_BROWSER_NAME" /> za pristup URL-u <ph name="TARGET_URL_HOSTNAME" />.</translation> +<translation id="7398989605938454041">Pomoću Chromiumovih profila možete razdvojiti sve svoje sadržaje u Chromiumu. To olakšava odvajanje posla i zabave.</translation> <translation id="7448255348454382571">Ponovo pokrenite OS Chromium</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> – Chromium Dev</translation> <translation id="7451052299415159299">Chromium treba dopuštenje za pristup kameri za ovu web-lokaciju</translation> @@ -243,6 +246,7 @@ <translation id="7828947555739565424">Profil u Chromiumu s tim računom već postoji na ovom uređaju</translation> <translation id="7857220146454061152">Da biste primali buduća Chromiumova ažuriranja, trebat će vam OS X 10.11 ili novija verzija. Na ovom se računalu upotrebljava OS X 10.10.</translation> <translation id="7867198900892795913">Chromium se nije mogao ažurirati na najnoviju verziju, tako da nemate nove značajke i sigurnosne popravke.</translation> +<translation id="788352880609666695">Sljedeći računi dostupni su za ovaj Chromium profil</translation> <translation id="7898472181347242998">Ažurnost uređaja možete provjeriti u <ph name="LINK_BEGIN" />postavkama OS-a Chromium<ph name="LINK_END" /></translation> <translation id="7937630085815544518">Bili ste prijavljeni na Chromium kao <ph name="USER_EMAIL_ADDRESS" />. Prijavite se ponovo istim računom.</translation> <translation id="7975919845073681630">Ovo je sekundarna instalacija Chromiuma, pa on ne može biti vaš zadani preglednik.</translation> @@ -255,6 +259,7 @@ <translation id="8290862415967981663">Datoteka je možda opasna i Chromium ju je blokirao.</translation> <translation id="8330519371938183845">Prijavite se da biste sinkronizirali i prilagodili Chromium na svim svojim uređajima</translation> <translation id="8340674089072921962">E-adresa <ph name="USER_EMAIL_ADDRESS" /> prethodno je upotrebljavala Chromium</translation> +<translation id="8357820681460164151">Da biste mogli pristupiti svojim sadržajima u pregledniku Chromium na svim svojim uređajima, prijavite se i zatim uključite sinkronizaciju</translation> <translation id="8417404458978023919">{0,plural, =1{Ponovo pokrenite Chromium u roku od jednog dana}one{Ponovo pokrenite Chromium u roku od # dana}few{Ponovo pokrenite Chromium u roku od # dana}other{Ponovo pokrenite Chromium u roku od # dana}}</translation> <translation id="8453117565092476964">Arhiva programa za instalaciju oštećena je ili nevažeća. Ponovo preuzmite Chromium.</translation> <translation id="8493179195440786826">Chromium je zastario</translation>
diff --git a/chrome/app/resources/chromium_strings_hy.xtb b/chrome/app/resources/chromium_strings_hy.xtb index fd540c311..79165d3b 100644 --- a/chrome/app/resources/chromium_strings_hy.xtb +++ b/chrome/app/resources/chromium_strings_hy.xtb
@@ -28,6 +28,7 @@ <translation id="1981611865800294956">Վերագործարկել՝ &Chromium OS-ը թարմացնելու համար</translation> <translation id="2008474315282236005">1 տարր կջնջվի այս սարքից: Հետագայում ձեր տվյալներն առբերելու համար մուտք գործեք Chromium <ph name="USER_EMAIL" /> հաշվով:</translation> <translation id="2020032459870799438">Որպեսզի պաշտպանեք ձեր մյուս գաղտնաբառերը տվյալների արտահոսքից և խուսափեք անվտանգության հետ կապված այլ խնդիրներից, <ph name="BEGIN_LINK" />մտեք հաշիվ Chromium դիտարկիչում<ph name="END_LINK" />։</translation> +<translation id="2049376729098081731">Ընտրեք, թե արդյոք ներառել Chromium-ի պատմությունը՝ Google-ի ծառայությունների ավելի անհատականացված օգտագործման համար։</translation> <translation id="2174178932569897599">Անհատականացնել Chromium-ը</translation> <translation id="2185166961232948079">Chromium – Ցանցի մուտք – <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">Եթե ձեզնից բացի որևէ այլ մեկն օգտվում է այս համակարգչից, օրինակ ձեր ընկերները կամ հարազատները, ապա նրանք կարող են առանձին աշխատել և կարգավորել Chromium-ն իրենց ուզած ձևով:</translation> @@ -39,6 +40,7 @@ <translation id="2401032172288869980">Այս կայքի համար Chromium-ին անհրաժեշտ է խոսափողն ու տեսախցիկն օգտագործելու թույլտվություն</translation> <translation id="2483889755041906834">Chromium-ի մեջ</translation> <translation id="2485422356828889247">Ապատեղադրել</translation> +<translation id="251127392410688874">Դիտեք, թե ինչպես է Chromium-ը պաշտպանելու ձեզ գործողությունների միջկայքային հետագծման մեխանիզմներից</translation> <translation id="2535480412977113886">Chromium OS-ին չհաջողվեց համաժամացնել ձեր տվյալները, քանի որ ձեր հաշվի տվյալները հնացել են:</translation> <translation id="2560420686485554789">Ֆայլեր ներբեռնելու համար Chromium-ին անհրաժեշտ է պահեստի օգտագործման թույլտվություն</translation> <translation id="2572494885440352020">Chromium օգնական</translation> @@ -224,6 +226,7 @@ <translation id="7339898014177206373">Նոր պատուհան</translation> <translation id="734373864078049451">Բոլոր վեբէջերը, էջանիշները և Chromium-ի այլ տվյալները պահվում են այստեղ:</translation> <translation id="7349591376906416160">Ձեր համակարգի ադմինիստրատորն այնպես է կարգավորել Chromium-ը, որ <ph name="TARGET_URL_HOSTNAME" /> կայքը բացվի <ph name="ALTERNATIVE_BROWSER_NAME" /> դիտարկիչով։</translation> +<translation id="7398989605938454041">Chromium պրոֆիլների միջոցով դուք կարող եք օգտագործել դիտարկիչն առանձին այլ օգտատերերից։Այդպես ավելի հեշտ է տարանջատել գործնական և անձնական նպատակներով օգտագործումը։</translation> <translation id="7448255348454382571">Վերագործարկեք Chromium OS-ը</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> – Chromium Dev</translation> <translation id="7451052299415159299">Chromium-ին այս կայքի համար անհրաժեշտ է ձեր տեսախցիկն օգտագործելու թույլտվություն</translation> @@ -244,6 +247,7 @@ <translation id="7828947555739565424">Այս հաշվի հետ կապված Chromium-ի պրոֆիլ արդեն գոյություն ունի այս սարքում</translation> <translation id="7857220146454061152">Chromium-ի հետագա թարմացումները ստանալու համար ձեզ անհրաժեշտ է OS X 10.11 կամ ավելի նոր տարբերակ։ Այս համակարգիչն օգտագործում է OS X 10.10 տարբերակը։</translation> <translation id="7867198900892795913">Չհաջողվեց տեղադրել Chromium-ի վերջին տարբերակը, որը թարմացվել է նոր գործառույթներով և անվտանգության բարելավումներով:</translation> +<translation id="788352880609666695">Հետևյալ հաշիվները հասանելի են այս Chromium պրոֆիլի համար</translation> <translation id="7898472181347242998">Սարքի ծրագրակազմի տարբերակը տեսնելու համար անցեք <ph name="LINK_BEGIN" />Chromium OS-ի կարգավորումներ<ph name="LINK_END" /></translation> <translation id="7937630085815544518">Դուք մուտք եք գործել Chromium որպես <ph name="USER_EMAIL_ADDRESS" />: Նորից մուտք գործելու համար օգտագործեք նույն հաշիվը:</translation> <translation id="7975919845073681630">Սա Chromium-ի երկրորդային տեղադրումն է: Այն չի կարող դառնալ ձեր կանխադրված դիտարկիչը:</translation> @@ -256,6 +260,7 @@ <translation id="8290862415967981663">Այս ֆայլը կարող է վտանգավոր լինել, և Chromium-ն արգելափակել է այն։</translation> <translation id="8330519371938183845">Մտեք հաշիվ՝ Chromium-ը ձեր բոլոր սարքերում անհատականացնելու համար</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" />-ը նախկինում Chromium է օգտագործել</translation> +<translation id="8357820681460164151">Chromium դիտարկիչի ձեր տվյալները ձեր բոլոր սարքերում օգտագործելու համար մուտք գործեք և միացրեք համաժամացումը</translation> <translation id="8417404458978023919">{0,plural, =1{Վերագործարկեք Chromium-ը մեկ օրվա ընթացքում}one{Վերագործարկեք Chromium-ը # օրվա ընթացքում}other{Վերագործարկեք Chromium-ը # օրվա ընթացքում}}</translation> <translation id="8453117565092476964">Տեղադրիչի արխիվը վնասված է կամ անվավեր: Նորից ներբեռնեք Chromium-ը:</translation> <translation id="8493179195440786826">Chromium-ը հնացած է</translation>
diff --git a/chrome/app/resources/chromium_strings_kk.xtb b/chrome/app/resources/chromium_strings_kk.xtb index 62b62773..fce64e8 100644 --- a/chrome/app/resources/chromium_strings_kk.xtb +++ b/chrome/app/resources/chromium_strings_kk.xtb
@@ -28,6 +28,7 @@ <translation id="1981611865800294956">&Chromium OS жүйесін жаңарту үшін қайта іске қосу</translation> <translation id="2008474315282236005">Құрылғыдан 1 элемент жойылады. Деректерді кейінірек алу үшін Chromium браузеріне <ph name="USER_EMAIL" /> болып кіріңіз.</translation> <translation id="2020032459870799438">Басқа құпия сөздеріңіздің ұрланудан және басқа да қауіпсіздік мәселелерінен қаншалықты қорғалғанын тексеру үшін <ph name="BEGIN_LINK" />Chromium браузеріне кіріңіз<ph name="END_LINK" />.</translation> +<translation id="2049376729098081731">Google қызметтерінде жекелендірілген мүмкіндіктерді пайдалану үшін Chromium тарихын қосу-қоспау нұсқасын таңдаңыз.</translation> <translation id="2174178932569897599">Chromium-ді реттеу</translation> <translation id="2185166961232948079">Chromium – Желіге кіру - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">Компьютерді бөлісетін болсаңыз, достарыңыз интернетке бөлек кіріп, Chromium жүйесін қалауынша орната алады.</translation> @@ -39,6 +40,7 @@ <translation id="2401032172288869980">Chromium бұл сайт үшін камера мен микрофонды пайдалануға рұқсат сұрайды.</translation> <translation id="2483889755041906834">Chromium аясында</translation> <translation id="2485422356828889247">Жою</translation> +<translation id="251127392410688874">Chromium ашық желіні қолдай отырып, сізді сайтаралық бақылаудан қалай қорғайтынын көріңіз.</translation> <translation id="2535480412977113886">Chromium OS деректеріңізді синхрондай алмайды, себебі аккаунтыңызға кіру мәліметтері ескірген.</translation> <translation id="2560420686485554789">Файлдарды жүктеп алу үшін Chromium браузеріне сақтау орнын пайдалану құқығы қажет</translation> <translation id="2572494885440352020">Chromium Helper</translation> @@ -224,6 +226,7 @@ <translation id="7339898014177206373">Жаңа терезе</translation> <translation id="734373864078049451">Мұнда веб-беттер, бетбелгілер және басқа Chromium материалдары тұрады.</translation> <translation id="7349591376906416160">Жүйе әкімшісі Chromium браузерін <ph name="TARGET_URL_HOSTNAME" /> бетіне кіргенде <ph name="ALTERNATIVE_BROWSER_NAME" /> браузері ашылатын етіп конфигурациялады.</translation> +<translation id="7398989605938454041">Chromium профильдері арқылы Chromium-дегі барлық материалыңызды бөле аласыз. Осылайша оларды жұмыс немесе көңіл көтеру топтарына оңай іріктеуге болады.</translation> <translation id="7448255348454382571">Chromium OS жүйесін қайта қосу</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> - Chromium әзірлеуші нұсқасы</translation> <translation id="7451052299415159299">Chromium браузеріне бұл сайтта камераны пайдалану үшін рұқсат керек</translation> @@ -244,6 +247,7 @@ <translation id="7828947555739565424">Осы құрылғыда бұл аккаунтқа Chromium профилі тіркеліп қойған.</translation> <translation id="7857220146454061152">Chromium жаңартылған нұсқасын алу үшін OS X 10.11 не одан кейінгі операциялық жүйе керек. Бұл компьютерде OS X 10.10 нұсқасы орнатылған.</translation> <translation id="7867198900892795913">Chromium браузерінің ең соңғы нұсқасы орнатылмады, сондықтан жаңа мүмкіндіктер мен қауіпсіздікке қатысты түзетілген функцияларды пайдалана алмайсыз.</translation> +<translation id="788352880609666695">Бұл Chromium профилі үшін келесі аккаунттар қолжетімді.</translation> <translation id="7898472181347242998">Құрылғыңызда операциялық жүйенің соңғы нұсқасы бар екенін тексеру үшін <ph name="LINK_BEGIN" />Chromium ОЖ параметрлері<ph name="LINK_END" /> бөлімінен қараңыз.</translation> <translation id="7937630085815544518">Chromium жүйесіне <ph name="USER_EMAIL_ADDRESS" /> ретінде кірдіңіз. Қайта кіру үшін бірдей аккаунтты пайдаланыңыз.</translation> <translation id="7975919845073681630">Бұл – Chromium браузерінің қайта орнатылған нұсқасы және әдепкі браузер бола алмайды.</translation> @@ -256,6 +260,7 @@ <translation id="8290862415967981663">Бұл файл қауіпті болуы мүмкін болғандықтан, Chromium оны бөгеді.</translation> <translation id="8330519371938183845">Chromium браузерін барлық құрылғыларда синхрондап, параметрлерін жекелендіру үшін аккаунтыңызға кіріңіз</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" /> бұрын Chromium браузерін пайдаланған</translation> +<translation id="8357820681460164151">Chromium браузерінің материалдарын барлық құрылғыда пайдалану үшін аккаунтқа кіріп, синхрондау параметрін қосыңыз.</translation> <translation id="8417404458978023919">{0,plural, =1{Chromium браузерін бір күннің ішінде қайта іске қосыңыз}other{Chromium браузерін # күннің ішінде қайта іске қосыңыз}}</translation> <translation id="8453117565092476964">Орнатқыш мұрағаты бүлінген немесе жарамсыз. Chromium қайтадан жүктеңіз.</translation> <translation id="8493179195440786826">Chromium ескірген</translation>
diff --git a/chrome/app/resources/chromium_strings_kn.xtb b/chrome/app/resources/chromium_strings_kn.xtb index ab14650..ba65772 100644 --- a/chrome/app/resources/chromium_strings_kn.xtb +++ b/chrome/app/resources/chromium_strings_kn.xtb
@@ -26,6 +26,7 @@ <translation id="1981611865800294956">&Chromium OS ಅಪ್ಡೇಟ್ ಮಾಡಲು ಮರುಪ್ರಾರಂಭಿಸಿ</translation> <translation id="2008474315282236005">ಈ ಸಾಧನದಿಂದ 1 ಐಟಂ ಅನ್ನು ಇದು ಅಳಿಸುತ್ತದೆ. ನಂತರ ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಮರುಪಡೆಯಲು, <ph name="USER_EMAIL" /> ನಂತೆ Chromium ಗೆ ಸೈನ್ಇನ್ ಮಾಡಿ.</translation> <translation id="2020032459870799438">ನಿಮ್ಮ ಇತರ ಪಾಸ್ವರ್ಡ್ಗಳು ಡೇಟಾ ಉಲ್ಲಂಘನೆ ಮತ್ತು ಇತರ ಭದ್ರತಾ ಸಮಸ್ಯೆಗಳಿಂದ ಸುರಕ್ಷಿತವಾಗಿವೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಲು, <ph name="BEGIN_LINK" />Chromium ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ<ph name="END_LINK" />.</translation> +<translation id="2049376729098081731">Google ಸೇವೆಗಳಲ್ಲಿ ಹೆಚ್ಚು ವೈಯಕ್ತೀಕರಿಸಿದ ಅನುಭವಗಳಿಗಾಗಿ Chromium ಇತಿಹಾಸವನ್ನು ಸೇರಿಸಬೇಕೆ ಬೇಡವೇ ಎಂಬುದನ್ನು ಆಯ್ಕೆಮಾಡಿ</translation> <translation id="2174178932569897599">Chromium ಅನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ</translation> <translation id="2185166961232948079">Chromium - ನೆಟ್ವರ್ಕ್ ಸೈನ್ ಇನ್ - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">ನೀವು ಕಂಪ್ಯೂಟರ್ ಅನ್ನು ಹಂಚಿಕೊಂಡರೆ, ಸ್ನೇಹಿತರು ಮತ್ತು ಕುಟುಂಬದವರು ಪ್ರತ್ಯೇಕವಾಗಿ ಬ್ರೌಸ್ ಮಾಡಬಹುದು ಮತ್ತು Chromium ಅನ್ನು ಅವರಿಗೆ ಬೇಕಾದಂತೆ ಹೊಂದಿಸಿಕೊಳ್ಳಬಹುದು.</translation> @@ -37,6 +38,7 @@ <translation id="2401032172288869980">ಈ ಸೈಟ್ಗೆ ಸಂಬಂಧಿಸಿದಂತೆ Chromium ಗೆ ಕ್ಯಾಮರಾ ಮತ್ತು ಮೈಕ್ರೊಫೋನ್ ಅನುಮತಿಗಳ ಅಗತ್ಯವಿದೆ</translation> <translation id="2483889755041906834">Chromium ನಲ್ಲಿ</translation> <translation id="2485422356828889247">ಅನ್ಇನ್ಸ್ಟಾಲ್</translation> +<translation id="251127392410688874">ತೆರೆದ ವೆಬ್ ಅನ್ನು ಕಾಪಾಡುವಾಗ ಕ್ರಾಸ್-ಸೈಟ್ ಟ್ರ್ಯಾಕಿಂಗ್ನಿಂದ ನಿಮ್ಮನ್ನು ಹೇಗೆ ರಕ್ಷಿಸಲು Chromium ಪ್ಲಾನ್ ಮಾಡುತ್ತದೆ ಎಂಬುದನ್ನು ನೋಡಿ</translation> <translation id="2535480412977113886">ನಿಮ್ಮ ಖಾತೆಯ ಸೈನ್ ಇನ್ ವಿವರಗಳು ತೀರಾ ಹಳೆಯದಾಗಿರುವ ಕಾರಣ ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಸಿಂಕ್ ಮಾಡಲು Chromium OS ಗೆ ಸಾಧ್ಯವಾಗಲಿಲ್ಲ.</translation> <translation id="2560420686485554789">ಫೈಲ್ಗಳನ್ನು ಡೌನ್ಲೋಡ್ ಮಾಡಲು Chromium ಗೆ ಸಂಗ್ರಹಣೆಯನ್ನು ಪ್ರವೇಶಿಸುವ ಅಗತ್ಯವಿದೆ</translation> <translation id="2572494885440352020">Chromium ಸಹಾಯಕ</translation> @@ -216,6 +218,7 @@ <translation id="7339898014177206373">ಹೊಸ ವಿಂಡೊ</translation> <translation id="734373864078049451">ನಿಮ್ಮ ವೆಬ್, ಬುಕ್ಮಾರ್ಕ್ಗಳು ಮತ್ತು ಇತರ Chromium ಸಂಗತಿಗಳು ಇಲ್ಲಿ ಲೈವ್ ಆಗುತ್ತವೆ.</translation> <translation id="7349591376906416160"><ph name="TARGET_URL_HOSTNAME" /> ಗೆ ಪ್ರವೇಶ ಪಡೆಯುವುದಕ್ಕಾಗಿ <ph name="ALTERNATIVE_BROWSER_NAME" /> ಅನ್ನು ತೆರೆಯಲು, ನಿಮ್ಮ ಸಿಸ್ಟಂ ನಿರ್ವಾಹಕರು Chromium ಅನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿದ್ದಾರೆ.</translation> +<translation id="7398989605938454041">Chromium ಪ್ರೊಫೈಲ್ಗಳನ್ನು ಬಳಸಿಕೊಂಡು Chromium ಗೆ ಸಂಬಂಧಿಸಿದ ನಿಮ್ಮ ಎಲ್ಲಾ ಸಂಗತಿಗಳನ್ನು ನೀವು ಪ್ರತ್ಯೇಕವಾಗಿಸಬಹುದು. ಇದು ಕೆಲಸ ಮತ್ತು ಮೋಜಿನ ನಡುವೆ ವಿಭಜನೆಯನ್ನು ಸುಲಭಗೊಳಿಸುತ್ತದೆ.</translation> <translation id="7448255348454382571">Chromium OS ಮರುಪ್ರಾರಂಭಿಸಿ</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> - Chromium Dev</translation> <translation id="7451052299415159299">ಈ ಸೈಟ್ಗಾಗಿ ನಿಮ್ಮ ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಲು Chromium ಗೆ ಅನುಮತಿಯ ಅಗತ್ಯವಿದೆ</translation> @@ -235,6 +238,7 @@ <translation id="7828947555739565424">ಈ ಸಾಧನದಲ್ಲಿ ಈ ಖಾತೆಯೊಂದಿಗಿನ Chromium ಪ್ರೊಫೈಲ್ ಈಗಾಗಲೇ ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ</translation> <translation id="7857220146454061152">ಭವಿಷ್ಯದ Chromium ಅಪ್ಡೇಟ್ಗಳನ್ನು ಪಡೆಯಲು, ನಿಮಗೆ OS X 10.11 ಅಥವಾ ಅದರ ನಂತರದ ಆವೃತ್ತಿಗಳ ಅಗತ್ಯವಿದೆ. ಈ ಕಂಪ್ಯೂಟರ್ OS X 10.10 ಅನ್ನು ಬಳಸುತ್ತಿದೆ.</translation> <translation id="7867198900892795913">Chromium ಗೆ ಇತ್ತೀಚಿನ ಆವೃತ್ತಿಗೆ ಅಪ್ಡೇಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ, ಈ ಮೂಲಕ ನೀವು ಹೊಸ ವೈಶಿಷ್ಟ್ಯಗಳು ಮತ್ತು ಭದ್ರತೆ ಸರಿಪಡಿಸುವಿಕೆಗಳನ್ನು ಕಳೆದುಕೊಳ್ಳುತ್ತಿರಬಹುದು.</translation> +<translation id="788352880609666695">ಈ Chromium ಪ್ರೊಫೈಲ್ಗಾಗಿ ಈ ಕೆಳಗಿನ ಖಾತೆಗಳು ಲಭ್ಯವಿದೆ</translation> <translation id="7898472181347242998">ನಿಮ್ಮ ಸಾಧನ ಅಪ್ ಟು ಡೇಟ್ ಆಗಿದೆಯೇ ಎಂಬುದನ್ನು ನೋಡಲು, <ph name="LINK_BEGIN" />Chromium OS ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ<ph name="LINK_END" /> ಹೋಗಿ</translation> <translation id="7937630085815544518"><ph name="USER_EMAIL_ADDRESS" /> ನಂತೆ Chromium ಅನ್ನು ನೀವು ಸೈನ್ ಇನ್ ಮಾಡಿರುವಿರಿ. ದಯವಿಟ್ಟು ಮತ್ತೆ ಸೈನ್ ಇನ್ ಮಾಡಲು ಅದೇ ಖಾತೆಯನ್ನು ಬಳಸಿ.</translation> <translation id="7975919845073681630">ಇದು Chromium ನ ದ್ವಿತೀಯ ಸ್ಥಾಪನೆಯಾಗಿದೆ ಮತ್ತು ಅದನ್ನು ನಿಮ್ಮ ಡಿಫಾಲ್ಟ್ ಬ್ರೌಸರ್ ಆಗಿ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</translation> @@ -247,6 +251,7 @@ <translation id="8290862415967981663">ಈ ಫೈಲ್ ಅಪಾಯಕಾರಿಯಾಗಿರಬಹುದು, ಹೀಗಾಗಿ Chromium ಇದನ್ನು ನಿರ್ಬಂಧಿಸಿದೆ.</translation> <translation id="8330519371938183845">ನಿಮ್ಮ ಸಾಧನಗಳಲ್ಲಿ Chromium ಅನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಮತ್ತು ವೈಯಕ್ತೀಕರಿಸಲು ಸೈನ್ ಇನ್ ಮಾಡಿ</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" /> ಅವರು ಮೊದಲಿನಿಂದಲೆ Chromium ಬಳಸುತ್ತಿದ್ದರು</translation> +<translation id="8357820681460164151">ನಿಮ್ಮ Chromium ಬ್ರೌಸರ್ನ ವಿಷಯಗಳನ್ನು ಎಲ್ಲಾ ಸಾಧನಗಳಾದ್ಯಂತ ಪ್ರವೇಶಿಸಲು, ಸೈನ್ ಇನ್ ಮಾಡಿ, ನಂತರ ಸಿಂಕ್ ಅನ್ನು ಆನ್ ಮಾಡಿ</translation> <translation id="8417404458978023919">{0,plural, =1{ಒಂದು ದಿನದ ಒಳಗೆ Chromium ಮರುಪ್ರಾರಂಭಿಸಿ}one{# ದಿನಗಳ ಒಳಗೆ Chromium ಮರುಪ್ರಾರಂಭಿಸಿ}other{# ದಿನಗಳ ಒಳಗೆ Chromium ಮರುಪ್ರಾರಂಭಿಸಿ}}</translation> <translation id="8453117565092476964">ಸ್ಥಾಪಕ ಆರ್ಕೈವ್ ದೋಷಪೂರಿತವಾಗಿದೆ ಅಥವಾ ಅಮಾನ್ಯವಾಗಿದೆ. ದಯವಿಟ್ಟು Chromium ಅನ್ನು ಪುನಃ ಡೌನ್ಲೋಡ್ ಮಾಡಿ.</translation> <translation id="8493179195440786826">Chromium ನ ಅವಧಿ ಮುಗಿದಿದೆ</translation>
diff --git a/chrome/app/resources/chromium_strings_nl.xtb b/chrome/app/resources/chromium_strings_nl.xtb index 66c6432..07b62eed 100644 --- a/chrome/app/resources/chromium_strings_nl.xtb +++ b/chrome/app/resources/chromium_strings_nl.xtb
@@ -28,6 +28,7 @@ <translation id="1981611865800294956">Opnieuw opstarten om &Chromium OS te updaten</translation> <translation id="2008474315282236005">Hiermee wordt 1 item verwijderd van dit apparaat. Als je je gegevens later wilt terughalen, log je in bij Chromium als <ph name="USER_EMAIL" />.</translation> <translation id="2020032459870799438">Als je wilt checken of je andere wachtwoorden zijn beveiligd tegen gegevenslekken en andere beveiligingsproblemen, <ph name="BEGIN_LINK" />log je in bij Chromium<ph name="END_LINK" />.</translation> +<translation id="2049376729098081731">Kies of je de Chromium-geschiedenis wilt opnemen voor meer gepersonaliseerde functies in Google-services</translation> <translation id="2174178932569897599">Chromium aanpassen</translation> <translation id="2185166961232948079">Chromium - Inloggen bij netwerk - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">Als je een computer deelt, kunnen vrienden en familie afzonderlijk surfen en Chromium configureren zoals zij dat willen.</translation> @@ -39,6 +40,7 @@ <translation id="2401032172288869980">Chromium heeft camera- en microfoonrechten nodig voor deze site</translation> <translation id="2483889755041906834">In Chromium</translation> <translation id="2485422356828889247">Installatie ongedaan maken</translation> +<translation id="251127392410688874">Bekijk hoe Chromium je wil beschermen tegen tracking op verschillende sites terwijl het open web behouden blijft</translation> <translation id="2535480412977113886">Chromium OS kan je gegevens niet synchroniseren omdat de inloggegevens voor je account zijn verouderd.</translation> <translation id="2560420686485554789">Chromium heeft toegang tot de opslag nodig om bestanden te downloaden</translation> <translation id="2572494885440352020">Chromium Helper</translation> @@ -224,6 +226,7 @@ <translation id="7339898014177206373">Nieuw venster</translation> <translation id="734373864078049451">Hier vind je internet, bookmarks en andere Chromium-instellingen.</translation> <translation id="7349591376906416160">Je systeembeheerder heeft Chromium geconfigureerd om <ph name="ALTERNATIVE_BROWSER_NAME" /> te openen voor toegang tot <ph name="TARGET_URL_HOSTNAME" />.</translation> +<translation id="7398989605938454041">Met Chromium-profielen kun je alle Chromium-gegevens gescheiden houden. Zo kun je makkelijker onderscheid maken tussen werk en privé.</translation> <translation id="7448255348454382571">Chromium OS opnieuw opstarten</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> - Chromium voor ontwikkelaars</translation> <translation id="7451052299415159299">Chromium heeft toegangsrechten voor je camera nodig voor deze site</translation> @@ -243,6 +246,7 @@ <translation id="7828947555739565424">Er bestaat op dit apparaat al een Chromium-profiel met dit account</translation> <translation id="7857220146454061152">Als je toekomstige Chromium-updates wilt ontvangen, heb je OS X 10.11 of hoger nodig. Deze computer gebruikt OS X 10.10.</translation> <translation id="7867198900892795913">Chromium kan niet worden geüpdatet naar de nieuwste versie, dus je loopt nieuwe functies en beveiligingsoplossingen mis.</translation> +<translation id="788352880609666695">De volgende accounts zijn beschikbaar voor dit Chromium-profiel</translation> <translation id="7898472181347242998">Ga naar de <ph name="LINK_BEGIN" />instellingen van Chromium OS<ph name="LINK_END" /> om te kijken of je apparaat up-to-date is</translation> <translation id="7937630085815544518">Je bent ingelogd bij Chromium als <ph name="USER_EMAIL_ADDRESS" />. Gebruik hetzelfde account om opnieuw in te loggen.</translation> <translation id="7975919845073681630">Dit is een tweede installatie van Chromium en kan niet als standaardbrowser worden ingesteld.</translation> @@ -255,6 +259,7 @@ <translation id="8290862415967981663">Dit bestand kan gevaarlijk zijn en is daarom door Chromium geblokkeerd.</translation> <translation id="8330519371938183845">Log in om Chromium op al je apparaten te synchroniseren en te personaliseren</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" /> maakte eerder gebruik van Chromium</translation> +<translation id="8357820681460164151">Log in en zet synchronisatie aan voor toegang tot je Chromium-browsergegevens op al je apparaten</translation> <translation id="8417404458978023919">{0,plural, =1{Start Chromium binnen een dag opnieuw}other{Start Chromium binnen # dagen opnieuw}}</translation> <translation id="8453117565092476964">Het archief van het installatieprogramma is beschadigd of ongeldig. Download Chromium opnieuw.</translation> <translation id="8493179195440786826">Chromium is verouderd</translation>
diff --git a/chrome/app/resources/chromium_strings_pt-BR.xtb b/chrome/app/resources/chromium_strings_pt-BR.xtb index 9bb1fae..a736dca 100644 --- a/chrome/app/resources/chromium_strings_pt-BR.xtb +++ b/chrome/app/resources/chromium_strings_pt-BR.xtb
@@ -26,6 +26,7 @@ <translation id="1981611865800294956">Reinicializar para atualizar o &Chromium OS</translation> <translation id="2008474315282236005">Essa ação excluirá 1 item deste dispositivo. Para recuperar seus dados mais tarde, faça login no Chromium como <ph name="USER_EMAIL" />.</translation> <translation id="2020032459870799438">Para verificar se suas outras senhas estão protegidas contra violações de dados e outros problemas de segurança, <ph name="BEGIN_LINK" />faça login no Chromium<ph name="END_LINK" />.</translation> +<translation id="2049376729098081731">Escolha se você quer incluir o histórico do Chromium para ter experiências mais personalizadas nos Serviços do Google</translation> <translation id="2174178932569897599">Personalizar o Chromium</translation> <translation id="2185166961232948079">Chromium - Login na rede - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">Se você usa um computador compartilhado, seus amigos e familiares podem navegar separadamente e configurar o Chromium da maneira que desejarem.</translation> @@ -37,6 +38,7 @@ <translation id="2401032172288869980">O Chromium precisa da permissão de acesso ao microfone e à câmera para este site</translation> <translation id="2483889755041906834">No Chromium</translation> <translation id="2485422356828889247">Desinstalar</translation> +<translation id="251127392410688874">Veja como o Chromium pretende proteger você contra mecanismos de rastreamento entre sites ao mesmo tempo em que preserva uma Internet livre</translation> <translation id="2535480412977113886">O Chromium OS não pôde sincronizar seus dados porque os detalhes de login da sua conta estão desatualizados.</translation> <translation id="2560420686485554789">O Chromium precisa de acesso de armazenamento para fazer o download de arquivos</translation> <translation id="2572494885440352020">Assistente do Chromium</translation> @@ -217,6 +219,7 @@ <translation id="7339898014177206373">Nova janela</translation> <translation id="734373864078049451">Sua Web, seus favoritos e demais conteúdo do Chromium estão aqui.</translation> <translation id="7349591376906416160">O administrador do seu sistema configurou o Chromium para abrir o <ph name="ALTERNATIVE_BROWSER_NAME" /> ao acessar <ph name="TARGET_URL_HOSTNAME" />.</translation> +<translation id="7398989605938454041">Você pode usar os perfis do Chromium para separar todos os seus dados nele. Assim, fica mais fácil dividir suas atividades entre trabalho e diversão.</translation> <translation id="7448255348454382571">Reiniciar o Chromium OS</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" />: Chromium Dev</translation> <translation id="7451052299415159299">O Chromium precisa de permissão para este site acessar sua câmera</translation> @@ -236,6 +239,7 @@ <translation id="7828947555739565424">Este dispositivo já tem um perfil do Chromium com essa conta</translation> <translation id="7857220146454061152">Para receber as futuras atualizações do Chromium, você precisará do OS X 10.11 ou versão mais recente. Este computador está usando o OS X 10.10.</translation> <translation id="7867198900892795913">Não foi possível atualizar o Chromium para a versão mais recente. Com isso, você está perdendo novos recursos e correções de segurança.</translation> +<translation id="788352880609666695">As seguintes contas estão disponíveis neste perfil do Chromium</translation> <translation id="7898472181347242998">Para verificar se o dispositivo está atualizado, acesse as <ph name="LINK_BEGIN" />Configurações do Chromium OS<ph name="LINK_END" /></translation> <translation id="7937630085815544518">Você estava conectado ao Chromium como <ph name="USER_EMAIL_ADDRESS" />. Use a mesma conta para fazer login novamente.</translation> <translation id="7975919845073681630">Como esta é uma instalação secundária do Chromium, ele não pode se tornar seu navegador padrão.</translation> @@ -248,6 +252,7 @@ <translation id="8290862415967981663">Esse arquivo pode ser perigoso, por isso ele foi bloqueado pelo Chromium.</translation> <translation id="8330519371938183845">Faça login para sincronizar e personalizar o Chromium em todos os seus dispositivos</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" /> estava usando o Chromium anteriormente</translation> +<translation id="8357820681460164151">Para ter acesso aos recursos do navegador Chromium em todos os seus dispositivos, faça login e ative a sincronização</translation> <translation id="8417404458978023919">{0,plural, =1{Reiniciar o Chromium em 1 dia}one{Reiniciar o Chromium em # dia}other{Reiniciar o Chromium em # dias}}</translation> <translation id="8453117565092476964">O arquivo de instalação está corrompido ou não é válido. Faça o download do Chromium novamente.</translation> <translation id="8493179195440786826">O Chromium está desatualizado</translation>
diff --git a/chrome/app/resources/chromium_strings_pt-PT.xtb b/chrome/app/resources/chromium_strings_pt-PT.xtb index 6a116eec..52faa6f4 100644 --- a/chrome/app/resources/chromium_strings_pt-PT.xtb +++ b/chrome/app/resources/chromium_strings_pt-PT.xtb
@@ -26,6 +26,7 @@ <translation id="1981611865800294956">Reiniciar para atualizar o &Chromium OS</translation> <translation id="2008474315282236005">Esta ação elimina 1 item deste dispositivo. Para recuperar os dados mais tarde, inicie sessão no Chromium como <ph name="USER_EMAIL" />.</translation> <translation id="2020032459870799438">Para verificar se as suas outras palavras-passe estão protegidas contra violação de dados e outros problemas de segurança, <ph name="BEGIN_LINK" />inicie sessão no Chromium<ph name="END_LINK" />.</translation> +<translation id="2049376729098081731">Escolha se pretende incluir o histórico do Chromium para obter mais experiências personalizadas nos serviços Google</translation> <translation id="2174178932569897599">Personalizar o Chromium</translation> <translation id="2185166961232948079">Chromium – Início de sessão na rede – <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">Se partilhar um computador, os amigos e os familiares podem navegar separadamente e configurar o Chromium da forma que quiserem.</translation> @@ -37,6 +38,7 @@ <translation id="2401032172288869980">O Chromium necessita de autorizações da câmara e do microfone para este site</translation> <translation id="2483889755041906834">No Chromium</translation> <translation id="2485422356828889247">Desinstalar</translation> +<translation id="251127392410688874">Veja como o Chromium planeia proteger o utilizador contra a monitorização entre sites, ao mesmo tempo que preserva a Web aberta</translation> <translation id="2535480412977113886">O SO Chromium não conseguiu sincronizar os dados porque os detalhes de início de sessão da sua conta estão desatualizados.</translation> <translation id="2560420686485554789">O Chromium necessita de acesso ao armazenamento para transferir ficheiros.</translation> <translation id="2572494885440352020">Ajuda do Chromium</translation> @@ -223,6 +225,7 @@ <translation id="7339898014177206373">Nova janela</translation> <translation id="734373864078049451">A sua Web, os seus marcadores e os seus outros itens do Chromium estão aqui.</translation> <translation id="7349591376906416160">O administrador do sistema configurou o Chromium para abrir o <ph name="ALTERNATIVE_BROWSER_NAME" /> e aceder a <ph name="TARGET_URL_HOSTNAME" />.</translation> +<translation id="7398989605938454041">Com os perfis do Chromium, pode separar todos os seus itens do Chromium. Desta forma, é mais fácil alternar entre o trabalho e o lazer.</translation> <translation id="7448255348454382571">Reiniciar o Chromium OS</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> – Chromium Dev</translation> <translation id="7451052299415159299">O Chromium necessita de autorização de acesso à câmara para este site.</translation> @@ -243,6 +246,7 @@ <translation id="7828947555739565424">Já existe um perfil do Chromium com esta conta neste dispositivo.</translation> <translation id="7857220146454061152">Para obter atualizações futuras do Chromium, precisa do OS X 10.11 ou posterior. Este computador está a utilizar o OS X 10.10.</translation> <translation id="7867198900892795913">Não foi possível atualizar o Chromium para a versão mais recente, pelo que não está a beneficiar das novas funcionalidades e correções de segurança.</translation> +<translation id="788352880609666695">As seguintes contas estão disponíveis para este perfil do Chromium</translation> <translation id="7898472181347242998">Para ver se o seu dispositivo está atualizado, aceda às <ph name="LINK_BEGIN" />Definições do Chromium OS<ph name="LINK_END" />.</translation> <translation id="7937630085815544518">Iniciou sessão no Chromium com a conta <ph name="USER_EMAIL_ADDRESS" />. Utilize a mesma conta para iniciar sessão novamente.</translation> <translation id="7975919845073681630">Esta é uma instalação secundária do Chromium, pelo que não pode tornar-se o navegador predefinido.</translation> @@ -255,6 +259,7 @@ <translation id="8290862415967981663">Este ficheiro pode ser perigoso. Como tal, o Chromium bloqueou-o.</translation> <translation id="8330519371938183845">Inicie sessão para sincronizar e personalizar o Chromium em todos os dispositivos.</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" /> estava a utilizar o Chromium</translation> +<translation id="8357820681460164151">Para aceder aos seus itens do navegador Chromium em todos os seus dispositivos, inicie sessão e, em seguida, ative a sincronização.</translation> <translation id="8417404458978023919">{0,plural, =1{Reinicie o Chromium dentro de um dia}one{Reinicie o Chromium dentro de # dia(s)}other{Reinicie o Chromium dentro de # dias}}</translation> <translation id="8453117565092476964">O arquivo do programa de instalação está corrompido ou não é válido. Descarregue novamente o Chromium.</translation> <translation id="8493179195440786826">O Chromium Está Desatualizado</translation>
diff --git a/chrome/app/resources/chromium_strings_tr.xtb b/chrome/app/resources/chromium_strings_tr.xtb index 150dfd31..5b9f618 100644 --- a/chrome/app/resources/chromium_strings_tr.xtb +++ b/chrome/app/resources/chromium_strings_tr.xtb
@@ -26,6 +26,7 @@ <translation id="1981611865800294956">&Chromium OS'i güncellemek için yeniden başlat</translation> <translation id="2008474315282236005">Bu işlem 1 öğeyi bu cihazdan silecektir. Verilerinizi daha sonra geri almak için Chromium'da <ph name="USER_EMAIL" /> hesabıyla oturum açın.</translation> <translation id="2020032459870799438">Öteki şifrelerinizin veri ihlali ve diğer güvenlik sorunlarına karşı güvende olup olmadığını kontrol etmek için <ph name="BEGIN_LINK" />Chromium'da oturum açın<ph name="END_LINK" />.</translation> +<translation id="2049376729098081731">Google hizmetlerinde daha fazla kişiselleştirilmiş deneyimden faydalanmak için Chromium geçmişinin eklenip eklenmeyeceğini seçin</translation> <translation id="2174178932569897599">Chromium'u özelleştir</translation> <translation id="2185166961232948079">Chromium - Ağda Oturum Açın - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">Bir bilgisayarı paylaşıyorsanız arkadaşlarınız ve aileniz ayrı olarak göz atabilir ve Chromium'u tam olarak istedikleri şekilde ayarlayabilir.</translation> @@ -37,6 +38,7 @@ <translation id="2401032172288869980">Bu site için Chromium'un kamera ve mikrofon izinlerine ihtiyacı var</translation> <translation id="2483889755041906834">Chromium'da</translation> <translation id="2485422356828889247">Kaldır</translation> +<translation id="251127392410688874">Chromium'un açık web'i korurken sizi siteler arası izlemeden nasıl koruduğunu öğrenin</translation> <translation id="2535480412977113886">Hesap oturum açma ayrıntılarınız güncel olmadığından Chromium OS, verilerinizi senkronize edemedi.</translation> <translation id="2560420686485554789">Dosya indirmek için Chromium'un depolama alanına erişmesi gerekiyor</translation> <translation id="2572494885440352020">Chromium Yardımcısı</translation> @@ -220,6 +222,7 @@ <translation id="7339898014177206373">Yeni pencere</translation> <translation id="734373864078049451">Web, yer işaretleri ve diğer Chromium bilgileriniz burada bulunur.</translation> <translation id="7349591376906416160">Sistem yöneticiniz Chromium'u <ph name="TARGET_URL_HOSTNAME" /> adresine erişmek için <ph name="ALTERNATIVE_BROWSER_NAME" /> tarayıcısını açacak şekilde yapılandırmış.</translation> +<translation id="7398989605938454041">Chromium profilleri ile tüm Chromium öğelerinizi ayırabilirsiniz. Bu özellik, iş ile eğlenceyi daha kolay ayırmayı sağlar.</translation> <translation id="7448255348454382571">Chromium OS'i yeniden başlatın</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> - Chromium Dev</translation> <translation id="7451052299415159299">Chromium'un bu sitede kameranıza erişmesi için izin gerekiyor</translation> @@ -240,6 +243,7 @@ <translation id="7828947555739565424">Cihazda bu hesaba sahip bir Chromium profili zaten var</translation> <translation id="7857220146454061152">Gelecekteki Chromium güncellemelerini almak için OS X 10.11 veya sonraki bir sürümün yüklü olması gerekir. Bu bilgisayar OS X 10.10 kullanıyor.</translation> <translation id="7867198900892795913">Chromium en son sürüme güncellenemediği için yeni özellikler ve güvenlik düzeltmeleri cihazınızda bulunmuyor.</translation> +<translation id="788352880609666695">Bu Chromium profili için aşağıdaki hesaplar kullanılabilir</translation> <translation id="7898472181347242998">Cihazınızın güncel olup olmadığını görmek için <ph name="LINK_BEGIN" />Chromium OS Ayarları<ph name="LINK_END" />'na gidin</translation> <translation id="7937630085815544518">Chromium'da <ph name="USER_EMAIL_ADDRESS" /> olarak oturum açtınız. Tekrar oturum açmak için lütfen aynı hesabı kullanın.</translation> <translation id="7975919845073681630">Bu, Chromium'un ikincil bir yüklemesidir ve varsayılan tarayıcınız yapılamaz.</translation> @@ -252,6 +256,7 @@ <translation id="8290862415967981663">Bu dosya tehlikeli olabileceği için Chromium tarafından engellendi.</translation> <translation id="8330519371938183845">Chromium'u cihazlarınız arasında senkronize etmek ve kişiselleştirmek için oturum açın</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" /> önceden Chromium kullanıyordu</translation> +<translation id="8357820681460164151">Chromium öğelerinize tüm cihazlarınızda erişmek için oturum açın ve senkronizasyonu etkinleştirin</translation> <translation id="8417404458978023919">{0,plural, =1{Chromium'u bir gün içinde yeniden başlatın}other{Chromium'u # gün içinde yeniden başlatın}}</translation> <translation id="8453117565092476964">Yükleyici arşivi bozuk veya geçersiz. Lütfen Chromium'u yeniden indirin.</translation> <translation id="8493179195440786826">Chromium Sürümü Eski</translation>
diff --git a/chrome/app/resources/chromium_strings_zu.xtb b/chrome/app/resources/chromium_strings_zu.xtb index 517e428..929af88 100644 --- a/chrome/app/resources/chromium_strings_zu.xtb +++ b/chrome/app/resources/chromium_strings_zu.xtb
@@ -28,6 +28,7 @@ <translation id="1981611865800294956">Qalisa kabusha ukuze ubuyekeze i-&Chromium OS</translation> <translation id="2008474315282236005">Lokhu kuzosusa into engu-1 kusuka kule divayisi. Ukuze usebenzise futhi idatha yakho ngokuhamba kwesikhathi, ngena ngemvume ku-Chromium njengo-<ph name="USER_EMAIL" />.</translation> <translation id="2020032459870799438">Ukuze uhlole uma ngabe amanye amaphasiwedi akho aphephile yini kusukela ekuphulweni kwedatha nezinye izinkinga zokuvikela, <ph name="BEGIN_LINK" />ngena ngemvume ku-Chromium<ph name="END_LINK" />.</translation> +<translation id="2049376729098081731">Khetha ukuthi ufake phakathi umlando we-Chromium ukuze uthole umuzwa womuntu siqu kumasevisi e-Google</translation> <translation id="2174178932569897599">Yenza i-Chromium ngokwezifiso</translation> <translation id="2185166961232948079">I-Chromium - Inethiwekhi Yokungena ngemvume - <ph name="PAGE_TITLE" /></translation> <translation id="2241627712206172106">Uma wabelana ngekhompyutha, abangani nomndeni bangadlulisa amehlo ngokuhlukile baphinde basethe i-Chrome ngendlela abafuna ngayo nje.</translation> @@ -39,6 +40,7 @@ <translation id="2401032172288869980">I-Chromium idinga izimvume zekhamera nemakrofoni kule sayithi</translation> <translation id="2483889755041906834">Ku-Chromium</translation> <translation id="2485422356828889247">Khipha</translation> +<translation id="251127392410688874">Bona ukuthi i-Chromium ihlela kanjani ukukuvikela ekulandeleleni amasayithi amaningi ngenkathi ilondoloza iwebhu evuliwe</translation> <translation id="2535480412977113886">I-Chromium OS ayikwazanga ukuvumelanisa idatha yakho ngoba imininingwane yokungena ngemvume kwi-akhawunti yakho iphelelwe isikhathi.</translation> <translation id="2560420686485554789">I-Chromium idinga ukufinyelela kusitoreji ukuze ilande amafayela</translation> <translation id="2572494885440352020">Isisizi se-Chromium</translation> @@ -225,6 +227,7 @@ <translation id="7339898014177206373">Iwindi elisha</translation> <translation id="734373864078049451">Iwebhu yakho, amabhukhimakhi, nezinye izinto ze-Chromium zihlala lapha.</translation> <translation id="7349591376906416160">Umlawuli wakho wesistimu ulungiselele i-Chromium ukuthi ivule i-<ph name="ALTERNATIVE_BROWSER_NAME" /> ukuze ifinyelele ku-<ph name="TARGET_URL_HOSTNAME" />.</translation> +<translation id="7398989605938454041">Ngamaphrofayela we-Chromium ungahlukanisa zonke izinto zakho ze-Chromium. Lokhu kwenza kube lula ukuhlukanisa phakathi komsebenzi nokuzijabulisa.</translation> <translation id="7448255348454382571">Qalisa kabusha i-Chromium OS</translation> <translation id="7449453770951226939"><ph name="PAGE_TITLE" /> - Chromium Dev</translation> <translation id="7451052299415159299">I-Chromium idinga imvume yakho ukuze ifinyelele kukhamera yakho yaleli sayithi</translation> @@ -245,6 +248,7 @@ <translation id="7828947555739565424">Iphrofayela ye-Chromium enale akhawunti isikhona akakade kule divayisi</translation> <translation id="7857220146454061152">Ukuze uthole izibuyekezo zesikhathi esizayo ze-Chromium, uzodinga i-OS X 10.11 noma yakamuva. Le khompuyutha isebenzisa i-OS X 10.10.</translation> <translation id="7867198900892795913">I-Chromium ayikwazanga ukubuyekezela kwinguqulo yakamuva, ngakho-ke uyalahlekelwa kuzici ezintsha nokulungiswa kokuphepha.</translation> +<translation id="788352880609666695">Ama-akhawunti alandelayo ayatholakala kule phrofayela ye-Chromium</translation> <translation id="7898472181347242998">Ukuze ubone uma ngabe idivayisi yakho isesikhathini, hamba <ph name="LINK_BEGIN" />kuzilungiselelo ze-Chromium OS<ph name="LINK_END" /></translation> <translation id="7937630085815544518">Ubukade ungene ngemvume ku-Chromium njengo-<ph name="USER_EMAIL_ADDRESS" />. Sicela usebenzise i-akhawunti efanayo ukuze uphinde ungene ngemvume futhi.</translation> <translation id="7975919845073681630">Lokhu ukufakwa kwesibili kwe-Chromium, futhi akukwazi ukwenziwa isiphequluli sakho esizenzakalelayo.</translation> @@ -257,6 +261,7 @@ <translation id="8290862415967981663">Leli fayela lingaba yingozi, ngakho-ke i-Chromium iyivimbile.</translation> <translation id="8330519371938183845">Ngena ngemvume ukuze uvumelanise uphinde wenze kube ngeyakho i-Chromium kumadivayisi akho wonkana</translation> <translation id="8340674089072921962"><ph name="USER_EMAIL_ADDRESS" /> ngaphambilini ibisebenzisa i-Chromium</translation> +<translation id="8357820681460164151">Ukuze ufinyelele ezintweni zakho ze-browser ye-Chromium kuwo wonke amadivayisi wakho, ngena ngemvume, bese uvula ukuvumelanisa</translation> <translation id="8417404458978023919">{0,plural, =1{Qalisa kabusha i-Chromium phakathi kosuku}one{Qalisa kabusha i-Chromium phakathi kwezinsuku ezingu-#}other{Qalisa kabusha i-Chromium phakathi kwezinsuku ezingu-#}}</translation> <translation id="8453117565092476964">Ingobo yomlando yesifaki yonakele noma ayivumelekile. Sicela ulande futhi i-Chromium.</translation> <translation id="8493179195440786826">I-Chromium ayikho kudethi</translation>
diff --git a/chrome/app/resources/generated_resources_af.xtb b/chrome/app/resources/generated_resources_af.xtb index 17d04254..a5b8405 100644 --- a/chrome/app/resources/generated_resources_af.xtb +++ b/chrome/app/resources/generated_resources_af.xtb
@@ -6117,7 +6117,6 @@ <translation id="7433708794692032816">Sit slimkaart in om aan te hou om jou <ph name="DEVICE_TYPE" /> te gebruik</translation> <translation id="7433957986129316853">Hou dit</translation> <translation id="7434509671034404296">Ontwikkelaar</translation> -<translation id="7434635829372401939">Sinkroniseer jou instellings</translation> <translation id="7434757724413878233">Muisversnelling</translation> <translation id="7434969625063495310">Kon nie die drukbediener byvoeg nie. Gaan die bediener se opstelling na en probeer weer.</translation> <translation id="7436921188514130341">Ai tog! Kon nie hernoem nie.</translation>
diff --git a/chrome/app/resources/generated_resources_am.xtb b/chrome/app/resources/generated_resources_am.xtb index 6d65cbc..a8c2aff 100644 --- a/chrome/app/resources/generated_resources_am.xtb +++ b/chrome/app/resources/generated_resources_am.xtb
@@ -1229,6 +1229,7 @@ <translation id="2232751457155581899">ጣቢያዎች የካሜራዎን አቀማመጥ ለመከታተል ሊጠይቁ ይችላሉ</translation> <translation id="2232876851878324699">ፋይሉ አንድ እንዲገባ ያልተደረገ የእውቅና ማረጋገጫ ይዞ ነበር፦</translation> <translation id="2233502537820838181">&ተጨማሪ መረጃ</translation> +<translation id="223356358902285214">የድር እና የመተግበሪያ እንቅስቃሴ</translation> <translation id="2234876718134438132">ማመሳሰል እና የGoogle አገልግሎቶች</translation> <translation id="2235344399760031203">የሦስተኛ ወገን ኩኪዎች ታግደዋል</translation> <translation id="2238379619048995541">የተደጋጋሚነት ሁኔታ ውሂብ</translation> @@ -1916,6 +1917,7 @@ <translation id="2923006468155067296">የእርስዎ <ph name="DEVICE_TYPE" /> አሁን ይቆለፋል። <ph name="DOMAIN" /> የእርስዎን ዘመናዊ ካርድ እንደገባ እንዲቆይ ይፈልግብዎታል።</translation> <translation id="2923234477033317484">ይህን መለያ አስወግድ</translation> +<translation id="2923644930701689793">የስልክዎን የካሜራ ጥቅል ይድረሱ</translation> <translation id="2926085873880284723">ነባሪ አቋራጮችን ወደነበሩበት መልስ</translation> <translation id="2926620265753325858"><ph name="DEVICE_NAME" /> አይደገፍም።</translation> <translation id="2927017729816812676">የመሸጎጫ ማከማቻ</translation> @@ -2356,6 +2358,7 @@ <translation id="3413122095806433232">CA ሰጪዎች፦ <ph name="LOCATION" /></translation> <translation id="3414952576877147120">መጠን፦</translation> <translation id="3414966631182382431">የእርስዎ <ph name="BEGIN_LINK" />አሳሽ የሚተዳደረው<ph name="END_LINK" /> በ<ph name="MANAGER" /> ነው</translation> +<translation id="341589277604221596">የቀጥታ ስርጭት መግለጫ ጽሑፍ - <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">ሁልጊዜ ሙሉ ዩአርኤሎችን አሳይ</translation> <translation id="3417835166382867856">ትሮችን ይፈልጉ</translation> <translation id="3417836307470882032">ወታደራዊ ሰዓት</translation> @@ -3106,6 +3109,7 @@ <translation id="4168015872538332605">አንዳንድ የ<ph name="PRIMARY_EMAIL" /> ቅንብሮች ለእርስዎ እየተጋሩ ነው። እነዚህ ቅንብሮች መለያዎ ላይ ተጽዕኖ የሚኖራቸው ባለብዙ መለያ መግቢያን ሲጠቀሙ ብቻ ነው።</translation> <translation id="4169535189173047238">አትፍቀድ</translation> <translation id="4170314459383239649">ሲወጣ አጽዳ</translation> +<translation id="417096670996204801">መገለጫ ይምረጡ</translation> <translation id="4175137578744761569">ፈካ ያለ ወይን ጠጅ እና ነጭ</translation> <translation id="4175737294868205930">ቋሚ ማከማቻ</translation> <translation id="4176463684765177261">ተሰናክሏል</translation> @@ -6105,7 +6109,6 @@ <translation id="7433708794692032816">የእርስዎን <ph name="DEVICE_TYPE" /> እየተጠቀሙ ለመቀጠል ዘመናዊ ካርድ ያስገቡ</translation> <translation id="7433957986129316853">ይቀጥል</translation> <translation id="7434509671034404296">ገንቢ</translation> -<translation id="7434635829372401939">የእርስዎ ቅንብሮችን አስምር</translation> <translation id="7434757724413878233">የመዳፊት ማፍጠኛ</translation> <translation id="7434969625063495310">የህትመት አገልጋዩን ማከል አልተቻለም። እባክዎ የአገልጋዩን ውቅረት ይፈትሹና እንደገና ይሞክሩ።</translation> <translation id="7436921188514130341">ኧረ ቴች! ዳግም በሚሰየምበት ጊዜ የሆነ ስህተት ነበር።</translation> @@ -7193,6 +7196,7 @@ <translation id="8540136935098276800">በትክክል የተቀረጸ ዩአርኤል ያስገቡ</translation> <translation id="8540503336857689453">የተደበቀ አውታረመረብ መጠቀም ለደህንነት ሲባል አይመከርም።</translation> <translation id="854071720451629801">እንደ የተነበበ ምልክት አድርግ</translation> +<translation id="8540942859441851323">ማዞር በአቅራቢው ይፈለጋል</translation> <translation id="8541462173655894684">ከህትመት አገልጋዩ ምንም አታሚዎች አልተገኙም</translation> <translation id="8541838361296720865">እሱን ለ«<ph name="ACTION" />» ለመመደብ የመቀየሪያ ወይም የቁልፍ ሰሌዳ ቁልፍን ይጫኑ</translation> <translation id="8542618328173222274">አንድ ጣቢያ የእርስዎን የምናባዊ እውነታ መሣሪያዎች እና ውሂብ መጠቀም ሲፈልግ ይጠይቅ</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb index 060d618..39fc5ac 100644 --- a/chrome/app/resources/generated_resources_ar.xtb +++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -2353,6 +2353,7 @@ <translation id="3413122095806433232">جهات إصدار المرجع المصدق (CA): <ph name="LOCATION" /></translation> <translation id="3414952576877147120">الحجم:</translation> <translation id="3414966631182382431"><ph name="BEGIN_LINK" />تتم إدارة متصفِّحك<ph name="END_LINK" /> من خلال <ph name="MANAGER" />.</translation> +<translation id="341589277604221596">عرض ميزة "النسخ النصي التلقائي" باللغة <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">عرض عناوين URL الكاملة دائمًا</translation> <translation id="3417835166382867856">البحث في علامات التبويب</translation> <translation id="3417836307470882032">التوقيت العسكري</translation> @@ -6101,7 +6102,6 @@ <translation id="7433708794692032816">أدخِل بطاقة ذكية للاستمرار في استخدام الجهاز <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">تجاهل</translation> <translation id="7434509671034404296">المطوِّر</translation> -<translation id="7434635829372401939">مزامنة إعداداتك</translation> <translation id="7434757724413878233">تسريع الماوس</translation> <translation id="7434969625063495310">تعذّر العثور على خادم الطباعة. يُرجى التحقّق من إعدادات الخادم وإعادة المحاولة.</translation> <translation id="7436921188514130341">عذرًا، حدث خطأ في أثناء إعادة التسمية.</translation> @@ -7184,6 +7184,7 @@ <translation id="8540136935098276800">يُرجى إدخال عنوان URL بتنسيق صحيح.</translation> <translation id="8540503336857689453">لا ننصح باستخدام شبكة مخفية لأسباب تتعلق بالأمان.</translation> <translation id="854071720451629801">وضع علامة "مقروءة"</translation> +<translation id="8540942859441851323">يطلب موفّر الخدمة تفعيل ميزة تجوال بيانات الجوّال.</translation> <translation id="8541462173655894684">لم يتم العثور على أيّ طابعات من خادم الطباعة.</translation> <translation id="8541838361296720865">اضغط على مفتاح تحكّم معيَّن أو مفتاح على لوحة المفاتيح لتخصيصه للإجراء "<ph name="ACTION" />".</translation> <translation id="8542618328173222274">طلب الإذن عندما يحاول موقع إلكتروني استخدام أجهزة الواقع الافتراضي وبياناتها</translation>
diff --git a/chrome/app/resources/generated_resources_as.xtb b/chrome/app/resources/generated_resources_as.xtb index 8266d90..f1dfda9d 100644 --- a/chrome/app/resources/generated_resources_as.xtb +++ b/chrome/app/resources/generated_resources_as.xtb
@@ -1231,6 +1231,7 @@ <translation id="2232751457155581899">ছাইটসমূহে আপোনাৰ কেমেৰাৰ স্থান ট্ৰেক কৰিবলৈ বিচাৰিব পাৰে</translation> <translation id="2232876851878324699">ফাইলটোত আমদানি নকৰা এখন প্ৰমাণপত্ৰ আছে:</translation> <translation id="2233502537820838181">&অধিক তথ্য</translation> +<translation id="223356358902285214">ৱেব আৰু এপৰ কাৰ্যকলাপ</translation> <translation id="2234876718134438132">ছিংক আৰু Google সেৱা</translation> <translation id="2235344399760031203">তৃতীয় পক্ষৰ কুকিসমূহ অৱৰোধ কৰা হৈছে</translation> <translation id="2238379619048995541">সঘনতাৰ স্থিতি ডেটা</translation> @@ -1919,6 +1920,7 @@ <translation id="2923006468155067296">এতিয়া আপোনাৰ <ph name="DEVICE_TYPE" />টো লক কৰা হ'ব। <ph name="DOMAIN" />ৰ বাবে আপুনি নিজৰ স্মাৰ্ট কাৰ্ডখন ভৰাই ৰখাৰ আৱশ্যক।</translation> <translation id="2923234477033317484">এই একাউণ্টটো আঁতৰাওক</translation> +<translation id="2923644930701689793">আপোনাৰ ফ’নৰ কেমেৰা ৰ’ল এক্সেছ কৰক</translation> <translation id="2926085873880284723">ডিফ’ল্ট শ্বৰ্টকাটসমূহ পুনঃস্থাপন কৰক</translation> <translation id="2926620265753325858"><ph name="DEVICE_NAME" /> সমৰ্থিত নহয়।</translation> <translation id="2927017729816812676">কেশ্বৰ ষ্ট'ৰেজ</translation> @@ -3111,6 +3113,7 @@ <translation id="4168015872538332605"><ph name="PRIMARY_EMAIL" />ৰ অন্তৰ্গত কিছুমান ছেটিং আপোনাৰ সৈতে শ্বেয়াৰ কৰা হৈছে৷ এই ছেটিংসমূহ আপোনাৰ একাউণ্টত তেতিয়াহে প্ৰভাৱিত হয় যেতিয়া একাধিক ছাইন ইনৰ ব্যৱহাৰ কৰা হয়৷</translation> <translation id="4169535189173047238">অনুমতি নিদিব</translation> <translation id="4170314459383239649">প্ৰস্থান কৰিলে মচক</translation> +<translation id="417096670996204801">এটা প্ৰ’ফাইল বাছনি কৰক</translation> <translation id="4175137578744761569">পাতল বেঙুনীয়া আৰু বগা</translation> <translation id="4175737294868205930">স্থিৰ ষ্ট’ৰেজ</translation> <translation id="4176463684765177261">অক্ষম আছে</translation> @@ -6111,7 +6114,6 @@ <translation id="7433708794692032816">আপোনাৰ <ph name="DEVICE_TYPE" /> ব্যৱহাৰ কৰি থাকিবলৈ স্মাৰ্ট কাৰ্ড ভৰাওক</translation> <translation id="7433957986129316853">এয়া ৰাখক</translation> <translation id="7434509671034404296">বিকাশকৰ্তা</translation> -<translation id="7434635829372401939">আপোনাৰ ছেটিংসমূহ ছিংক কৰক</translation> <translation id="7434757724413878233">মাউছৰ এক্সিলাৰেশ্বন</translation> <translation id="7434969625063495310">প্ৰিণ্ট ছার্ভাৰটো যোগ দিব পৰা নগ’ল। অনুগ্ৰহ কৰি ছার্ভাৰটোৰ কনফিগাৰেশ্বন পৰীক্ষা কৰক আৰু পুনৰ চেষ্টা কৰক।</translation> <translation id="7436921188514130341">আমি দুঃখিত! পূৰ্বৰ নাম সলাই নতুন নাম দি থাকোঁতে কিবা আসোঁৱাহ হ'ল।</translation>
diff --git a/chrome/app/resources/generated_resources_az.xtb b/chrome/app/resources/generated_resources_az.xtb index 4da35b0..cf81aabb 100644 --- a/chrome/app/resources/generated_resources_az.xtb +++ b/chrome/app/resources/generated_resources_az.xtb
@@ -6095,7 +6095,6 @@ <translation id="7433708794692032816"><ph name="DEVICE_TYPE" /> cihazınızdan istifadəyə davam etmək üçün smart kart taxın</translation> <translation id="7433957986129316853">Saxlayın</translation> <translation id="7434509671034404296">Developer</translation> -<translation id="7434635829372401939">Ayarları sinxronlaşdırın</translation> <translation id="7434757724413878233">Siçanın sürəti</translation> <translation id="7434969625063495310">Çap serverini əlavə etmək mümkün olmadı. Serverin konfiqurasiyasını yoxlayın və yenidən cəhd edin.</translation> <translation id="7436921188514130341">Yenidən adlandırarkən xəta baş verdi.</translation>
diff --git a/chrome/app/resources/generated_resources_be.xtb b/chrome/app/resources/generated_resources_be.xtb index dacb3b0..9d6a7fa 100644 --- a/chrome/app/resources/generated_resources_be.xtb +++ b/chrome/app/resources/generated_resources_be.xtb
@@ -2397,6 +2397,7 @@ <translation id="3449393517661170867">Новае акно ва ўкладцы</translation> <translation id="3449839693241009168">Націсніце <ph name="SEARCH_KEY" />, каб адправіць каманды ў пашырэнне <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Працэнт выкарыстання зараду акумулятара ў стане бяздзейнасці</translation> +<translation id="3450180775417907283">Выкарыстанне дамена "<ph name="MANAGER" />" патрабуе падключэння да сеткі Wi-Fi і спампоўвання абнаўлення.</translation> <translation id="3451753556629288767">Маюць дазвол адкрываць файлы пэўных тыпаў</translation> <translation id="3452999110156026232">Бацькоўскі доступ</translation> <translation id="3453612417627951340">Патрабуецца аўтарызацыя</translation> @@ -4264,6 +4265,7 @@ <translation id="5472627187093107397">Захоўваць паролі для гэтага сайта</translation> <translation id="5473075389972733037">IBM</translation> <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{PIN-код павінен змяшчаць як мінімум 1 сімвал}one{PIN-код павінен змяшчаць як мінімум # сімвал}few{PIN-код павінен змяшчаць як мінімум # сімвалы}many{PIN-код павінен змяшчаць як мінімум # сімвалаў}other{PIN-код павінен змяшчаць як мінімум # сімвала}}</translation> +<translation id="5474859849784484111">Выкарыстанне дамена "<ph name="MANAGER" />" патрабуе падключэння да сеткі Wi-Fi і спампоўвання абнаўлення. Вы можаце таксама спампаваць яго праз падключэнне з падлікам трафіка (можа спаганяцца плата).</translation> <translation id="5481273127572794904">Не дазволена аўтаматычна спампоўваць некалькі файлаў</translation> <translation id="5481941284378890518">Дадаць прынтары паблізу</translation> <translation id="5483785310822538350">Адклікаць доступ да файлаў і прылад</translation> @@ -4689,6 +4691,7 @@ <translation id="592880897588170157">Спампоўваць файлы PDF замест аўтаматычнага адкрыцця ў Chrome</translation> <translation id="592919310198008711">Калі я націскаю на пашырэнне</translation> <translation id="5932124097031739492">Linux абноўлены.</translation> +<translation id="5932209916647644605">Выкарыстанне дамена "<ph name="MANAGER" />" патрабуе неадкладнага абнаўлення прылады "<ph name="DEVICE_TYPE" />".</translation> <translation id="5932224571077948991">Сайт паказвае назойлівую рэкламу або рэкламу, якая ўводзіць у зман</translation> <translation id="59324397759951282">Прылада USB ад вытворцы "<ph name="MANUFACTURER_NAME" />"</translation> <translation id="5932441198730183141">У вас недастаткова ліцэнзій, каб зарэгістраваць гэту прыладу Google Meet. Каб купіць дадатковыя ліцэнзіі, звярніцеся ў аддзел продажу. Калі вы лічыце, што гэта паведамленне паказваецца вам памылкова, звярніцеся ў службу падтрымкі.</translation> @@ -6095,7 +6098,6 @@ <translation id="7433708794692032816">Каб працягваць карыстацца прыладай <ph name="DEVICE_TYPE" />, устаўце разумную картку</translation> <translation id="7433957986129316853">Пакінуць</translation> <translation id="7434509671034404296">Для распрацоўшчыкаў</translation> -<translation id="7434635829372401939">Сінхранізацыя налад</translation> <translation id="7434757724413878233">Паскарэнне мышы</translation> <translation id="7434969625063495310">Не ўдалося дадаць сервер друку. Праверце канфігурацыю сервера і паўтарыце спробу.</translation> <translation id="7436921188514130341">На жаль, падчас перайменавання адбылася памылка.</translation>
diff --git a/chrome/app/resources/generated_resources_bg.xtb b/chrome/app/resources/generated_resources_bg.xtb index 29f3b85..6971ee48 100644 --- a/chrome/app/resources/generated_resources_bg.xtb +++ b/chrome/app/resources/generated_resources_bg.xtb
@@ -6113,7 +6113,6 @@ <translation id="7433708794692032816">Поставете смарткарта, за да продължите да използвате своя <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Запазване</translation> <translation id="7434509671034404296">Програмист</translation> -<translation id="7434635829372401939">Синхронизиране на настройките ви</translation> <translation id="7434757724413878233">Ускоряване на мишката</translation> <translation id="7434969625063495310">Сървърът за отпечатване не бе добавен. Моля, проверете конфигурацията му и опитайте отново.</translation> <translation id="7436921188514130341">Ужас! При преименуването възникна грешка.</translation>
diff --git a/chrome/app/resources/generated_resources_bn.xtb b/chrome/app/resources/generated_resources_bn.xtb index f78a48e..48ce261 100644 --- a/chrome/app/resources/generated_resources_bn.xtb +++ b/chrome/app/resources/generated_resources_bn.xtb
@@ -1234,6 +1234,7 @@ <translation id="2232751457155581899">আপনার ক্যামেরার পজিশন ট্র্যাক করতে সাইট অনুমতি চাইতে পারে</translation> <translation id="2232876851878324699">ফাইলটিতে একটি সার্টিফিকেট রয়েছে, এটি আমদানি করা হয়নি:</translation> <translation id="2233502537820838181">&আরো তথ্য</translation> +<translation id="223356358902285214">ওয়েব ও অ্যাপ অ্যাক্টিভিটি</translation> <translation id="2234876718134438132">সিঙ্ক এবং Google পরিষেবাগুলি</translation> <translation id="2235344399760031203">থার্ড-পার্টি কুকি ব্লক করা হয়েছে</translation> <translation id="2238379619048995541">ফ্রিকোয়েন্সি স্থিতি ডেটা</translation> @@ -1922,6 +1923,7 @@ <translation id="2923006468155067296">আপনার <ph name="DEVICE_TYPE" /> এখনই লক হয়ে যাবে। <ph name="DOMAIN" />-এর জন্য আপনার স্মার্ট কার্ড প্রবেশ করিয়ে রাখতে হবে।</translation> <translation id="2923234477033317484">এই অ্যাকাউন্ট সরিয়ে দিন</translation> +<translation id="2923644930701689793">আপনার ফোনের ক্যামেরা রোল অ্যাক্সেস করুন</translation> <translation id="2926085873880284723">ডিফল্ট শর্টকাট ফিরিয়ে আনুন</translation> <translation id="2926620265753325858"><ph name="DEVICE_NAME" /> কাজ করে না।</translation> <translation id="2927017729816812676">ক্যাশে সঞ্চয় স্থান</translation> @@ -3113,6 +3115,7 @@ <translation id="4168015872538332605"><ph name="PRIMARY_EMAIL" />-এর কিছু সেটিংস আপনার সাথে শেয়ার করা হচ্ছে৷ এই সেটিংস শুধুমাত্র আপনার অ্যাকাউন্টে একাধিক সাইন-ইন ব্যবহারের সময় কাজ করে৷</translation> <translation id="4169535189173047238">অনুমতি দেবেন না</translation> <translation id="4170314459383239649">ছেড়ে গেলে কুকিজ মুছে দিন</translation> +<translation id="417096670996204801">প্রোফাইল বেছে নিন</translation> <translation id="4175137578744761569">হালকা বেগুনি ও সাদা</translation> <translation id="4175737294868205930">অনবরত স্টোরেজ</translation> <translation id="4176463684765177261">অক্ষম হয়েছে</translation> @@ -6114,7 +6117,6 @@ <translation id="7433708794692032816">আপনার <ph name="DEVICE_TYPE" /> ব্যবহার করা চালিয়ে যেতে স্মার্ট কার্ড প্রবেশ করান</translation> <translation id="7433957986129316853">এটি রাখতে চাই</translation> <translation id="7434509671034404296">ডেভেলপার</translation> -<translation id="7434635829372401939">আপনার সেটিংস সিঙ্ক করুন</translation> <translation id="7434757724413878233">মাউস অ্যাক্সিলারেশন</translation> <translation id="7434969625063495310">প্রিন্ট সার্ভারটি যোগ করা যায়নি। সার্ভার কনফিগারেশন চেক করে আবার চেষ্টা করুন।</translation> <translation id="7436921188514130341">নাম পরিবর্তনের সময় একটি ত্রুটি হয়েছিল।</translation>
diff --git a/chrome/app/resources/generated_resources_bs.xtb b/chrome/app/resources/generated_resources_bs.xtb index 72f7dd15..86a2798 100644 --- a/chrome/app/resources/generated_resources_bs.xtb +++ b/chrome/app/resources/generated_resources_bs.xtb
@@ -2362,6 +2362,7 @@ <translation id="3413122095806433232">Izdavači CA potvrda: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">Veličina:</translation> <translation id="3414966631182382431">Vašim <ph name="BEGIN_LINK" />preglednikom upravlja<ph name="END_LINK" /> <ph name="MANAGER" /></translation> +<translation id="341589277604221596">Automatski titlovi – <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">Uvijek prikaži pune URL-ove</translation> <translation id="3417835166382867856">Pretraživanje kartica</translation> <translation id="3417836307470882032">24-satni format vremena</translation> @@ -6115,7 +6116,6 @@ <translation id="7433708794692032816">Umetnite pametnu karticu da nastavite koristiti uređaj <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Zadrži</translation> <translation id="7434509671034404296">Programer</translation> -<translation id="7434635829372401939">Sinhronizirajte postavke</translation> <translation id="7434757724413878233">Ubrzanje miša</translation> <translation id="7434969625063495310">Dodavanje servera za štampanje nije uspjelo. Provjerite konfiguraciju servera i pokušajte ponovo.</translation> <translation id="7436921188514130341">O, ne! Došlo je do pogreške prilikom preimenovanja.</translation> @@ -7198,6 +7198,7 @@ <translation id="8540136935098276800">Unesite URL s ispravnim formatom</translation> <translation id="8540503336857689453">Korištenje skrivene mreže se ne preporučuje iz sigurnosnih razloga.</translation> <translation id="854071720451629801">Označi kao pročitano</translation> +<translation id="8540942859441851323">Davatelj usluga zahtijeva roaming</translation> <translation id="8541462173655894684">Nije pronađen nijedan štampač na serveru za štampanje</translation> <translation id="8541838361296720865">Pritisnite prekidač ili tipku na tastaturi da dodijelite radnju "<ph name="ACTION" />"</translation> <translation id="8542618328173222274">Pitaj me kada web lokacija želi koristiti moje uređaje i podatke virtualne realnosti</translation>
diff --git a/chrome/app/resources/generated_resources_ca.xtb b/chrome/app/resources/generated_resources_ca.xtb index ef3206d..6a1b67b 100644 --- a/chrome/app/resources/generated_resources_ca.xtb +++ b/chrome/app/resources/generated_resources_ca.xtb
@@ -6101,7 +6101,6 @@ <translation id="7433708794692032816">Insereix la targeta intel·ligent per continuar utilitzant el teu <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Mantén els canvis</translation> <translation id="7434509671034404296">Desenvolupador</translation> -<translation id="7434635829372401939">Sincronitza la configuració</translation> <translation id="7434757724413878233">Acceleració del ratolí</translation> <translation id="7434969625063495310">No s'ha pogut afegir el servidor d'impressió. Comprova'n la configuració i torna-ho a provar.</translation> <translation id="7436921188514130341">S'ha produït un error durant el canvi de nom.</translation>
diff --git a/chrome/app/resources/generated_resources_cs.xtb b/chrome/app/resources/generated_resources_cs.xtb index e8578dc..da9bca5 100644 --- a/chrome/app/resources/generated_resources_cs.xtb +++ b/chrome/app/resources/generated_resources_cs.xtb
@@ -6098,7 +6098,6 @@ <translation id="7433708794692032816">Pokud chcete pokračovat v používání zařízení <ph name="DEVICE_TYPE" />, vložte čipovou kartu</translation> <translation id="7433957986129316853">Zachovat</translation> <translation id="7434509671034404296">Vývojář</translation> -<translation id="7434635829372401939">Synchronizace nastavení</translation> <translation id="7434757724413878233">Zrychlení myši</translation> <translation id="7434969625063495310">Přidání tiskového serveru se nezdařilo. Zkontrolujte konfiguraci serveru a zkuste to znovu.</translation> <translation id="7436921188514130341">Aj, chyba! Při přejmenovávání došlo k chybě.</translation>
diff --git a/chrome/app/resources/generated_resources_da.xtb b/chrome/app/resources/generated_resources_da.xtb index 6464977..d80d9d17 100644 --- a/chrome/app/resources/generated_resources_da.xtb +++ b/chrome/app/resources/generated_resources_da.xtb
@@ -6115,7 +6115,6 @@ <translation id="7433708794692032816">Indsæt chipkortet for at blive ved med at bruge din <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Behold den</translation> <translation id="7434509671034404296">Udvikler</translation> -<translation id="7434635829372401939">Synkroniser dine indstillinger</translation> <translation id="7434757724413878233">Acceleration af mus</translation> <translation id="7434969625063495310">Der kunne ikke tilføjes en printerserver. Tjek serverens konfiguration, og prøv igen.</translation> <translation id="7436921188514130341">Øv, surt! Der opstod en fejl under omdøbningen.</translation>
diff --git a/chrome/app/resources/generated_resources_de.xtb b/chrome/app/resources/generated_resources_de.xtb index 4ed0d9df..69b1519 100644 --- a/chrome/app/resources/generated_resources_de.xtb +++ b/chrome/app/resources/generated_resources_de.xtb
@@ -6093,7 +6093,6 @@ <translation id="7433708794692032816">Smartcard einstecken, um <ph name="DEVICE_TYPE" /> weiterhin zu verwenden</translation> <translation id="7433957986129316853">Beibehalten</translation> <translation id="7434509671034404296">Entwickler</translation> -<translation id="7434635829372401939">Einstellungen synchronisieren</translation> <translation id="7434757724413878233">Mausbeschleunigung</translation> <translation id="7434969625063495310">Der Druckserver konnte nicht hinzugefügt werden. Prüfen Sie die Konfiguration des Servers und versuchen Sie es noch einmal.</translation> <translation id="7436921188514130341">Oh nein! Beim Umbenennen ist ein Fehler aufgetreten.</translation>
diff --git a/chrome/app/resources/generated_resources_el.xtb b/chrome/app/resources/generated_resources_el.xtb index 2f34d41..a4ed8391f 100644 --- a/chrome/app/resources/generated_resources_el.xtb +++ b/chrome/app/resources/generated_resources_el.xtb
@@ -1233,6 +1233,7 @@ <translation id="2232751457155581899">Οι ιστότοποι μπορούν να ζητούν την παρακολούθηση της θέσης της κάμεράς σας</translation> <translation id="2232876851878324699">Το αρχείο περιείχε ένα πιστοποιητικό, το οποίο δεν εισάχθηκε: </translation> <translation id="2233502537820838181">&Περισσότερες πληροφορίες</translation> +<translation id="223356358902285214">Δραστηριότητα ιστού και εφαρμογών</translation> <translation id="2234876718134438132">Συγχρονισμός και υπηρ. Google</translation> <translation id="2235344399760031203">Τα cookie τρίτου μέρους αποκλείστηκαν.</translation> <translation id="2238379619048995541">Δεδομένα κατάστασης συχνότητας</translation> @@ -1922,6 +1923,7 @@ <translation id="2923006468155067296">Η συσκευή <ph name="DEVICE_TYPE" /> θα κλειδωθεί τώρα. Ο τομέας <ph name="DOMAIN" /> απαιτεί να μην αφαιρέσετε την έξυπνη κάρτα.</translation> <translation id="2923234477033317484">Κατάργηση αυτού του λογαριασμού</translation> +<translation id="2923644930701689793">Πρόσβαση στις φωτογραφίες κάμερας του τηλεφώνου</translation> <translation id="2926085873880284723">Επαναφορά προεπιλεγμένων συντομεύσεων</translation> <translation id="2926620265753325858">Δεν υποστηρίζεται η συσκευή <ph name="DEVICE_NAME" />.</translation> <translation id="2927017729816812676">Αποθηκευτικός χώρος κρυφής μνήμης</translation> @@ -3114,6 +3116,7 @@ <translation id="4168015872538332605">Ορισμένες ρυθμίσεις που ανήκουν στον χρήστη <ph name="PRIMARY_EMAIL" /> κοινοποιούνται σε εσάς. Αυτές οι ρυθμίσεις επηρεάζουν το λογαριασμό σας μόνο κατά τη χρήση πολλαπλών συνδέσεων.</translation> <translation id="4169535189173047238">Να μην επιτρέπεται</translation> <translation id="4170314459383239649">Διαγραφή κατά την έξοδο</translation> +<translation id="417096670996204801">Επιλέξτε προφίλ</translation> <translation id="4175137578744761569">Ανοιχτό μοβ και λευκό</translation> <translation id="4175737294868205930">Μόνιμος αποθηκευτικός χώρος</translation> <translation id="4176463684765177261">Απενεργοποιημένο</translation> @@ -6115,7 +6118,6 @@ <translation id="7433708794692032816">Εισαγάγετε την έξυπνη κάρτα για να συνεχίσετε τη χρήση της συσκευής <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Διατήρηση</translation> <translation id="7434509671034404296">Για Προγραμματιστές</translation> -<translation id="7434635829372401939">Συγχρονισμός των ρυθμίσεών σας</translation> <translation id="7434757724413878233">Επιτάχυνση ποντικιού</translation> <translation id="7434969625063495310">Δεν ήταν δυνατή η προσθήκη του διακομιστή εκτύπωσης. Ελέγξτε τη διαμόρφωση του διακομιστή και δοκιμάστε ξανά.</translation> <translation id="7436921188514130341">Δυστυχώς, παρουσιάστηκε σφάλμα κατά τη μετονομασία.</translation>
diff --git a/chrome/app/resources/generated_resources_en-GB.xtb b/chrome/app/resources/generated_resources_en-GB.xtb index 8471460..3ac3822 100644 --- a/chrome/app/resources/generated_resources_en-GB.xtb +++ b/chrome/app/resources/generated_resources_en-GB.xtb
@@ -6114,7 +6114,6 @@ <translation id="7433708794692032816">Insert smart card to keep using your <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Keep it</translation> <translation id="7434509671034404296">Developer</translation> -<translation id="7434635829372401939">Sync your settings</translation> <translation id="7434757724413878233">Mouse acceleration</translation> <translation id="7434969625063495310">Couldn't add the print server. Please check the server's configuration and try again.</translation> <translation id="7436921188514130341">Oh no! There was an error during renaming.</translation>
diff --git a/chrome/app/resources/generated_resources_es-419.xtb b/chrome/app/resources/generated_resources_es-419.xtb index 4416d37..8a1c27b 100644 --- a/chrome/app/resources/generated_resources_es-419.xtb +++ b/chrome/app/resources/generated_resources_es-419.xtb
@@ -6095,7 +6095,6 @@ <translation id="7433708794692032816">Inserta la tarjeta inteligente para seguir usando tu <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Conservar el cambio</translation> <translation id="7434509671034404296">Opciones para desarrolladores</translation> -<translation id="7434635829372401939">Sincroniza tu configuración</translation> <translation id="7434757724413878233">Aceleración del mouse</translation> <translation id="7434969625063495310">No se pudo agregar el servidor de impresión. Revisa la configuración del servidor y vuelve a intentarlo.</translation> <translation id="7436921188514130341">Se produjo un error al cambiar el nombre.</translation>
diff --git a/chrome/app/resources/generated_resources_es.xtb b/chrome/app/resources/generated_resources_es.xtb index 35bd22a..d25a8f09 100644 --- a/chrome/app/resources/generated_resources_es.xtb +++ b/chrome/app/resources/generated_resources_es.xtb
@@ -6095,7 +6095,6 @@ <translation id="7433708794692032816">Introduce la tarjeta inteligente para seguir usando tu <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Conservar</translation> <translation id="7434509671034404296">Opciones para desarrolladores</translation> -<translation id="7434635829372401939">Sincronizar tus ajustes</translation> <translation id="7434757724413878233">Aceleración del ratón</translation> <translation id="7434969625063495310">No se ha podido añadir el servidor de impresión. Revisa la configuración del servidor y vuelve a intentarlo.</translation> <translation id="7436921188514130341">¡Vaya! No se ha podido cambiar el nombre.</translation>
diff --git a/chrome/app/resources/generated_resources_et.xtb b/chrome/app/resources/generated_resources_et.xtb index 8b67d1b..aaaab379 100644 --- a/chrome/app/resources/generated_resources_et.xtb +++ b/chrome/app/resources/generated_resources_et.xtb
@@ -6103,7 +6103,6 @@ <translation id="7433708794692032816">Sisestage kiipkaart, et jätkata seadme <ph name="DEVICE_TYPE" /> kasutamist</translation> <translation id="7433957986129316853">Säilita</translation> <translation id="7434509671034404296">Arendaja</translation> -<translation id="7434635829372401939">Seadete sünkroonimine</translation> <translation id="7434757724413878233">Hiire kiirendus</translation> <translation id="7434969625063495310">Prindiserverit ei õnnestunud lisada. Kontrollige serveri seadistust ja proovige uuesti.</translation> <translation id="7436921188514130341">Ups, ebaõnn! Ümbernimetamisel ilmnes viga.</translation>
diff --git a/chrome/app/resources/generated_resources_eu.xtb b/chrome/app/resources/generated_resources_eu.xtb index 190c0dd9..7b5df4c 100644 --- a/chrome/app/resources/generated_resources_eu.xtb +++ b/chrome/app/resources/generated_resources_eu.xtb
@@ -1221,6 +1221,7 @@ <translation id="2232751457155581899">Webguneek kameraren posizioaren jarraipena egitea eska dezakete</translation> <translation id="2232876851878324699">Fitxategiak ziurtagiri bat du, baina ez da inportatu.</translation> <translation id="2233502537820838181">Infor&mazio gehiago</translation> +<translation id="223356358902285214">Sareko eta aplikazioetako jarduerak</translation> <translation id="2234876718134438132">Sinkronizazioa eta Google-ren zerbitzuak</translation> <translation id="2235344399760031203">Hirugarrenen cookieak blokeatu dira</translation> <translation id="2238379619048995541">Maiztasunaren egoeraren datuak</translation> @@ -1906,6 +1907,7 @@ <translation id="2923006468155067296"><ph name="DEVICE_TYPE" /> blokeatu egingo da. Txartel adimenduna sartuta edukitzea eskatzen du <ph name="DOMAIN" /> domeinuak.</translation> <translation id="2923234477033317484">Kendu kontua</translation> +<translation id="2923644930701689793">Atzitu kamerako argazkiak</translation> <translation id="2926085873880284723">Leheneratu lasterbide lehenetsiak</translation> <translation id="2926620265753325858">Ez da onartzen <ph name="DEVICE_NAME" />.</translation> <translation id="2927017729816812676">Cache-memoria</translation> @@ -2346,6 +2348,7 @@ <translation id="3413122095806433232">Autoritate ziurtagiri-emaileen jaulkitzaileak: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">Tamaina:</translation> <translation id="3414966631182382431"><ph name="MANAGER" /> domeinuak <ph name="BEGIN_LINK" />kudeatzen du arakatzailea<ph name="END_LINK" /></translation> +<translation id="341589277604221596">Istanteko azpitituluak (<ph name="LANGUAGE" />)</translation> <translation id="3416468988018290825">Erakutsi beti URL osoak</translation> <translation id="3417835166382867856">Bilatu fitxak</translation> <translation id="3417836307470882032">24 orduko formatua</translation> @@ -3098,6 +3101,7 @@ <translation id="4168015872538332605"><ph name="PRIMARY_EMAIL" /> kontuko ezarpen batzuk zurekin partekatu dira. Ezarpen horiek saio-hasiera anizkoitza erabiltzean soilik izango dute eragina zure kontuan.</translation> <translation id="4169535189173047238">Ez eman baimenik</translation> <translation id="4170314459383239649">Garbitu irteterakoan</translation> +<translation id="417096670996204801">Aukeratu profil bat</translation> <translation id="4175137578744761569">More argia eta zuria</translation> <translation id="4175737294868205930">Memoria iraunkorra</translation> <translation id="4176463684765177261">Desgaituta</translation> @@ -6095,7 +6099,6 @@ <translation id="7433708794692032816">Sartu txartel adimenduna <ph name="DEVICE_TYPE" /> erabiltzen jarraitzeko</translation> <translation id="7433957986129316853">Mantendu</translation> <translation id="7434509671034404296">Garatzailea</translation> -<translation id="7434635829372401939">Sinkronizatu ezarpenak</translation> <translation id="7434757724413878233">Saguaren erabilera bizkortua</translation> <translation id="7434969625063495310">Ezin izan da gehitu inprimatze-zerbitzaria. Egiaztatu ongi konfiguratuta dagoela eta saiatu berriro.</translation> <translation id="7436921188514130341">Errore bat gertatu da izena aldatzean.</translation> @@ -7175,6 +7178,7 @@ <translation id="8540136935098276800">Idatzi formatu egokia duen URL bat</translation> <translation id="8540503336857689453">Segurtasuna bermatzeko, ez da gomendatzen sare ezkutu bat erabiltzea.</translation> <translation id="854071720451629801">Markatu irakurritako gisa</translation> +<translation id="8540942859441851323">Hornitzaileak ibiltaritza behar du</translation> <translation id="8541462173655894684">Ez da aurkitu inprimagailurik inprimatze-zerbitzarian</translation> <translation id="8541838361296720865">Sakatu erabilerraztasun-etengailu bat edo teklatuko tekla bat hura "<ph name="ACTION" />" ekintzari esleitzeko</translation> <translation id="8542618328173222274">Eskatu zure baimena webguneren batek errealitate birtualeko gailuak eta datuak erabili nahi dituenean</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb index e5d883e..948cb047 100644 --- a/chrome/app/resources/generated_resources_fa.xtb +++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -1230,6 +1230,7 @@ <translation id="2232751457155581899">سایتها میتوانند ردیابی موقعیت دوربین را درخواست کنند</translation> <translation id="2232876851878324699">این فایل دارای یک مجوز است، که وارد نشده است:</translation> <translation id="2233502537820838181">&اطلاعات بیشتر</translation> +<translation id="223356358902285214">فعالیت برنامه و وب</translation> <translation id="2234876718134438132">همگامسازی و سرویسهای Google</translation> <translation id="2235344399760031203">کوکیهای شخص ثالث مسدود شدهاند</translation> <translation id="2238379619048995541">دادههای حالت فرکانس</translation> @@ -1919,6 +1920,7 @@ <translation id="2923006468155067296">دستگاه <ph name="DEVICE_TYPE" /> شما اکنون قفل میشود. برای اینکه از سیستم <ph name="DOMAIN" /> خارج نشوید، باید کارت هوشمندتان را در دستگاه نگه دارید.</translation> <translation id="2923234477033317484">حذف این حساب</translation> +<translation id="2923644930701689793">دسترسی به حلقه فیلم دوربین تلفن</translation> <translation id="2926085873880284723">بازیابی میانبرهای پیشفرض</translation> <translation id="2926620265753325858"><ph name="DEVICE_NAME" /> پشتیبانی نمیشود.</translation> <translation id="2927017729816812676">فضای حافظه پنهان</translation> @@ -2359,6 +2361,7 @@ <translation id="3413122095806433232">صادرکنندگان CA: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">اندازه:</translation> <translation id="3414966631182382431"><ph name="BEGIN_LINK" />مرورگرتان<ph name="END_LINK" /> توسط <ph name="MANAGER" /> مدیریت میشود</translation> +<translation id="341589277604221596">زیرنویس ناشنوایان زنده - <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">همیشه نشانیهای وب کامل نشان داده شود</translation> <translation id="3417835166382867856">برگههای جستجو</translation> <translation id="3417836307470882032">ساعت نظامی</translation> @@ -3111,6 +3114,7 @@ <translation id="4168015872538332605">برخی از تنظیمات متعلق به <ph name="PRIMARY_EMAIL" /> با شما به اشتراک گذاشته میشود. این تنظیمات وقتی از ورود چندگانه به سیستم استفاده شود، فقط در حساب شما اعمال میشود.</translation> <translation id="4169535189173047238">اجازه داده نشود</translation> <translation id="4170314459383239649">پاک کردن هنگام خروج</translation> +<translation id="417096670996204801">انتخاب نمایه</translation> <translation id="4175137578744761569">بنفش روشن و سفید</translation> <translation id="4175737294868205930">محل ذخیرهسازی دائمی</translation> <translation id="4176463684765177261">غیرفعال شد</translation> @@ -6111,7 +6115,6 @@ <translation id="7433708794692032816">برای ادامه استفاده از <ph name="DEVICE_TYPE" />، کارت هوشمند را وارد کنید</translation> <translation id="7433957986129316853">حفظ شود</translation> <translation id="7434509671034404296">برنامهنویس</translation> -<translation id="7434635829372401939">همگامسازی تنظیمات</translation> <translation id="7434757724413878233">شتاب موشواره</translation> <translation id="7434969625063495310">سرور چاپ اضافه نشد. لطفاً پیکربندی سرور را بررسی و دوباره امتحان کنید.</translation> <translation id="7436921188514130341">اوه، نه! درحین تغییر نام خطایی رخ داد.</translation> @@ -7194,6 +7197,7 @@ <translation id="8540136935098276800">نشانی وبی وارد کنید که بهدرستی قالببندی شده باشد</translation> <translation id="8540503336857689453">بهدلایل امنیتی، توصیه میشود از شبکه پنهان استفاده نشود.</translation> <translation id="854071720451629801">علامتگذاری بهعنوان خواندهشده</translation> +<translation id="8540942859441851323">فراگردی ازسوی ارائهدهنده الزامی است</translation> <translation id="8541462173655894684">هیچ چاپگری از این سرور چاپ پیدا نشد</translation> <translation id="8541838361296720865">کلیدی خارجی یا کلیدی از صفحهکلید را فشار دهید تا به کنش «<ph name="ACTION" />» اختصاص داده شود</translation> <translation id="8542618328173222274">وقتی سایتی میخواهد از دستگاهها و دادههای واقعیت مجازی استفاده کند سؤال شود</translation>
diff --git a/chrome/app/resources/generated_resources_fi.xtb b/chrome/app/resources/generated_resources_fi.xtb index b3b83ad..4f29916 100644 --- a/chrome/app/resources/generated_resources_fi.xtb +++ b/chrome/app/resources/generated_resources_fi.xtb
@@ -6110,7 +6110,6 @@ <translation id="7433708794692032816">Aseta älykortti, niin <ph name="DEVICE_TYPE" /> on taas käytettävissä</translation> <translation id="7433957986129316853">Säilytä</translation> <translation id="7434509671034404296">Kehittäjille</translation> -<translation id="7434635829372401939">Synkronoi asetuksesi</translation> <translation id="7434757724413878233">Hiiren nopeuttaminen</translation> <translation id="7434969625063495310">Tulostuspalvelinta ei voitu asentaa. Tarkista palvelimen asetukset ja yritä uudelleen.</translation> <translation id="7436921188514130341">Harmin paikka! Uudelleennimeämisen aikana tapahtui virhe.</translation>
diff --git a/chrome/app/resources/generated_resources_fil.xtb b/chrome/app/resources/generated_resources_fil.xtb index 701a9f24..909fdeb 100644 --- a/chrome/app/resources/generated_resources_fil.xtb +++ b/chrome/app/resources/generated_resources_fil.xtb
@@ -2365,6 +2365,7 @@ <translation id="3413122095806433232">Mga Nagbigay ng CA: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">Laki:</translation> <translation id="3414966631182382431">Pinaapamahalaan ng <ph name="MANAGER" /> ang iyong <ph name="BEGIN_LINK" />browser<ph name="END_LINK" /></translation> +<translation id="341589277604221596">Instant Caption - <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">Palaging ipakita ang mga buong URL</translation> <translation id="3417835166382867856">Maghanap sa mga tab</translation> <translation id="3417836307470882032">Military time</translation> @@ -6118,7 +6119,6 @@ <translation id="7433708794692032816">Maglagay ng smart card para mapanatili ang iyong <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Panatilihin ito</translation> <translation id="7434509671034404296">Bumubuo</translation> -<translation id="7434635829372401939">I-sync ang iyong mga setting</translation> <translation id="7434757724413878233">Pag-accelerate ng mouse</translation> <translation id="7434969625063495310">Hindi maidagdag ang server sa pag-print. Pakisuri ang configuration ng server at subukan ulit.</translation> <translation id="7436921188514130341">Naku! Nagka-error habang pinapalitan ang pangalan.</translation> @@ -7202,6 +7202,7 @@ <translation id="8540136935098276800">Maglagay ng URL na tama ang pag-format</translation> <translation id="8540503336857689453">Hindi inirerekomenda ang paggamit ng nakatagong network para sa seguridad.</translation> <translation id="854071720451629801">Markahan Bilang Nabasa Na</translation> +<translation id="8540942859441851323">Kinakailangan ng provider ang pag-roam</translation> <translation id="8541462173655894684">Walang nakitang anumang printer mula sa server sa pag-print</translation> <translation id="8541838361296720865">Pumindot ng switch o key sa keyboard para italaga ito sa “<ph name="ACTION" />”</translation> <translation id="8542618328173222274">Magtanong kapag gusto ng isang site na gamitin ang iyong mga virtual reality device at data</translation>
diff --git a/chrome/app/resources/generated_resources_fr-CA.xtb b/chrome/app/resources/generated_resources_fr-CA.xtb index fbc7f387..c102668 100644 --- a/chrome/app/resources/generated_resources_fr-CA.xtb +++ b/chrome/app/resources/generated_resources_fr-CA.xtb
@@ -6089,7 +6089,6 @@ <translation id="7433708794692032816">Insérez votre carte à puce pour continuer à utiliser votre <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Conserver</translation> <translation id="7434509671034404296">Concepteur</translation> -<translation id="7434635829372401939">Synchroniser vos paramètres</translation> <translation id="7434757724413878233">Accélération de la souris</translation> <translation id="7434969625063495310">Impossible d'ajouter le serveur d'impression. Veuillez vérifier la configuration du serveur, puis réessayer.</translation> <translation id="7436921188514130341">Oups… Une erreur s'est produite lors du changement de nom.</translation>
diff --git a/chrome/app/resources/generated_resources_fr.xtb b/chrome/app/resources/generated_resources_fr.xtb index 19f27a5..76c3efd 100644 --- a/chrome/app/resources/generated_resources_fr.xtb +++ b/chrome/app/resources/generated_resources_fr.xtb
@@ -6092,7 +6092,6 @@ <translation id="7433708794692032816">Insérez votre carte à puce pour continuer à utiliser votre <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Conserver</translation> <translation id="7434509671034404296">Options pour les développeurs</translation> -<translation id="7434635829372401939">Synchroniser vos paramètres</translation> <translation id="7434757724413878233">Accélération du curseur</translation> <translation id="7434969625063495310">Impossible d'ajouter le serveur d'impression. Veuillez vérifier la configuration du serveur, puis réessayer.</translation> <translation id="7436921188514130341">Aïe, aïe, aïe ! Une erreur s'est produite lors du changement du nom.</translation>
diff --git a/chrome/app/resources/generated_resources_gl.xtb b/chrome/app/resources/generated_resources_gl.xtb index d361db2..46c94e1 100644 --- a/chrome/app/resources/generated_resources_gl.xtb +++ b/chrome/app/resources/generated_resources_gl.xtb
@@ -2393,6 +2393,7 @@ <translation id="3449393517661170867">Nova ventá con pestanas</translation> <translation id="3449839693241009168">Preme <ph name="SEARCH_KEY" /> para enviar comandos a <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Porcentaxe de ocupación de estado de inactividade</translation> +<translation id="3450180775417907283"><ph name="MANAGER" /> require que te conectes agora á wifi e descargues unha actualización.</translation> <translation id="3451753556629288767">Con permiso para abrir tipos de ficheiros</translation> <translation id="3452999110156026232">Acceso parental</translation> <translation id="3453612417627951340">Precisa autorización</translation> @@ -4261,6 +4262,7 @@ <translation id="5472627187093107397">Gardar os contrasinais deste sitio</translation> <translation id="5473075389972733037">IBM</translation> <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{O PIN debe ter como mínimo 1 carácter}other{O PIN debe ter como mínimo # caracteres}}</translation> +<translation id="5474859849784484111"><ph name="MANAGER" /> require que te conectes agora á wifi e descargues unha actualización. Tamén podes descargala desde unha conexión de pago por consumo (pódense aplicar cargos).</translation> <translation id="5481273127572794904">Sitios que non poden descargar automaticamente varios ficheiros</translation> <translation id="5481941284378890518">Engadir impresoras que estean cerca</translation> <translation id="5483785310822538350">Revogar acceso a ficheiros e dispositivos</translation> @@ -4686,6 +4688,7 @@ <translation id="592880897588170157">Descargar ficheiros PDF en lugar de abrilos automaticamente en Chrome</translation> <translation id="592919310198008711">Cando faga clic na extensión</translation> <translation id="5932124097031739492">Linux actualizouse correctamente.</translation> +<translation id="5932209916647644605"><ph name="MANAGER" /> require actualizar o teu dispositivo (<ph name="DEVICE_TYPE" />) de inmediato.</translation> <translation id="5932224571077948991">O sitio mostra anuncios enganosos ou intrusivos</translation> <translation id="59324397759951282">Dispositivo USB de <ph name="MANUFACTURER_NAME" /></translation> <translation id="5932441198730183141">Non tes suficientes licenzas dispoñibles para inscribir este dispositivo de hardware de Google Meet. Se queres comprar máis, ponte en contacto co departamento de vendas. Se consideras que esta mensaxe se che mostrou por erro, ponte en contacto co servizo de asistencia.</translation> @@ -6091,7 +6094,6 @@ <translation id="7433708794692032816">Para seguir usando o teu dispositivo (<ph name="DEVICE_TYPE" />), insire a tarxeta intelixente</translation> <translation id="7433957986129316853">Conservar cambios</translation> <translation id="7434509671034404296">Programador</translation> -<translation id="7434635829372401939">Sincronizar a túa configuración</translation> <translation id="7434757724413878233">Aceleración do rato</translation> <translation id="7434969625063495310">Non se puido engadir o servidor de impresión. Comproba a súa configuración e téntao de novo.</translation> <translation id="7436921188514130341">Que pena! Produciuse un erro durante o cambio de nome.</translation>
diff --git a/chrome/app/resources/generated_resources_gu.xtb b/chrome/app/resources/generated_resources_gu.xtb index da179458..01b9718 100644 --- a/chrome/app/resources/generated_resources_gu.xtb +++ b/chrome/app/resources/generated_resources_gu.xtb
@@ -6101,7 +6101,6 @@ <translation id="7433708794692032816">તમારા <ph name="DEVICE_TYPE" />નો ઉપયોગ ચાલુ રાખવા માટે સ્માર્ટ કાર્ડ દાખલ કરો</translation> <translation id="7433957986129316853">આ જ રાખો</translation> <translation id="7434509671034404296">વિકાસકર્તા</translation> -<translation id="7434635829372401939">તમારા સેટિંગને સિંક કરો</translation> <translation id="7434757724413878233">માઉસની ઝડપ</translation> <translation id="7434969625063495310">પ્રિન્ટ સર્વર ઉમેરી શક્યા નથી. કૃપા કરીને સર્વરની ગોઠવણી ચેક કરો અને ફરી પ્રયાસ કરો.</translation> <translation id="7436921188514130341">અરેરે! નામ બદલતી વખતે એક ભૂલ આવી હતી.</translation>
diff --git a/chrome/app/resources/generated_resources_hi.xtb b/chrome/app/resources/generated_resources_hi.xtb index b44c3d3..ebc7a458 100644 --- a/chrome/app/resources/generated_resources_hi.xtb +++ b/chrome/app/resources/generated_resources_hi.xtb
@@ -6113,7 +6113,6 @@ <translation id="7433708794692032816"><ph name="DEVICE_TYPE" /> का इस्तेमाल जारी रखने के लिए स्मार्ट कार्ड डालें</translation> <translation id="7433957986129316853">इसे बनाए रखें</translation> <translation id="7434509671034404296">डेवलपर</translation> -<translation id="7434635829372401939">अपनी सेटिंग सिंक करें</translation> <translation id="7434757724413878233">माउस की रफ़्तार बढ़ाना</translation> <translation id="7434969625063495310">प्रिंट सर्वर नहीं जोड़ा जा सका. कृपया सर्वर का कॉन्फ़िगरेशन जांचें और फिर से कोशिश करें.</translation> <translation id="7436921188514130341">हे भगवान! नाम बदलने के दौरान गड़बड़ी हुई.</translation>
diff --git a/chrome/app/resources/generated_resources_hr.xtb b/chrome/app/resources/generated_resources_hr.xtb index 5375a40..9024b65 100644 --- a/chrome/app/resources/generated_resources_hr.xtb +++ b/chrome/app/resources/generated_resources_hr.xtb
@@ -1223,6 +1223,7 @@ <translation id="2232751457155581899">Web-lokacije mogu tražiti dopuštenje za praćenje položaja kamere</translation> <translation id="2232876851878324699">Datoteka je sadržavala jedan certifikat koji nije bio uvezen:</translation> <translation id="2233502537820838181">&Više informacija</translation> +<translation id="223356358902285214">Aktivnost na webu i u aplikacijama</translation> <translation id="2234876718134438132">Sinkronizacija i Googleove usluge</translation> <translation id="2235344399760031203">Blokirani su kolačići treće strane</translation> <translation id="2238379619048995541">Podaci o stanju učestalosti</translation> @@ -1910,6 +1911,7 @@ <translation id="2923006468155067296"><ph name="DEVICE_TYPE" /> će se odmah zaključati. <ph name="DOMAIN" /> zahtijeva da vaša pametna kartica ostane umetnuta.</translation> <translation id="2923234477033317484">Ukloni taj račun</translation> +<translation id="2923644930701689793">Pristupite snimljenim fotografijama na telefonu</translation> <translation id="2926085873880284723">Vrati zadane prečace</translation> <translation id="2926620265753325858">Uređaj <ph name="DEVICE_NAME" /> nije podržan.</translation> <translation id="2927017729816812676">Pohrana predmemorije</translation> @@ -2350,6 +2352,7 @@ <translation id="3413122095806433232">CA izdavači: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">Veličina:</translation> <translation id="3414966631182382431">Vašim <ph name="BEGIN_LINK" />preglednikom upravlja<ph name="END_LINK" /> <ph name="MANAGER" /></translation> +<translation id="341589277604221596">Automatski titlovi – <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">Uvijek prikaži cijele URL-ove</translation> <translation id="3417835166382867856">Pretraži kartice</translation> <translation id="3417836307470882032">24-satni brojčanik</translation> @@ -2398,6 +2401,7 @@ <translation id="3449393517661170867">Novi prozor s karticama</translation> <translation id="3449839693241009168">Pritisnite <ph name="SEARCH_KEY" /> da biste poslali naredbe usluzi <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Postotak zauzetosti u stanju mirovanja</translation> +<translation id="3450180775417907283"><ph name="MANAGER" /> zahtijeva da se odmah povežete s Wi-Fijem i preuzmete ažuriranje.</translation> <translation id="3451753556629288767">Ima dopuštenje za otvaranje određenih vrsta datoteka</translation> <translation id="3452999110156026232">Roditeljski pristup</translation> <translation id="3453612417627951340">Potrebna je autorizacija</translation> @@ -3101,6 +3105,7 @@ <translation id="4168015872538332605">Neke postavke korisnika <ph name="PRIMARY_EMAIL" /> dijele se s vama. Te postavke utječu na vaš račun samo kad upotrebljavate višestruku prijavu.</translation> <translation id="4169535189173047238">Nemoj dopustiti</translation> <translation id="4170314459383239649">Izbriši pri izlazu</translation> +<translation id="417096670996204801">Odabir profila</translation> <translation id="4175137578744761569">Svijetloljubičasta i bijela</translation> <translation id="4175737294868205930">Stalna pohrana</translation> <translation id="4176463684765177261">Onemogućeno</translation> @@ -4267,6 +4272,7 @@ <translation id="5472627187093107397">Spremanje zaporki za ovu web-lokaciju</translation> <translation id="5473075389972733037">IBM</translation> <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{PIN mora imati najmanje jedan znak}one{PIN mora imati najmanje # znak}few{PIN mora imati najmanje # znaka}other{PIN mora imati najmanje # znakova}}</translation> +<translation id="5474859849784484111"><ph name="MANAGER" /> zahtijeva da se odmah povežete s Wi-Fijem i preuzmete ažuriranje. Možete ga preuzeti i putem veze s ograničenim prometom (moguća je naplata naknada).</translation> <translation id="5481273127572794904">Nije dopušteno automatsko preuzimanje više datoteka</translation> <translation id="5481941284378890518">Dodaj pisače u blizini</translation> <translation id="5483785310822538350">Opozovi pristup datotekama i uređaju</translation> @@ -4692,6 +4698,7 @@ <translation id="592880897588170157">Preuzmite PDF datoteke umjesto da se automatski otvaraju u Chromeu</translation> <translation id="592919310198008711">Kad kliknem proširenje</translation> <translation id="5932124097031739492">Linux je uspješno nadograđen.</translation> +<translation id="5932209916647644605"><ph name="MANAGER" /> zahtijeva da odmah ažurirate uređaj <ph name="DEVICE_TYPE" />.</translation> <translation id="5932224571077948991">Web-lokacija prikazuje ometajuće ili obmanjujuće oglase</translation> <translation id="59324397759951282">USB uređaj proizvođača <ph name="MANUFACTURER_NAME" /></translation> <translation id="5932441198730183141">Nemate dovoljno softverskih licenci za prijavu ovog hardvera za Google Meet. Obratite se prodaji da biste kupili više licenci. Ako smatrate da vam se ova poruka prikazuje pogreškom, obratite se podršci.</translation> @@ -6098,7 +6105,6 @@ <translation id="7433708794692032816">Umetnite pametnu karticu da biste nastavili upotrebljavati uređaj <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Zadrži</translation> <translation id="7434509671034404296">Razvojni programer</translation> -<translation id="7434635829372401939">Sinkronizirajte svoje postavke</translation> <translation id="7434757724413878233">Ubrzanje miša</translation> <translation id="7434969625063495310">Dodavanje poslužitelja za ispis nije uspjelo. Provjerite konfiguraciju poslužitelja i pokušajte ponovo.</translation> <translation id="7436921188514130341">O, ne! Došlo je do pogreške prilikom preimenovanja.</translation> @@ -7180,6 +7186,7 @@ <translation id="8540136935098276800">Unesite ispravno oblikovan URL</translation> <translation id="8540503336857689453">Upotreba skrivene mreže ne preporučuje se iz sigurnosnih razloga.</translation> <translation id="854071720451629801">Označi kao pročitano</translation> +<translation id="8540942859441851323">Davatelj usluga zahtijeva roaming</translation> <translation id="8541462173655894684">Nije pronađen nijedan pisač na poslužitelju za ispis</translation> <translation id="8541838361296720865">Pritisnite prekidač ili tipku tipkovnice da biste ih dodijelili radnji <ph name="ACTION" /></translation> <translation id="8542618328173222274">Kad web-lokacija želi koristiti uređaje i podatke virtualne stvarnosti, prikaži upit</translation>
diff --git a/chrome/app/resources/generated_resources_hu.xtb b/chrome/app/resources/generated_resources_hu.xtb index e181e0f..9eb8446 100644 --- a/chrome/app/resources/generated_resources_hu.xtb +++ b/chrome/app/resources/generated_resources_hu.xtb
@@ -6113,7 +6113,6 @@ <translation id="7433708794692032816">Helyezze be az intelligens kártyát, hogy tovább használhassa <ph name="DEVICE_TYPE" /> eszközét</translation> <translation id="7433957986129316853">Megtartom</translation> <translation id="7434509671034404296">Fejlesztőknek</translation> -<translation id="7434635829372401939">Beállítások szinkronizálása</translation> <translation id="7434757724413878233">Egér gyorsítása</translation> <translation id="7434969625063495310">Nem sikerült hozzáadni a nyomtatószervert. Ellenőrizze a szerver beállításait, majd próbálja újra.</translation> <translation id="7436921188514130341">Ajjaj! Hiba történt az átnevezés közben.</translation>
diff --git a/chrome/app/resources/generated_resources_hy.xtb b/chrome/app/resources/generated_resources_hy.xtb index 8fe9a53a..92c0df5 100644 --- a/chrome/app/resources/generated_resources_hy.xtb +++ b/chrome/app/resources/generated_resources_hy.xtb
@@ -598,6 +598,7 @@ <translation id="161042844686301425">Երկնագույն</translation> <translation id="1611432201750675208">Ձեր սարքը կողպված է</translation> <translation id="1612019740169791082">Ձեր կոնտեյներում հնարավոր չէ փոփոխել սկավառակի չափը։ Լինուքսի (բետա) համար հատկացվող տարածքի ծավալը փոխելու համար պահուստավորեք սկավառակը և վերականգնեք այն նոր կոնտեյներում։</translation> +<translation id="1613019471223620622">Ցույց տալ <ph name="USERNAME" /> հաշվի գաղտնաբառը <ph name="DOMAIN" /> տիրույթում</translation> <translation id="1614511179807650956">Հնարավոր է՝ դուք սպառել եք հասանելի ամբողջ բջջային թրաֆիկը: Լրացուցիչ թրաֆիկ գնելու համար այցելեք <ph name="NAME" /> ակտիվացման կայքէջ:</translation> <translation id="161460670679785907">Չհաջողվեց հայտնաբերել ձեր հեռախոսը</translation> <translation id="1615337439947999338">Պահել իմ Google հաշվում (<ph name="EMAIL" />)</translation> @@ -1205,6 +1206,7 @@ <translation id="2220529011494928058">Հաղորդել խնդրի մասին</translation> <translation id="2220572644011485463">PIN կոդը կամ գաղտնաբառը</translation> <translation id="2221261048068091179"><ph name="FIRST_SWITCH" />, <ph name="SECOND_SWITCH" /></translation> +<translation id="222201875806112242">Անանուն մեդիա աղբյուր</translation> <translation id="2224444042887712269">Այս կարգավորման հեղինակը <ph name="OWNER_EMAIL" />-ն է:</translation> <translation id="222447520299472966">Անհրաժեշտ է ընտրել ցուցասրահի առնվազն մեկ ալբոմ</translation> <translation id="2224551243087462610">Պանակի անվան փոփոխում</translation> @@ -1221,6 +1223,7 @@ <translation id="2232751457155581899">Կայքերը կարող են հետագծել տեսախցիկի դիրքը</translation> <translation id="2232876851878324699">Ֆայլում պարունակվում էր վկայագիր, որը չի ներմուծվել`</translation> <translation id="2233502537820838181">&Լրացուցիչ տեղեկություններ</translation> +<translation id="223356358902285214">Ակտիվությունը համացանցում և հավելվածներում</translation> <translation id="2234876718134438132">Համաժամացում և Google-ի ծառայություններ</translation> <translation id="2235344399760031203">Երրորդ կողմի քուքիներն արգելափակված են</translation> <translation id="2238379619048995541">Տվյալներ հաճախականության վիճակի մասին</translation> @@ -1906,6 +1909,7 @@ <translation id="2923006468155067296">Ձեր <ph name="DEVICE_TYPE" /> սարքն այժմ կկողպվի։ Համաձայն <ph name="DOMAIN" /> տիրույթի կանոնների՝ խելացի քարտը պետք է տեղադրված լինի։</translation> <translation id="2923234477033317484">Հեռացնել հաշիվը</translation> +<translation id="2923644930701689793">Բացեք ձեր հեռախոսի ֆոտոժապավենը</translation> <translation id="2926085873880284723">Վերականգնել կանխադրված դյուրանցումները</translation> <translation id="2926620265753325858"><ph name="DEVICE_NAME" /> սարքը չի աջակցվում։</translation> <translation id="2927017729816812676">Հիշապահեստ</translation> @@ -3098,6 +3102,7 @@ <translation id="4168015872538332605">Որոշ կարգավորումներ, որոնք պատկանում են <ph name="PRIMARY_EMAIL" />-ին, համօգտագործվում են ձեզ հետ: Այս կարգավորումները ներգործում են ձեր հաշվի վրա միայն բազմակի մուտքի ժամանակ:</translation> <translation id="4169535189173047238">Չեղարկել</translation> <translation id="4170314459383239649">Մաքրել ելնելիս</translation> +<translation id="417096670996204801">Ընտրեք պրոֆիլ</translation> <translation id="4175137578744761569">Բաց մանուշակագույն և սպիտակ</translation> <translation id="4175737294868205930">Հիմնական հիշողություն</translation> <translation id="4176463684765177261">Անջատված է</translation> @@ -3326,6 +3331,7 @@ <translation id="4444304522807523469">Մուտք գործել փաստաթղթի տեսածրիչներ, որոնց կցված են USB-ի կամ տեղային ցանցի միջոցով</translation> <translation id="4444512841222467874">Եթե չազատեք տարածք, օգտատերերն ու տվյալները կարող են ավտոմատ ջնջվել:</translation> <translation id="4446933390699670756">Հայելային</translation> +<translation id="4448914100439890108">Թաքցնել <ph name="USERNAME" /> հաշվի գաղտնաբառը <ph name="DOMAIN" /> տիրույթում</translation> <translation id="4449948729197510913">Ձեր օգտանունը պատկանում է ձեր կազմակերպության կորպորատիվ հաշվին։ Սարքերը հաշվում գրանցելու համար նախ հաստատեք տիրույթի պատկանելիությունը ադմինիստրատորի վահանակում։ Հաստատելու համար ձեզ անհրաժեշտ կլինեն հաշվի ադմինիստրատորի արտոնություններ։</translation> <translation id="4449996769074858870">Այս ներդիրը աուդիո ֆայլ է նվագարկում:</translation> <translation id="4450274068924249931">Ցուցադրում է լուսանկարներ, ժամը, եղանակը և նորություններ, երբ ձեր սարքն անգործուն ռեժիմում է։ Եթե միացնեք էկրանապահը, լիցքավորման ժամանակ էկրանը չի անջատվի։</translation> @@ -3850,6 +3856,7 @@ <translation id="5009463889040999939">Պրոֆիլը վերանվանվում է։ Դա կարող է մի քանի րոպե տևել։</translation> <translation id="5010043101506446253">Հավաստագրման կենտրոն</translation> <translation id="5015344424288992913">Պրոքսի-սերվերի լուծում…</translation> +<translation id="5016491575926936899">Դուք կարող եք համակարգչից SMS ուղարկել, համատեղ օգտագործել հեռախոսի բջջային թրաֆիկը, պատասխանել հաղորդագրությունների զրույցներում և հեռախոսի միջոցով ապակողպել ձեր <ph name="DEVICE_TYPE" /> սարքի էկրանը։<ph name="FOOTNOTE_POINTER" /> <ph name="LINK_BEGIN" />Իմանալ ավելին<ph name="LINK_END" /></translation> <translation id="5017643436812738274">Դուք կարող եք մեկ էջից անցնել մյուսը տեսքտի նշորդի միջոցով։ Անջատելու համար սեղմեք Ctrl + Search + 7։</translation> <translation id="5017828934289857214">Հիշեցնել ինձ ավելի ուշ</translation> <translation id="5018207570537526145">Բացել ընդլայնման կայքը</translation> @@ -4442,6 +4449,7 @@ <translation id="5638309510554459422">Գտեք ընդլայնումներ և թեմաներ <ph name="BEGIN_LINK" />Chrome Web Store<ph name="END_LINK" />-ում</translation> <translation id="5639549361331209298">Վերաբեռնել էջը (սեղմած պահեք՝ լրացուցիչ ընտրանքները տեսնելու համար)</translation> <translation id="5640133431808313291">Կառավարեք անվտանգության բանալիները</translation> +<translation id="5641608986289282154">Սկսեք օգտագործել <ph name="DEVICE_OS" />-ը</translation> <translation id="5642508497713047">CRL-ի ստորագրող</translation> <translation id="5643321261065707929">Վճարովի ինտերնետ</translation> <translation id="5643620609347735571">Մաքրել և շարունակել</translation> @@ -6097,7 +6105,6 @@ <translation id="7433708794692032816">Տեղադրեք խելացի քարտը, որպեսզի շարունակեք օգտվել <ph name="DEVICE_TYPE" /> սարքից</translation> <translation id="7433957986129316853">Պահպանել</translation> <translation id="7434509671034404296">Մշակողների համար</translation> -<translation id="7434635829372401939">Կարգավորումների համաժամացում</translation> <translation id="7434757724413878233">Մկնիկի արագացում</translation> <translation id="7434969625063495310">Չհաջողվեց ավելացնել տպման սերվերը։ Ստուգեք սերվերի կարգավորումները և նորից փորձեք։</translation> <translation id="7436921188514130341">Վերանվանման ժամանակ սխալ առաջացավ:</translation>
diff --git a/chrome/app/resources/generated_resources_id.xtb b/chrome/app/resources/generated_resources_id.xtb index 5a0ff17..8eaa3aa 100644 --- a/chrome/app/resources/generated_resources_id.xtb +++ b/chrome/app/resources/generated_resources_id.xtb
@@ -6093,7 +6093,6 @@ <translation id="7433708794692032816">Pasang kartu smart agar tetap menggunakan <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Simpan</translation> <translation id="7434509671034404296">Pengembang</translation> -<translation id="7434635829372401939">Sinkronkan setelan Anda</translation> <translation id="7434757724413878233">Akselerasi mouse</translation> <translation id="7434969625063495310">Tidak dapat menambahkan server cetak. Harap periksa konfigurasi server dan coba lagi.</translation> <translation id="7436921188514130341">Maaf. Terjadi error saat mengganti nama.</translation>
diff --git a/chrome/app/resources/generated_resources_is.xtb b/chrome/app/resources/generated_resources_is.xtb index c6eff2c..bcd93d3 100644 --- a/chrome/app/resources/generated_resources_is.xtb +++ b/chrome/app/resources/generated_resources_is.xtb
@@ -6109,7 +6109,6 @@ <translation id="7433708794692032816">Settu snjallkort í til að halda áfram að nota <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Halda henni</translation> <translation id="7434509671034404296">Forritarar</translation> -<translation id="7434635829372401939">Samstilla stillingar</translation> <translation id="7434757724413878233">Hröðun músar</translation> <translation id="7434969625063495310">Ekki var hægt að bæta við prentþjóni. Athugaðu stillingar þjónsins og reyndu aftur.</translation> <translation id="7436921188514130341">Úbbs! Villa kom upp við að breyta heiti.</translation>
diff --git a/chrome/app/resources/generated_resources_it.xtb b/chrome/app/resources/generated_resources_it.xtb index 6f81e70..7bfc93af 100644 --- a/chrome/app/resources/generated_resources_it.xtb +++ b/chrome/app/resources/generated_resources_it.xtb
@@ -597,6 +597,7 @@ <translation id="161042844686301425">Ciano</translation> <translation id="1611432201750675208">Il tuo dispositivo è bloccato</translation> <translation id="1612019740169791082">Il tuo contenitore non è configurato per supportare il ridimensionamento del disco. Per modificare la quantità di spazio riservata a Linux, effettua il backup e il ripristino in un nuovo contenitore.</translation> +<translation id="1613019471223620622">Mostra password per <ph name="USERNAME" /> su <ph name="DOMAIN" /></translation> <translation id="1614511179807650956">Potresti aver esaurito la tua quota di dati mobili. Visita il portale di attivazione <ph name="NAME" /> per acquistare altri dati.</translation> <translation id="161460670679785907">Impossibile rilevare il tuo telefono</translation> <translation id="1615337439947999338">Salva nel tuo Account Google (<ph name="EMAIL" />)</translation> @@ -1204,6 +1205,7 @@ <translation id="2220529011494928058">Segnala un problema</translation> <translation id="2220572644011485463">PIN o password</translation> <translation id="2221261048068091179"><ph name="FIRST_SWITCH" /> e <ph name="SECOND_SWITCH" /></translation> +<translation id="222201875806112242">Origine di contenuti multimediali senza nome</translation> <translation id="2224444042887712269">Questa impostazione appartiene a <ph name="OWNER_EMAIL" />.</translation> <translation id="222447520299472966">Deve essere selezionato almeno un album Galleria d'arte</translation> <translation id="2224551243087462610">Modifica nome cartella</translation> @@ -3325,6 +3327,7 @@ <translation id="4444304522807523469">Accesso a scanner di documenti aggiunti tramite USB o sulla rete locale</translation> <translation id="4444512841222467874">Se non viene liberato dello spazio, utenti e dati potrebbero essere rimossi automaticamente.</translation> <translation id="4446933390699670756">Speculare</translation> +<translation id="4448914100439890108">Nascondi password per <ph name="USERNAME" /> su <ph name="DOMAIN" /></translation> <translation id="4449948729197510913">Il tuo nome utente appartiene all'account aziendale della tua organizzazione. Per registrare dispositivi all'account, verifica innanzitutto la proprietà del dominio nella Console di amministrazione. Per la verifica, avrai bisogno dei privilegi di amministratore sull'account.</translation> <translation id="4449996769074858870">In questa scheda c'è audio in riproduzione.</translation> <translation id="4450274068924249931">Quando il tuo schermo è inattivo, mostra foto, ora, meteo e informazioni multimediali. L'attivazione del salvaschermo manterrà il display attivo durante la ricarica.</translation> @@ -3848,6 +3851,7 @@ <translation id="5009463889040999939">Ridenominazione del profilo in corso. Questa operazione può richiedere alcuni minuti.</translation> <translation id="5010043101506446253">Autorità di certificazione</translation> <translation id="5015344424288992913">Risoluzione proxy in corso...</translation> +<translation id="5016491575926936899">Puoi inviare SMS dal computer, condividere la connessione a Internet, rispondere a notifiche delle conversazioni e sbloccare <ph name="DEVICE_TYPE" /> con il telefono.<ph name="FOOTNOTE_POINTER" /> <ph name="LINK_BEGIN" />Scopri di più<ph name="LINK_END" /></translation> <translation id="5017643436812738274">Puoi spostarti da una pagina all'altra con un cursore di testo. Premi Ctrl + Cerca + 7 per disattivare l'opzione.</translation> <translation id="5017828934289857214">Ricordamelo dopo</translation> <translation id="5018207570537526145">Apri sito web dell'estensione</translation> @@ -4436,6 +4440,7 @@ <translation id="5638309510554459422">Trova estensioni e temi nel <ph name="BEGIN_LINK" />Chrome Web Store<ph name="END_LINK" /></translation> <translation id="5639549361331209298">Ricarica questa pagina, tieni premuto per visualizzare altre opzioni</translation> <translation id="5640133431808313291">Gestisci i token di sicurezza</translation> +<translation id="5641608986289282154">Inizia a usare <ph name="DEVICE_OS" /></translation> <translation id="5642508497713047">Firmatario CRL</translation> <translation id="5643321261065707929">Rete a consumo</translation> <translation id="5643620609347735571">Cancella e continua</translation> @@ -6089,7 +6094,6 @@ <translation id="7433708794692032816">Inserisci la smart card per continuare a utilizzare il tuo <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Mantieni</translation> <translation id="7434509671034404296">Opzioni per sviluppatori</translation> -<translation id="7434635829372401939">Sincronizza le impostazioni</translation> <translation id="7434757724413878233">Accelerazione del mouse</translation> <translation id="7434969625063495310">Impossibile aggiungere il server di stampa. Controlla la configurazione del server e riprova.</translation> <translation id="7436921188514130341">Uffa! Si è verificato un errore durante la ridenominazione.</translation>
diff --git a/chrome/app/resources/generated_resources_iw.xtb b/chrome/app/resources/generated_resources_iw.xtb index 9441195..08746f9 100644 --- a/chrome/app/resources/generated_resources_iw.xtb +++ b/chrome/app/resources/generated_resources_iw.xtb
@@ -2403,6 +2403,7 @@ <translation id="3449393517661170867">חלון מרובה כרטיסיות חדש</translation> <translation id="3449839693241009168">יש ללחוץ על <ph name="SEARCH_KEY" /> כדי לשלוח פקודות אל <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">אחוז תפוסה במצב לא פעיל</translation> +<translation id="3450180775417907283">כדי להיכנס אל <ph name="MANAGER" />, מתחברים עכשיו לרשת Wi-Fi ומורידים עדכון.</translation> <translation id="3451753556629288767">יש הרשאה לפתיחת סוגי קבצים</translation> <translation id="3452999110156026232">גישה של הורה</translation> <translation id="3453612417627951340">יש צורך באישור</translation> @@ -4269,6 +4270,7 @@ <translation id="5472627187093107397">שמירת סיסמאות עבור האתר הזה</translation> <translation id="5473075389972733037">IBM</translation> <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{קוד האימות חייב להיות באורך של תו אחד לפחות}two{קוד האימות חייב להיות באורך של # תווים לפחות}many{קוד האימות חייב להיות באורך של # תווים לפחות}other{קוד האימות חייב להיות באורך של # תווים לפחות}}</translation> +<translation id="5474859849784484111">כדי להיכנס אל <ph name="MANAGER" />, מתחברים עכשיו לרשת Wi-Fi ומורידים עדכון. ניתן גם לבצע את ההורדה דרך חיבור עם חיוב לפי שימוש בנתונים (עשויים לחול חיובים).</translation> <translation id="5481273127572794904">לא מורשים להוריד מספר קבצים באופן אוטומטי</translation> <translation id="5481941284378890518">הוספת מדפסות קרובות</translation> <translation id="5483785310822538350">ביטול גישה לקבצים ולמכשירים</translation> @@ -4692,6 +4694,7 @@ <translation id="592880897588170157">הורדת קובצי PDF במקום פתיחה אוטומטית שלהם ב-Chrome</translation> <translation id="592919310198008711">בלחיצה על התוסף</translation> <translation id="5932124097031739492">מערכת Linux שודרגה בהצלחה.</translation> +<translation id="5932209916647644605">כדי להיכנס אל <ph name="MANAGER" /> צריך לעדכן את <ph name="DEVICE_TYPE" /> באופן מיידי.</translation> <translation id="5932224571077948991">באתר מוצגות מודעות מפריעות או מטעות</translation> <translation id="59324397759951282">התקן USB של <ph name="MANUFACTURER_NAME" /></translation> <translation id="5932441198730183141">אין ברשותך מספיק רישיונות זמינים לשיוך המכשיר הזה ל-Google Meet. עליך לפנות למחלקת המכירות כדי לרכוש רישיונות נוספים. אם לדעתך ההודעה הזו מוצגת לך בטעות, אפשר לפנות לתמיכה.</translation> @@ -6095,7 +6098,6 @@ <translation id="7433708794692032816">יש להכניס את הכרטיס החכם כדי להמשיך להשתמש ב-<ph name="DEVICE_TYPE" /> שלך</translation> <translation id="7433957986129316853">שמירת השינוי</translation> <translation id="7434509671034404296">למפתחים</translation> -<translation id="7434635829372401939">סנכרון ההגדרות שלך</translation> <translation id="7434757724413878233">האצת עכבר</translation> <translation id="7434969625063495310">לא ניתן היה להוסיף את שרת ההדפסה. יש לבדוק את הגדרת השרת ולנסות שוב.</translation> <translation id="7436921188514130341">אופס! אירעה שגיאה במהלך שינוי השם.</translation>
diff --git a/chrome/app/resources/generated_resources_ja.xtb b/chrome/app/resources/generated_resources_ja.xtb index 39df8eb..9c6e1c86 100644 --- a/chrome/app/resources/generated_resources_ja.xtb +++ b/chrome/app/resources/generated_resources_ja.xtb
@@ -6084,7 +6084,6 @@ <translation id="7433708794692032816"><ph name="DEVICE_TYPE" /> を引き続き使用するにはスマートカードを挿入してください</translation> <translation id="7433957986129316853">そのままにする</translation> <translation id="7434509671034404296">開発 / 管理</translation> -<translation id="7434635829372401939">設定の同期</translation> <translation id="7434757724413878233">マウス アクセラレーション</translation> <translation id="7434969625063495310">プリント サーバーを追加できませんでした。サーバーの設定を確認してから、もう一度お試しください。</translation> <translation id="7436921188514130341">名前の変更中にエラーが発生しました。</translation>
diff --git a/chrome/app/resources/generated_resources_ka.xtb b/chrome/app/resources/generated_resources_ka.xtb index cfbebaf..ee5852f 100644 --- a/chrome/app/resources/generated_resources_ka.xtb +++ b/chrome/app/resources/generated_resources_ka.xtb
@@ -6101,7 +6101,6 @@ <translation id="7433708794692032816"><ph name="DEVICE_TYPE" /> კვლავ რომ გამოიყენოთ, ჩასვით სმარტ-ბარათი</translation> <translation id="7433957986129316853">შენარჩუნება</translation> <translation id="7434509671034404296">შემმუშავებელი</translation> -<translation id="7434635829372401939">თქვენი პარამეტრების სინქრონიზაცია</translation> <translation id="7434757724413878233">მაუსის აჩქარება</translation> <translation id="7434969625063495310">ბეჭდვის სერვერის დამატება ვერ მოხერხდა. შეამოწმეთ სერვერის კონფიგურაცია და ცადეთ ხელახლა.</translation> <translation id="7436921188514130341">სამწუხაროდ, გადარქმევა ვერ მოხერხდა შეცდომის გამო.</translation>
diff --git a/chrome/app/resources/generated_resources_kk.xtb b/chrome/app/resources/generated_resources_kk.xtb index d455be55..2c9ffda 100644 --- a/chrome/app/resources/generated_resources_kk.xtb +++ b/chrome/app/resources/generated_resources_kk.xtb
@@ -1214,6 +1214,7 @@ <translation id="2232751457155581899">Сайттар камераңыздың орнын қадағалауға рұқсат сұрай алады.</translation> <translation id="2232876851878324699">Бұл файлда импортталмаған бір сертификат қамтылған:</translation> <translation id="2233502537820838181">&Қосымша ақпарат</translation> +<translation id="223356358902285214">Интернет пен қолданбаларды пайдалану тарихы</translation> <translation id="2234876718134438132">Синхрондау және Google қызметтері</translation> <translation id="2235344399760031203">Үшінші тараптың cookie файлдары бөгелді</translation> <translation id="2238379619048995541">Жиілік күйі деректері</translation> @@ -1894,6 +1895,7 @@ <translation id="2923006468155067296"><ph name="DEVICE_TYPE" /> құрылғыңыз қазір құлыпталады. <ph name="DOMAIN" /> домені смарт картаңызды салып жүруіңізді талап етеді.</translation> <translation id="2923234477033317484">Бұл аккаунтты өшіру</translation> +<translation id="2923644930701689793">Телефон камерасының суреттер қалтасына кіру</translation> <translation id="2926085873880284723">Әдепкі таңбашаларды қалпына келтіру</translation> <translation id="2926620265753325858">"<ph name="DEVICE_NAME" />" құрылғысына қолдау көрсетілмейді.</translation> <translation id="2927017729816812676">Кэш жады</translation> @@ -3085,6 +3087,7 @@ <translation id="4168015872538332605"><ph name="PRIMARY_EMAIL" /> аккаунтына қатысты кейбір параметрлер сізбен бөлісілді. Бұл параметрлер бірнеше рет кіру кезінде ғана аккаунтқа әсер етеді.</translation> <translation id="4169535189173047238">Рұқсат бермеу</translation> <translation id="4170314459383239649">Шыққан кезде тазалау</translation> +<translation id="417096670996204801">Профиль таңдаңыз</translation> <translation id="4175137578744761569">Ашық күлгін және ақ</translation> <translation id="4175737294868205930">Тұрақты жад</translation> <translation id="4176463684765177261">Өшірілген</translation> @@ -3818,7 +3821,7 @@ <translation id="4992473555164495036">Әкімшіңіз қолжетімді енгізу әдістерінің санын шектеді.</translation> <translation id="4994474651455208930">Сайттардың протоколдар үшін әдепкі өңдегіш болуды сұрауына рұқсат беру</translation> <translation id="4994754230098574403">Реттелуде</translation> -<translation id="4995131849631312693"><ph name="BEGIN_PARAGRAPH1" />Тіркелуден бұрын TPM-ді тазартуыңыз керек, сонда <ph name="DEVICE_OS" /> құрылғыға иелік құқығын ала алады.<ph name="END_PARAGRAPH1" /> +<translation id="4995131849631312693"><ph name="BEGIN_PARAGRAPH1" />Тіркелуден бұрын TPM-ді тазартуыңыз керек, сонда <ph name="DEVICE_OS" /> құрылғыға меншік құқығын ала алады.<ph name="END_PARAGRAPH1" /> <ph name="BEGIN_PARAGRAPH2" />TPM құрылғысын толығымен өшіріп тастауға да болады. Деректеріңіз бағдарламалық құрал шифрлауымен қауіпсіз түрде сақтала береді, бірақ жабдық қолдауының сертификаттары сияқты кейбір қауіпсіздік функциялары өшіріледі.<ph name="END_PARAGRAPH2" /> <ph name="BEGIN_PARAGRAPH3" />Өшіріп қосып, жүйенің BIOS/UEFI параметрлеріне кіру арқылы TPM параметрлерін өзгерте аласыз. Орындалатын қадамдар құрылғы моделіне байланысты әртүрлі болады. Толығырақ ақпарат алу үшін өшіріп қоспас бұрын басқа құрылғыда <ph name="DEVICE_OS" /> құжаттамасын ашып алыңыз: [URL link]<ph name="END_PARAGRAPH3" /></translation> <translation id="4996851818599058005">{NUM_VMS,plural, =0{"<ph name="VM_TYPE" />" виртуалды машиналары табылмады.}=1{1 "<ph name="VM_TYPE" />" виртуалды машинасы табылды: <ph name="VM_NAME_LIST" />.}other{{NUM_VMS} "<ph name="VM_TYPE" />" виртуалды машинасы табылды: <ph name="VM_NAME_LIST" />.}}</translation> @@ -6070,7 +6073,6 @@ <translation id="7433708794692032816"><ph name="DEVICE_TYPE" /> құрылғысын пайдалана беру үшін смарт картаны салу</translation> <translation id="7433957986129316853">Сақтау</translation> <translation id="7434509671034404296">Әзірлеуші</translation> -<translation id="7434635829372401939">Параметрлерді синхрондау</translation> <translation id="7434757724413878233">Тінтуірді жылдамдату</translation> <translation id="7434969625063495310">Басып шығару сервері енгізілмеді. Сервер конфигурациясын тексеріп, қайталап көріңіз.</translation> <translation id="7436921188514130341">Қап! Атын өзгерту кезінде қате пайда болды.</translation>
diff --git a/chrome/app/resources/generated_resources_km.xtb b/chrome/app/resources/generated_resources_km.xtb index 931bf98d..7799766d 100644 --- a/chrome/app/resources/generated_resources_km.xtb +++ b/chrome/app/resources/generated_resources_km.xtb
@@ -6119,7 +6119,6 @@ <translation id="7433708794692032816">ដោតកាតឆ្លាតវៃ ដើម្បីបន្តប្រើ <ph name="DEVICE_TYPE" /> របស់អ្នក</translation> <translation id="7433957986129316853">រក្សាទុកវា</translation> <translation id="7434509671034404296">អ្នកអភិវឌ្ឍន៍</translation> -<translation id="7434635829372401939">ធ្វើសមកាលកម្មការកំណត់របស់អ្នក</translation> <translation id="7434757724413878233">ការបង្កើនល្បឿនកណ្ដុរ</translation> <translation id="7434969625063495310">មិនអាចបញ្ចូលម៉ាស៊ីនមេបោះពុម្ពបានទេ។ សូមពិនិត្យការកំណត់រចនាសម្ព័ន្ធរបស់ម៉ាស៊ីនមេ រួចព្យាយាមម្ដងទៀត។</translation> <translation id="7436921188514130341">អូ! មានបញ្ហាពេលកំពុងប្តូរឈ្មោះ។</translation>
diff --git a/chrome/app/resources/generated_resources_kn.xtb b/chrome/app/resources/generated_resources_kn.xtb index 54504c2..307e10d6 100644 --- a/chrome/app/resources/generated_resources_kn.xtb +++ b/chrome/app/resources/generated_resources_kn.xtb
@@ -1226,6 +1226,7 @@ <translation id="2232751457155581899">ಸೈಟ್ಗಳು ನಿಮ್ಮ ಕ್ಯಾಮರಾ ಸ್ಥಾನವನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು ಕೇಳಬಹುದು</translation> <translation id="2232876851878324699">ಫೈಲ್ ಆಮದು ಮಾಡದೆ ಇರುವಂತಹ ಒಂದು ಪ್ರಮಾಣಪತ್ರವನ್ನು ಒಳಗೊಂಡಿದೆ:</translation> <translation id="2233502537820838181">&ಹೆಚ್ಚಿನ ಮಾಹಿತಿ</translation> +<translation id="223356358902285214">ವೆಬ್ ಮತ್ತು ಆ್ಯಪ್ ಚಟುವಟಿಕೆ</translation> <translation id="2234876718134438132">ಸಿಂಕ್ ಮತ್ತು Google ಸೇವೆಗಳು</translation> <translation id="2235344399760031203">ಥರ್ಡ್-ಪಾರ್ಟಿ ಕುಕೀಗಳನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ</translation> <translation id="2238379619048995541">ಆವರ್ತನ ಸ್ಥಿತಿಯ ಡೇಟಾ</translation> @@ -1914,6 +1915,7 @@ <translation id="2923006468155067296">ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ಅನ್ನು ಈಗ ಲಾಕ್ ಮಾಡಲಾಗುತ್ತದೆ. <ph name="DOMAIN" />, ನಿಮ್ಮ ಸ್ಮಾರ್ಟ್ ಕಾರ್ಡ್ ಅನ್ನು ಸೇರಿಸಬೇಕೆಂದು ಬಯಸುತ್ತದೆ.</translation> <translation id="2923234477033317484">ಈ ಖಾತೆಯನ್ನು ತೆಗೆದುಹಾಕಿ</translation> +<translation id="2923644930701689793">ನಿಮ್ಮ ಫೋನ್ನ ಕ್ಯಾಮರಾ ರೋಲ್ ಅನ್ನು ಪ್ರವೇಶಿಸಿ</translation> <translation id="2926085873880284723">ಡಿಫಾಲ್ಟ್ ಶಾರ್ಟ್ಕಟ್ಗಳನ್ನು ಮರುಸ್ಥಾಪಿಸಿ</translation> <translation id="2926620265753325858"><ph name="DEVICE_NAME" /> ಬೆಂಬಲಿತವಾಗಿಲ್ಲ.</translation> <translation id="2927017729816812676">ಕ್ಯಾಷ್ ಸಂಗ್ರಹಣೆ</translation> @@ -2354,6 +2356,7 @@ <translation id="3413122095806433232">CA ನೀಡುವವರು: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">ಗಾತ್ರ:</translation> <translation id="3414966631182382431">ನಿಮ್ಮ <ph name="BEGIN_LINK" />ಬ್ರೌಸರ್ ಅನ್ನು<ph name="END_LINK" /> <ph name="MANAGER" /> ನಿರ್ವಹಿಸುತ್ತಿದೆ</translation> +<translation id="341589277604221596">ಲೈವ್ ಕ್ಯಾಪ್ಶನ್ - <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">ಯಾವಾಗಲೂ ಪೂರ್ಣ URL ಗಳನ್ನು ತೋರಿಸಿ</translation> <translation id="3417835166382867856">ಟ್ಯಾಬ್ಗಳನ್ನು ಹುಡುಕಿ</translation> <translation id="3417836307470882032">24-ಗಂಟೆಯ ಗಡಿಯಾರ ಬಳಸಿ</translation> @@ -3107,6 +3110,7 @@ <translation id="4168015872538332605"><ph name="PRIMARY_EMAIL" /> ಸೇರಿದಂತಹ ಕೆಲವು ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ನಿಮ್ಮೊಂದಿಗೆ ಹಂಚಿಕೊಳ್ಳಲಾಗಿದೆ. ಬಹು ಸೈನ್-ಇನ್ ಬಳಸುವಾಗ ಮಾತ್ರ ಈ ಸೆಟ್ಟಿಂಗ್ಗಳು ನಿಮ್ಮ ಖಾತೆಯ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರುತ್ತವೆ.</translation> <translation id="4169535189173047238">ಅನುಮತಿಸಬೇಡಿ</translation> <translation id="4170314459383239649">ನಿರ್ಗಮಿಸುವಲ್ಲಿ ತೆರವುಗೊಳಿಸಿ</translation> +<translation id="417096670996204801">ಪ್ರೊಫೈಲ್ ಅನ್ನು ಆರಿಸಿ</translation> <translation id="4175137578744761569">ತಿಳಿ ನೇರಳೆ ಮತ್ತು ಬಿಳಿ</translation> <translation id="4175737294868205930">ಶಾಶ್ವತವಾಗಿರುವ ಸಂಗ್ರಹಣೆ</translation> <translation id="4176463684765177261">ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ</translation> @@ -6109,7 +6113,6 @@ <translation id="7433708794692032816">ನಿಮ್ಮ <ph name="DEVICE_TYPE" /> ಬಳಕೆಯನ್ನು ಮುಂದುವರಿಸಲು ಸ್ಮಾರ್ಟ್ ಕಾರ್ಡ್ ಸೇರಿಸಿ</translation> <translation id="7433957986129316853">ಇರಲಿ ಬಿಡಿ</translation> <translation id="7434509671034404296">ಡೆವಲಪರ್</translation> -<translation id="7434635829372401939">ನಿಮ್ಮ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಸಿಂಕ್ ಮಾಡಿ</translation> <translation id="7434757724413878233">ಮೌಸ್ ವೇಗವರ್ಧನೆ</translation> <translation id="7434969625063495310">ಪ್ರಿಂಟ್ ಸರ್ವರ್ ಅನ್ನು ಸೇರಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ಸರ್ವರ್ನ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ಪರಿಶೀಲಿಸಿ ಮತ್ತು ಪುನಃ ಪ್ರಯತ್ನಿಸಿ.</translation> <translation id="7436921188514130341">ಓಹ್, ಹೋಯ್ತು! ಮರುಹೆಸರಿಸುವ ಸಂದರ್ಭದಲ್ಲಿ ದೋಷ ಕಂಡುಬಂದಿದೆ.</translation> @@ -7188,6 +7191,7 @@ <translation id="8540136935098276800">ಸರಿಯಾಗಿ ಫಾರ್ಮ್ಯಾಟ್ ಮಾಡಲಾದ URL ಅನ್ನು ನಮೂದಿಸಿ</translation> <translation id="8540503336857689453">ಭದ್ರತಾ ಕಾರಣಗಳಿಗಾಗಿ ಮರೆಮಾಡಿರುವ ನೆಟ್ವರ್ಕ್ ಬಳಸುವುದನ್ನು ಶಿಫಾರಸು ಮಾಡುವುದಿಲ್ಲ.</translation> <translation id="854071720451629801">ಓದಿದಂತೆ ಗುರುತಿಸಿ</translation> +<translation id="8540942859441851323">ಪೂರೈಕೆದಾರರು ರೋಮಿಂಗ್ ಸೌಲಭ್ಯ ಒದಗಿಸುವ ಅಗತ್ಯವಿದೆ</translation> <translation id="8541462173655894684">ಪ್ರಿಂಟ್ ಸರ್ವರ್ನಿಂದ ಯಾವುದೇ ಪ್ರಿಂಟರ್ಗಳು ಕಂಡುಬಂದಿಲ್ಲ</translation> <translation id="8541838361296720865">ಇದನ್ನು “<ph name="ACTION" />” ಗೆ ನಿಯೋಜಿಸಲು ಸ್ವಿಚ್ ಅಥವಾ ಕೀಬೋರ್ಡ್ ಕೀಯನ್ನು ಒತ್ತಿ</translation> <translation id="8542618328173222274">ನಿಮ್ಮ ವರ್ಚುವಲ್ ರಿಯಾಲಿಟಿ ಸಾಧನಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಬಳಸಲು ಸೈಟ್ ಬಯಸಿದಾಗ, ಕೇಳಿ</translation>
diff --git a/chrome/app/resources/generated_resources_ko.xtb b/chrome/app/resources/generated_resources_ko.xtb index 991e115..9d8184f 100644 --- a/chrome/app/resources/generated_resources_ko.xtb +++ b/chrome/app/resources/generated_resources_ko.xtb
@@ -6112,7 +6112,6 @@ <translation id="7433708794692032816"><ph name="DEVICE_TYPE" /> 기기를 계속 사용하려면 스마트 카드 삽입</translation> <translation id="7433957986129316853">유지</translation> <translation id="7434509671034404296">개발자 정보</translation> -<translation id="7434635829372401939">설정 동기화</translation> <translation id="7434757724413878233">마우스 가속</translation> <translation id="7434969625063495310">인쇄 서버를 추가할 수 없습니다. 서버 설정을 확인하고 다시 시도해 보세요.</translation> <translation id="7436921188514130341">이름 변경 중에 오류가 발생했습니다.</translation>
diff --git a/chrome/app/resources/generated_resources_ky.xtb b/chrome/app/resources/generated_resources_ky.xtb index 51ed3f0..799bd95 100644 --- a/chrome/app/resources/generated_resources_ky.xtb +++ b/chrome/app/resources/generated_resources_ky.xtb
@@ -2364,6 +2364,7 @@ <translation id="3413122095806433232">Тастыктама берүүчүлөр: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">Өлчөм:</translation> <translation id="3414966631182382431"><ph name="BEGIN_LINK" />Серепчиңиз<ph name="END_LINK" /> <ph name="MANAGER" /> тарабынан башкарылууда</translation> +<translation id="341589277604221596">Ыкчам коштомо жазуулар — <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">URL'дер ар дайым толугу менен көрүнсүн</translation> <translation id="3417835166382867856">Өтмөктөрдү издөө</translation> <translation id="3417836307470882032">24 сааттык убакыт</translation> @@ -6117,7 +6118,6 @@ <translation id="7433708794692032816"><ph name="DEVICE_TYPE" /> түзмөгүңүздү колдонууну улантуу үчүн акылдуу картаны салыңыз</translation> <translation id="7433957986129316853">Жок, кала берсин</translation> <translation id="7434509671034404296">Иштеп чыгуучу</translation> -<translation id="7434635829372401939">Жөндөөлөрдү шайкештирүү</translation> <translation id="7434757724413878233">Чычканды ылдамдаткыч</translation> <translation id="7434969625063495310">Басып чыгаруу сервери кошулган жок. Сервердин конфигурациясын текшерип, кайталап көрүңүз.</translation> <translation id="7436921188514130341">Ка-ап! Аталышы өзгөртүлүп жатканда ката кетти.</translation> @@ -7199,6 +7199,7 @@ <translation id="8540136935098276800">Туура форматталган URL дарегин киргизиңиз</translation> <translation id="8540503336857689453">Жашыруун тармакты колдонуу коопсуздук максатында сунушталбайт.</translation> <translation id="854071720451629801">Окулган деп белгилөө</translation> +<translation id="8540942859441851323">Провайдер роумингди иштетүүнү талап кылат</translation> <translation id="8541462173655894684">Басып чыгаруу серверинде бир да принтер табылган жок</translation> <translation id="8541838361296720865">Которгучту же баскычтоптогу баскычты “<ph name="ACTION" />” аракетине дайындоо үчүн аны таптаңыз</translation> <translation id="8542618328173222274">Сайт виртуалдык чындык түзмөктөрүңүздү жана дайын-даректериңизди колдонгону жатканда уруксат сурасын</translation>
diff --git a/chrome/app/resources/generated_resources_lo.xtb b/chrome/app/resources/generated_resources_lo.xtb index 6730f05..99aa9b1 100644 --- a/chrome/app/resources/generated_resources_lo.xtb +++ b/chrome/app/resources/generated_resources_lo.xtb
@@ -2357,6 +2357,7 @@ <translation id="3413122095806433232">ຜູ້ອອກ CA: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">ຂະໜາດ:</translation> <translation id="3414966631182382431"><ph name="BEGIN_LINK" />ໂປຣແກຣມທ່ອງເວັບຂອງທ່ານຖືກຈັດການ<ph name="END_LINK" /> ໂດຍ <ph name="MANAGER" /></translation> +<translation id="341589277604221596">ຄຳບັນຍາຍສົດ - <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">ສະແດງ URL ເຕັມທຸກເທື່ອ</translation> <translation id="3417835166382867856">ຊອກຫາແຖບ</translation> <translation id="3417836307470882032">ເວລາແບບ 24 ຊົ່ວໂມງ</translation> @@ -6105,7 +6106,6 @@ <translation id="7433708794692032816">ສຽບບັດອັດສະລິຍະເພື່ອສືບຕໍ່ໃຊ້ <ph name="DEVICE_TYPE" /> ຂອງທ່ານ</translation> <translation id="7433957986129316853">ເກັບໄວ້</translation> <translation id="7434509671034404296">ຜູ້ພັດທະນາ</translation> -<translation id="7434635829372401939">ຊິ້ງຂໍ້ມູນການຕັ້ງຄ່າຂອງທ່ານ</translation> <translation id="7434757724413878233">ການເລັ່ງຄວາມໄວເມົ້າ</translation> <translation id="7434969625063495310">ບໍ່ສາມາດເພີ່ມເຊີບເວີການພິມໄດ້. ກະລຸນາກວດເບິ່ງການຕັ້ງຄ່າເຊີບເວີ ແລ້ວລອງໃໝ່.</translation> <translation id="7436921188514130341">ໂອ໋ຍ, ໂຊກຮ້າຍແທ້! ເກີດຄວາມຜິດພາດຂຶ້ນໃນເວລາປ່ຽນຊື່.</translation> @@ -7186,6 +7186,7 @@ <translation id="8540136935098276800">ປ້ອນ URL ທີ່ມີຮູບແບບຖືກຕ້ອງ</translation> <translation id="8540503336857689453">ການໃຊ້ເຄືອຂ່າຍທີ່ຖືກເຊື່ອງໄວ້ແມ່ນບໍ່ແນະນຳເນື່ອງຈາກເຫດຜົນດ້ານຄວາມປອດໄພ.</translation> <translation id="854071720451629801">ໝາຍວ່າອ່ານແລ້ວ</translation> +<translation id="8540942859441851323">ຜູ້ໃຫ້ບໍລິການບັງຄັບໃຫ້ໃຊ້ໂຣມມິງ</translation> <translation id="8541462173655894684">ຊອກບໍ່ເຫັນເຄື່ອງພິມໃດໆຈາກເຊີບເວີການພິມ</translation> <translation id="8541838361296720865">ກົດສະວິດ ຫຼື ປຸ່ມແປ້ນພິມໃດໜຶ່ງເພື່ອມອບໝາຍມັນເປັນ “<ph name="ACTION" />”</translation> <translation id="8542618328173222274">ຖາມເມື່ອເວັບໄຊຕ້ອງການໃຊ້ອຸປະກອນ ແລະ ຂໍ້ມູນເວີຊົວ ຣິອາລິຕີຂອງທ່ານ</translation>
diff --git a/chrome/app/resources/generated_resources_lt.xtb b/chrome/app/resources/generated_resources_lt.xtb index 2f4de4cd..e757206 100644 --- a/chrome/app/resources/generated_resources_lt.xtb +++ b/chrome/app/resources/generated_resources_lt.xtb
@@ -6118,7 +6118,6 @@ <translation id="7433708794692032816">Įdėkite išmaniąją kortelę, kad galėtumėte toliau naudoti „<ph name="DEVICE_TYPE" />“ įrenginį</translation> <translation id="7433957986129316853">Palikti</translation> <translation id="7434509671034404296">Vykdymo programa</translation> -<translation id="7434635829372401939">Nustatymų sinchronizavimas</translation> <translation id="7434757724413878233">Pelės spartinimas</translation> <translation id="7434969625063495310">Nepavyko pridėti spausdinimo serverio. Patikrinkite serverio konfigūraciją ir bandykite dar kartą.</translation> <translation id="7436921188514130341">Oi, pervardijant įvyko klaida.</translation>
diff --git a/chrome/app/resources/generated_resources_lv.xtb b/chrome/app/resources/generated_resources_lv.xtb index b9c7905..9f5da8454 100644 --- a/chrome/app/resources/generated_resources_lv.xtb +++ b/chrome/app/resources/generated_resources_lv.xtb
@@ -6097,7 +6097,6 @@ <translation id="7433708794692032816">Lai jūs varētu turpināt izmantot savu <ph name="DEVICE_TYPE" /> ierīci, ievietojiet viedkarti</translation> <translation id="7433957986129316853">Paturēt</translation> <translation id="7434509671034404296">Izstrādātājs</translation> -<translation id="7434635829372401939">Iestatījumu sinhronizācija</translation> <translation id="7434757724413878233">Peles darbības paātrinājums</translation> <translation id="7434969625063495310">Nevarēja pievienot drukas serveri. Lūdzu, pārbaudiet servera konfigurāciju un mēģiniet vēlreiz.</translation> <translation id="7436921188514130341">Diemžēl pārdēvēšanas laikā radās kļūda.</translation>
diff --git a/chrome/app/resources/generated_resources_mk.xtb b/chrome/app/resources/generated_resources_mk.xtb index 022df73..a943043 100644 --- a/chrome/app/resources/generated_resources_mk.xtb +++ b/chrome/app/resources/generated_resources_mk.xtb
@@ -600,6 +600,7 @@ <translation id="161042844686301425">Тиркизна</translation> <translation id="1611432201750675208">Уредот е заклучен</translation> <translation id="1612019740169791082">Вашиот контејнер не е конфигуриран да поддржува промени на големината на дискот. За да го приспособите количеството простор што е резервирано за Linux, направете бекап, па вратете го во нов контејнер.</translation> +<translation id="1613019471223620622">Прикажи ја лозинката за <ph name="USERNAME" /> на <ph name="DOMAIN" /></translation> <translation id="1614511179807650956">Можно е да сте го искористиле доделениот мобилен интернет. Посетете го порталот за активација на <ph name="NAME" /> за да купите уште мобилен интернет</translation> <translation id="161460670679785907">Не може да се открие вашиот телефон</translation> <translation id="1615337439947999338">Зачувајте во вашата сметка на Google (<ph name="EMAIL" />)</translation> @@ -1216,6 +1217,7 @@ <translation id="2220529011494928058">Пријави проблем</translation> <translation id="2220572644011485463">PIN или лозинка</translation> <translation id="2221261048068091179"><ph name="FIRST_SWITCH" /> <ph name="SECOND_SWITCH" /></translation> +<translation id="222201875806112242">Неименуван извор на аудиовизуелни содржини</translation> <translation id="2224444042887712269">Оваа поставка припаѓа на <ph name="OWNER_EMAIL" />.</translation> <translation id="222447520299472966">Треба да се избере минимум еден албум во „Уметничката галерија“</translation> <translation id="2224551243087462610">Измени име на папка</translation> @@ -3344,6 +3346,7 @@ <translation id="4444304522807523469">Пристап до скенери за документи поврзани преку USB или на локалната мрежа</translation> <translation id="4444512841222467874">Ако не се ослободи простор, автоматски може да се отстранат корисници и податоци.</translation> <translation id="4446933390699670756">Отсликано</translation> +<translation id="4448914100439890108">Сокриј ја лозинката за <ph name="USERNAME" /> на <ph name="DOMAIN" /></translation> <translation id="4449948729197510913">Вашето корисничко име е сопственост на работната сметка на вашата организација. За регистрирање на уредите во сметката, прво треба да ја потврдите сопственоста на доменот во администрациската конзола. За таа цел, ќе ви требаат административни привилегии на сметката.</translation> <translation id="4449996769074858870">Оваа картичка репродуцира аудио.</translation> <translation id="4450274068924249931">Кога екранот е неактивен, прикажувај фотографии, време, временска прогноза и вести. Ако го овозможите „Штедачот на екранот“, екранот ќе остане вклучен при полнење.</translation> @@ -3868,6 +3871,7 @@ <translation id="5009463889040999939">Се преименува профилот. Може да потрае неколку минути.</translation> <translation id="5010043101506446253">Орган за сертификати</translation> <translation id="5015344424288992913">Разрешување прокси...</translation> +<translation id="5016491575926936899">Може да испраќате пораки од компјутерот, да ја споделувате интернет-врската, да одговарате на известувањата од разговорите, да го отклучувате вашиот <ph name="DEVICE_TYPE" /> со телефонот.<ph name="FOOTNOTE_POINTER" /> <ph name="LINK_BEGIN" />Дознајте повеќе<ph name="LINK_END" /></translation> <translation id="5017643436812738274">Може да се движите низ страниците со курсорот за текст. Притиснете Ctrl+Пребарување+7 за да исклучите.</translation> <translation id="5017828934289857214">Потсети ме подоцна</translation> <translation id="5018207570537526145">Отвори веб-сајт со екстензии</translation> @@ -4458,6 +4462,7 @@ <translation id="5638309510554459422">Најдете екстензии и теми во <ph name="BEGIN_LINK" />Веб-продавницата на Chrome<ph name="END_LINK" /></translation> <translation id="5639549361331209298">Повторно вчитај ја страницава, задржи за приказ на повеќе опции</translation> <translation id="5640133431808313291">Управувајте со безбедносните клучеви</translation> +<translation id="5641608986289282154">Започнете да користите <ph name="DEVICE_OS" /></translation> <translation id="5642508497713047">CRL-пријавувач</translation> <translation id="5643321261065707929">Мрежа со мерен сообраќај</translation> <translation id="5643620609347735571">Исчисти и продолжи</translation> @@ -6113,7 +6118,6 @@ <translation id="7433708794692032816">Вметнете паметна картичка за да продолжите да го користите вашиот <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Задржи</translation> <translation id="7434509671034404296">Програмер</translation> -<translation id="7434635829372401939">Синхронизирајте ги поставките</translation> <translation id="7434757724413878233">Забрзување на глувчето</translation> <translation id="7434969625063495310">Не може да се додаде серверот за печатење. Проверете ја конфигурацијата на серверот и обидете се повторно.</translation> <translation id="7436921188514130341">Да му се сневиди! Настана грешка за време на форматирањето.</translation>
diff --git a/chrome/app/resources/generated_resources_ml.xtb b/chrome/app/resources/generated_resources_ml.xtb index 0e2f0ba..ae55ed88 100644 --- a/chrome/app/resources/generated_resources_ml.xtb +++ b/chrome/app/resources/generated_resources_ml.xtb
@@ -214,7 +214,7 @@ <translation id="120368089816228251">മ്യൂസിക് നോട്ട്</translation> <translation id="1203942045716040624">ഷെയേർഡ് വർക്കർ: <ph name="SCRIPT_URL" /></translation> <translation id="1211769675100312947">കുറുക്കുവഴികൾ നിങ്ങൾ ക്യുറേറ്റ് ചെയ്തവയാണ്</translation> -<translation id="1213254615020057352">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ സ്വയമേവ Google-ന് അയച്ച്, കുട്ടിയുടെ Android അനുഭവം മെച്ചപ്പെടുത്താൻ സഹായിക്കുക. നിങ്ങളുടെ കുട്ടിയെ തിരിച്ചറിയാൻ ഇത് ഉപയോഗിക്കില്ല, സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് സഹായിക്കുകയും ചെയ്യും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. ഈ ക്രമീകരണം നടപ്പിലാക്കിയിരിക്കുന്നത് ഉടമയാണ്. ഈ ഉപകരണത്തിലെ പ്രശ്നനിർണ്ണയവും ഉപയോഗവുമായി ബന്ധപ്പെട്ട ഡാറ്റയും Google-ന് അയയ്ക്കാൻ ഉടമ തീരുമാനിച്ചേക്കാം. നിങ്ങളുടെ കുട്ടിയുടെ അധിക വെബ്, ആപ്പ് പ്രവർത്തന ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ അവരുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> +<translation id="1213254615020057352">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ സ്വയമേവ Google-ന് അയച്ച്, കുട്ടിയുടെ Android അനുഭവം മെച്ചപ്പെടുത്താൻ സഹായിക്കുക. നിങ്ങളുടെ കുട്ടിയെ തിരിച്ചറിയാൻ ഇത് ഉപയോഗിക്കില്ല, സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് സഹായിക്കുകയും ചെയ്യും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. ഈ ക്രമീകരണം നടപ്പിലാക്കിയിരിക്കുന്നത് ഉടമയാണ്. ഈ ഉപകരണത്തിലെ പ്രശ്നനിർണ്ണയവും ഉപയോഗവുമായി ബന്ധപ്പെട്ട ഡാറ്റയും Google-ന് അയയ്ക്കാൻ ഉടമ തീരുമാനിച്ചേക്കാം. നിങ്ങളുടെ കുട്ടിയുടെ അധിക വെബ്, ആപ്പ് ആക്റ്റിവിറ്റി ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ അവരുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> <translation id="121384500095351701">ഈ ഫയൽ സുരക്ഷിതമായി ഡൗൺലോഡ് ചെയ്യാനാവില്ല</translation> <translation id="1215411991991485844">പുതിയ പശ്ചാത്തല ആപ്പ് ചേർത്തു</translation> <translation id="1216542092748365687">ഫിംഗർപ്രിന്റ് നീക്കം ചെയ്യുക</translation> @@ -1339,7 +1339,7 @@ <translation id="2348729153658512593"><ph name="WINDOW_TITLE" /> - അനുമതി അഭ്യർത്ഥിച്ചു, പ്രതികരിക്കാൻ Ctrl + Forward അമർത്തുക</translation> <translation id="234889437187286781">ഡാറ്റ ലോഡ് ചെയ്യുന്നതിൽ പിശക്</translation> <translation id="2349610121459545414">നിങ്ങളുടെ ലൊക്കേഷൻ ആക്സസ് ചെയ്യാൻ ഈ സൈറ്റിനെ അനുവദിക്കുന്നത് തുടരുക</translation> -<translation id="2349896577940037438">നിങ്ങളുടെ അധിക വെബ്, ആപ്പ് പ്രവർത്തനം ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം. account.google.com സന്ദർശിച്ച്, ഡാറ്റ കാണുകയും ഇല്ലാതാക്കുകയും നിങ്ങളുടെ അക്കൗണ്ട് ക്രമീകരണം മാറ്റുകയും ചെയ്യാവുന്നതാണ്.</translation> +<translation id="2349896577940037438">നിങ്ങളുടെ അധിക വെബ്, ആപ്പ് ആക്റ്റിവിറ്റി ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം. account.google.com സന്ദർശിച്ച്, ഡാറ്റ കാണുകയും ഇല്ലാതാക്കുകയും നിങ്ങളുടെ അക്കൗണ്ട് ക്രമീകരണം മാറ്റുകയും ചെയ്യാവുന്നതാണ്.</translation> <translation id="2350133097354918058">റീലോഡ് ചെയ്തു</translation> <translation id="2350182423316644347">ആപ്പ് സമാരംഭിക്കുന്നു...</translation> <translation id="2350796302381711542"><ph name="REPLACED_HANDLER_TITLE" /> എന്നതിനുപകരം എല്ലാ <ph name="PROTOCOL" /> ലിങ്കുകളും തുറക്കാൻ <ph name="HANDLER_HOSTNAME" /> എന്നതിനെ അനുവദിക്കണോ?</translation> @@ -2371,7 +2371,7 @@ <translation id="3432762828853624962">പങ്കിട്ട വർക്കർമാർ</translation> <translation id="3433621910545056227">ക്ഷമിക്കണം! ഉപകരണ ഇൻസ്റ്റലേഷൻ-സമയ ആട്രിബ്യൂട്ട് ലോക്ക് സ്ഥാപിക്കുന്നതിൽ സിസ്റ്റം പരാജയപ്പെട്ടു.</translation> <translation id="3434107140712555581">ബാറ്ററി: <ph name="BATTERY_PERCENTAGE" />%</translation> -<translation id="3434272557872943250">നിങ്ങളുടെ കുട്ടിയുടെ അധിക വെബ്, ആപ്പ് പ്രവർത്തന ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ അവരുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം. ഈ ക്രമീകരണത്തെ കുറിച്ചും അതെങ്ങനെയാണ് ക്രമപ്പെടുത്തുന്നത് എന്നതിനെ കുറിച്ചും families.google.com എന്നതിൽ കൂടുതലറിയുക.</translation> +<translation id="3434272557872943250">നിങ്ങളുടെ കുട്ടിയുടെ അധിക വെബ്, ആപ്പ് ആക്റ്റിവിറ്റി ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ അവരുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം. ഈ ക്രമീകരണത്തെ കുറിച്ചും അതെങ്ങനെയാണ് ക്രമപ്പെടുത്തുന്നത് എന്നതിനെ കുറിച്ചും families.google.com എന്നതിൽ കൂടുതലറിയുക.</translation> <translation id="3435688026795609344">"<ph name="EXTENSION_NAME" />" നിങ്ങളുടെ <ph name="CODE_TYPE" /> അഭ്യർത്ഥിക്കുന്നു</translation> <translation id="3435738964857648380">സുരക്ഷ</translation> <translation id="343578350365773421">പേപ്പറില്ല</translation> @@ -3857,7 +3857,7 @@ <translation id="5017643436812738274">ടെക്സ്റ്റ് കഴ്സർ ഉപയോഗിച്ച് നിങ്ങൾക്ക് പേജുകൾക്കിടയിൽ നാവിഗേറ്റ് ചെയ്യാനാകും. ഓഫാക്കാൻ Ctrl+Search+7 അമർത്തുക.</translation> <translation id="5017828934289857214">പിന്നീട് ഓർമ്മിപ്പിക്കുക</translation> <translation id="5018207570537526145">വിപുലീകരണ വെബ്സൈറ്റ് തുറക്കുക</translation> -<translation id="5018526990965779848">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ സ്വയമേവ Google-ന് അയച്ച്, നിങ്ങളുടെ Android അനുഭവം മെച്ചപ്പെടുത്താൻ സഹായിക്കുക. സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് ഇത് സഹായിക്കും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. നിങ്ങളുടെ അധിക വെബ്, ആപ്പ് പ്രവർത്തനം ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> +<translation id="5018526990965779848">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ സ്വയമേവ Google-ന് അയച്ച്, നിങ്ങളുടെ Android അനുഭവം മെച്ചപ്പെടുത്താൻ സഹായിക്കുക. സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് ഇത് സഹായിക്കും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. നിങ്ങളുടെ അധിക വെബ്, ആപ്പ് ആക്റ്റിവിറ്റി ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> <translation id="5021750053540820849">ഇതുവരെ അപ്ഡേറ്റ് ചെയ്തിട്ടില്ല</translation> <translation id="5026492829171796515">Google അക്കൗണ്ട് ചേർക്കാൻ സൈൻ ഇൻ ചെയ്യുക</translation> <translation id="5026806129670917316">വൈഫൈ ഓണാക്കുക</translation> @@ -4019,7 +4019,7 @@ <translation id="5193988420012215838">നിങ്ങളുടെ ക്ലിപ്പ്ബോർഡിലേക്ക് പകർത്തി</translation> <translation id="5194256020863090856">ഇത് അദൃശ്യ വിൻഡോകളെ മാത്രമേ ബാധിക്കൂ</translation> <translation id="5197255632782567636">ഇന്റര്നെറ്റ്</translation> -<translation id="5198430103906431024">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഈ ഉപകരണം നിലവിൽ സ്വയമേവ Google-ന് അയയ്ക്കുന്നുണ്ട്. സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് ഇത് സഹായിക്കും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. നിങ്ങളുടെ അധിക വെബ്, ആപ്പ് പ്രവർത്തനം ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> +<translation id="5198430103906431024">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഈ ഉപകരണം നിലവിൽ സ്വയമേവ Google-ന് അയയ്ക്കുന്നുണ്ട്. സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് ഇത് സഹായിക്കും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. നിങ്ങളുടെ അധിക വെബ്, ആപ്പ് ആക്റ്റിവിറ്റി ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> <translation id="5199729219167945352">പരീക്ഷണങ്ങള്</translation> <translation id="5203920255089865054">{NUM_EXTENSIONS,plural, =1{വിപുലീകരണം കാണാൻ ക്ലിക്ക് ചെയ്യുക}other{ഈ വിപുലീകരണങ്ങൾ കാണാൻ ക്ലിക്ക് ചെയ്യുക}}</translation> <translation id="5204673965307125349">ഉപകരണം Powerwash ചെയ്ത ശേഷം വീണ്ടും ശ്രമിക്കുക.</translation> @@ -5561,7 +5561,7 @@ <translation id="6848388270925200958">ഇപ്പോൾ, ഈ ഉപകരണത്തിൽ മാത്രം ഉപയോഗിക്കാനാവുന്ന ചില കാർഡുകൾ നിങ്ങൾക്കുണ്ട്</translation> <translation id="6848716236260083778">ഫിംഗർപ്രിന്റ് സജ്ജീകരിക്കാൻ, വിരലടയാള സെൻസറിൽ സ്പർശിക്കാൻ നിങ്ങളുടെ കുട്ടിയോട് ആവശ്യപ്പെടുക. നിങ്ങളുടെ കുട്ടിയുടെ ഫിംഗർപ്രിന്റ് ഡാറ്റ <ph name="DEVICE_TYPE" /> എന്നതിൽ സുരക്ഷിതമായി സംഭരിക്കുന്നു, ഒരിക്കലും ഇതിൽ നിന്ന് പുറത്ത് പോകില്ല.</translation> <translation id="6850286078059909152">ടെക്സ്റ്റ് വർണ്ണം</translation> -<translation id="6851181413209322061">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഈ ഉപകരണം നിലവിൽ സ്വയമേവ Google-ന് അയയ്ക്കുന്നുണ്ട്. നിങ്ങളുടെ കുട്ടിയെ തിരിച്ചറിയാൻ ഇത് ഉപയോഗിക്കില്ല, സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് സഹായിക്കുകയും ചെയ്യും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. ഈ ക്രമീകരണം നടപ്പിലാക്കിയിരിക്കുന്നത് ഉടമയാണ്. കുട്ടിയുടെ അധിക വെബ്, ആപ്പ് പ്രവർത്തനം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ അവരുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> +<translation id="6851181413209322061">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഈ ഉപകരണം നിലവിൽ സ്വയമേവ Google-ന് അയയ്ക്കുന്നുണ്ട്. നിങ്ങളുടെ കുട്ടിയെ തിരിച്ചറിയാൻ ഇത് ഉപയോഗിക്കില്ല, സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് സഹായിക്കുകയും ചെയ്യും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. ഈ ക്രമീകരണം നടപ്പിലാക്കിയിരിക്കുന്നത് ഉടമയാണ്. കുട്ടിയുടെ അധിക വെബ്, ആപ്പ് ആക്റ്റിവിറ്റി ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ അവരുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> <translation id="6851497530878285708">ആപ്പ് പ്രവർത്തനക്ഷമമാക്കി</translation> <translation id="6853388645642883916">അപ്ഡേറ്റർ പ്രവർത്തിക്കുന്നില്ല</translation> <translation id="68541483639528434">മറ്റ് ടാബുകള് അടയ്ക്കുക</translation> @@ -5883,7 +5883,7 @@ <translation id="7203150201908454328">വിപുലീകരിച്ചത്</translation> <translation id="7206693748120342859"><ph name="PLUGIN_NAME" /> ഡൗൺലോഡുചെയ്യുന്നു...</translation> <translation id="720715819012336933">{NUM_PAGES,plural, =1{പേജിൽ നിന്ന് പുറത്തുകടക്കുക}other{പേജുകളിൽ നിന്ന് പുറത്തുകടക്കുക}}</translation> -<translation id="7207457272187520234">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഈ ഉപകരണം നിലവിൽ സ്വയമേവ Google-ന് അയയ്ക്കുന്നുണ്ട്. സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് ഇത് സഹായിക്കും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. ഈ ക്രമീകരണം നടപ്പിലാക്കിയിരിക്കുന്നത് ഉടമയാണ്. നിങ്ങളുടെ അധിക വെബ്, ആപ്പ് പ്രവർത്തനം ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> +<translation id="7207457272187520234">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഈ ഉപകരണം നിലവിൽ സ്വയമേവ Google-ന് അയയ്ക്കുന്നുണ്ട്. സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് ഇത് സഹായിക്കും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. ഈ ക്രമീകരണം നടപ്പിലാക്കിയിരിക്കുന്നത് ഉടമയാണ്. നിങ്ങളുടെ അധിക വെബ്, ആപ്പ് ആക്റ്റിവിറ്റി ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> <translation id="7207631048330366454">ആപ്പുകൾ തിരയുക</translation> <translation id="7210499381659830293">വിപുലീകരണ പ്രിന്ററുകള്</translation> <translation id="7211783048245131419">ഇതുവരെ സ്വിച്ച് അസൈൻ ചെയ്തിട്ടില്ല</translation> @@ -6102,7 +6102,6 @@ <translation id="7433708794692032816">നിങ്ങളുടെ <ph name="DEVICE_TYPE" /> ഉപയോഗിക്കുന്നത് തുടരാൻ സ്മാർട്ട് കാർഡ് ഇൻസേർട്ട് ചെയ്യുക</translation> <translation id="7433957986129316853">നിലനിർത്തുക</translation> <translation id="7434509671034404296">ഡെവലപ്പർ</translation> -<translation id="7434635829372401939">നിങ്ങളുടെ ക്രമീകരണം സമന്വയിപ്പിക്കുക</translation> <translation id="7434757724413878233">മൗസ് ആക്സിലറേഷൻ</translation> <translation id="7434969625063495310">പ്രിന്റ് സെർവർ ചേർക്കാനായില്ല. സെർവറിന്റെ കോൺഫിഗറേഷൻ പരിശോധിച്ച ശേഷം വീണ്ടും ശ്രമിക്കുക.</translation> <translation id="7436921188514130341">ക്ഷമിക്കണം! പേരുമാറ്റുന്നതിനിടെ ഒരു പിശകുണ്ടായി.</translation> @@ -6987,7 +6986,7 @@ <translation id="8300011035382349091">ഈ ടാബിന്റെ ബുക്ക്മാർക്ക് എഡിറ്റ് ചെയ്യുക</translation> <translation id="8300374739238450534">ഇരുളിൻ നീല</translation> <translation id="8303616404642252802">{COUNT,plural, =1{വിലാസം}other{# വിലാസങ്ങൾ}}</translation> -<translation id="8304383784961451596">ഈ ഉപകരണം ഉപയോഗിക്കാൻ നിങ്ങൾക്ക് അനുമതിയില്ല. സൈൻ-ഇൻ അനുമതിക്കായി അഡ്മിനുമായി ബന്ധപ്പെടുക അല്ലെങ്കിൽ Family Link മേൽനോട്ടം വഹിക്കുന്ന ഒരു Google അക്കൗണ്ട് ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യുക.</translation> +<translation id="8304383784961451596">ഈ ഉപകരണം ഉപയോഗിക്കാൻ നിങ്ങൾക്ക് അനുമതിയില്ല. സൈൻ-ഇൻ അനുമതിക്കായി അഡ്മിനുമായി ബന്ധപ്പെടുക അല്ലെങ്കിൽ Family Link മേൽനോട്ടത്തിലുള്ള ഒരു Google അക്കൗണ്ട് ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യുക.</translation> <translation id="8308016398665340540">ഈ ഉപകരണത്തിന്റെ മറ്റ് ഉപയോക്താക്കളുമായി നിങ്ങൾ ഈ നെറ്റ്വർക്ക് പങ്കിടുന്നു</translation> <translation id="8308179586020895837"><ph name="HOST" />-ന് നിങ്ങളുടെ ക്യാമറ ആക്സസ് ചെയ്യാൻ താൽപ്പര്യമുണ്ടോ എന്ന് ചോദിക്കുക</translation> <translation id="830868413617744215">ബീറ്റ</translation> @@ -7267,7 +7266,7 @@ <translation id="8637542770513281060">നിങ്ങളുടെ കമ്പ്യൂട്ടറിൽ, Chrome OS-ലെ നിർണ്ണായകമായ നിരവധി സുരക്ഷാ ഫീച്ചറുകൾ നടപ്പിലാക്കാൻ ഉപയോഗിക്കുന്ന സുരക്ഷാ മൊഡ്യൂൾ അടങ്ങിയിരിക്കുന്നു. കൂടുതലറിയാൻ Chromebook സഹായകേന്ദ്രം സന്ദർശിക്കുക: https://support.google.com/chromebook/?p=sm</translation> <translation id="8637688295594795546">സിസ്റ്റം അപ്ഡേറ്റ് ലഭ്യമാണ്. ഡൌണ്ലോഡ് ചെയ്യുന്നതിന് തയ്യാറെടുക്കുന്നു...</translation> <translation id="8639047128869322042">ദോഷകരമായ സോഫ്റ്റ്വെയർ ഉണ്ടോയെന്ന് പരിശോധിക്കുന്നു...</translation> -<translation id="8639635302972078117">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഈ ഉപകരണം നിലവിൽ സ്വയമേവ Google-ന് അയയ്ക്കുന്നുണ്ട്. നിങ്ങളുടെ കുട്ടിയെ തിരിച്ചറിയാൻ ഇത് ഉപയോഗിക്കില്ല, സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് സഹായിക്കുകയും ചെയ്യും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. നിങ്ങളുടെ കുട്ടിയുടെ അധിക വെബ്, ആപ്പ് പ്രവർത്തന ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ അവരുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> +<translation id="8639635302972078117">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഈ ഉപകരണം നിലവിൽ സ്വയമേവ Google-ന് അയയ്ക്കുന്നുണ്ട്. നിങ്ങളുടെ കുട്ടിയെ തിരിച്ചറിയാൻ ഇത് ഉപയോഗിക്കില്ല, സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് സഹായിക്കുകയും ചെയ്യും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. നിങ്ങളുടെ കുട്ടിയുടെ അധിക വെബ്, ആപ്പ് ആക്റ്റിവിറ്റി ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ അവരുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> <translation id="8642900771896232685">2 സെക്കൻഡ്</translation> <translation id="8642947597466641025">പാഠത്തെ വലുതാക്കുക</translation> <translation id="8643443571868262066"><ph name="FILE_NAME" /> അപകടകരമായേക്കാം. സ്കാൻ ചെയ്യാൻ Google-ന്റെ വിപുലമായ പരിരക്ഷയിലേക്ക് അയയ്ക്കണോ?</translation> @@ -7573,7 +7572,7 @@ <translation id="8929696694736010839">നിലവിലെ അദൃശ്യ സെഷന് മാത്രം</translation> <translation id="8930351635855238750">പേജ് റീലോഡ് ചെയ്തതിന് ശേഷം പുതിയ കുക്കി ക്രമീകരണം പ്രാബല്യത്തില് വരും</translation> <translation id="8930622219860340959">വയര്ലെസ്സ്</translation> -<translation id="8931076093143205651">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ സ്വയമേവ Google-ന് അയച്ച്, നിങ്ങളുടെ Android അനുഭവം മെച്ചപ്പെടുത്താൻ സഹായിക്കുക. സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് ഇത് സഹായിക്കും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. ഈ ക്രമീകരണം നടപ്പിലാക്കിയിരിക്കുന്നത് ഉടമയാണ്. ഈ ഉപകരണത്തിലെ പ്രശ്നനിർണ്ണയവും ഉപയോഗവുമായി ബന്ധപ്പെട്ട ഡാറ്റയും Google-ന് അയയ്ക്കാൻ ഉടമ തീരുമാനിച്ചേക്കാം. നിങ്ങളുടെ അധിക വെബ്, ആപ്പ് പ്രവർത്തനം ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> +<translation id="8931076093143205651">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ സ്വയമേവ Google-ന് അയച്ച്, നിങ്ങളുടെ Android അനുഭവം മെച്ചപ്പെടുത്താൻ സഹായിക്കുക. സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് ഇത് സഹായിക്കും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. ഈ ക്രമീകരണം നടപ്പിലാക്കിയിരിക്കുന്നത് ഉടമയാണ്. ഈ ഉപകരണത്തിലെ പ്രശ്നനിർണ്ണയവും ഉപയോഗവുമായി ബന്ധപ്പെട്ട ഡാറ്റയും Google-ന് അയയ്ക്കാൻ ഉടമ തീരുമാനിച്ചേക്കാം. നിങ്ങളുടെ അധിക വെബ്, ആപ്പ് ആക്റ്റിവിറ്റി ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> <translation id="8931475688782629595">നിങ്ങൾ സമന്വയിപ്പിക്കുന്നത് മാനേജ് ചെയ്യുക</translation> <translation id="8932654652795262306">തൽക്ഷണ ടെതറിംഗ് വിശദാംശങ്ങള്</translation> <translation id="8932894639908691771">ആക്സസ് ഓപ്ഷനുകൾ മാറുക</translation> @@ -7825,7 +7824,7 @@ <translation id="9170848237812810038">&പൂര്വാവസ്ഥയിലാക്കുക</translation> <translation id="9170884462774788842">നിങ്ങളുടെ കമ്പ്യൂട്ടറിലെ മറ്റൊരു പ്രോഗ്രാം Chrome പ്രവർത്തിക്കുന്ന രീതി മാറ്റിയേക്കാവുന്ന ഒരു തീം ചേർത്തു.</translation> <translation id="917350715406657904"><ph name="APP_NAME" />-നായി നിങ്ങളുടെ രക്ഷിതാവ് സജ്ജീകരിച്ച സമയ പരിധിയിലെത്തി. നിങ്ങൾക്ക് ഇത് നാളെ <ph name="TIME_LIMIT" /> ഉപയോഗിക്കാം.</translation> -<translation id="9174401638287877180">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ സ്വയമേവ Google-ന് അയച്ച്, കുട്ടിയുടെ Android അനുഭവം മെച്ചപ്പെടുത്താൻ സഹായിക്കുക. നിങ്ങളുടെ കുട്ടിയെ തിരിച്ചറിയാൻ ഇത് ഉപയോഗിക്കില്ല, സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് സഹായിക്കുകയും ചെയ്യും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. നിങ്ങളുടെ കുട്ടിയുടെ അധിക വെബ്, ആപ്പ് പ്രവർത്തന ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ അവരുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> +<translation id="9174401638287877180">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ സ്വയമേവ Google-ന് അയച്ച്, കുട്ടിയുടെ Android അനുഭവം മെച്ചപ്പെടുത്താൻ സഹായിക്കുക. നിങ്ങളുടെ കുട്ടിയെ തിരിച്ചറിയാൻ ഇത് ഉപയോഗിക്കില്ല, സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തലുകൾ എന്നിവയ്ക്ക് സഹായിക്കുകയും ചെയ്യും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. നിങ്ങളുടെ കുട്ടിയുടെ അധിക വെബ്, ആപ്പ് ആക്റ്റിവിറ്റി ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ അവരുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം.</translation> <translation id="917510707618656279">Bluetooth ഉപകരണങ്ങൾ ആക്സസ് ചെയ്യാൻ ഒരു സൈറ്റ് താൽപ്പര്യപ്പെടുമ്പോൾ ചോദിക്കുക</translation> <translation id="9176476835295860688">ഉപയോഗവും പ്രശ്നനിർണ്ണയവുമായി ബന്ധപ്പെട്ട ഡാറ്റ അയയ്ക്കുക. പ്രശ്നനിർണ്ണയം, ഉപകരണം, ആപ്പ് ഉപയോഗം എന്നിവയുമായി ബന്ധപ്പെട്ട ഡാറ്റ, ഈ ഉപകരണം നിലവിൽ സ്വയമേവ Google-ന് അയയ്ക്കുന്നുണ്ട്. സിസ്റ്റം, ആപ്പ് സ്ഥിരത, മറ്റ് മെച്ചപ്പെടുത്തൽ എന്നിവയ്ക്ക് ഇത് സഹായിക്കും. ചില സംഗ്രഹ ഡാറ്റ, Google ആപ്പുകളെയും Android ഡെവലപ്പർമാരെപ്പോലുള്ള പങ്കാളികളെയും സഹായിക്കുകയും ചെയ്യും. ഈ <ph name="BEGIN_LINK1" />ക്രമീകരണം<ph name="END_LINK1" /> നടപ്പിലാക്കുന്നത് ഉടമയാണ്. നിങ്ങളുടെ അധിക വെബ്, ആപ്പ് ആക്റ്റിവിറ്റി ക്രമീകരണം ഓണാക്കിയിട്ടുണ്ടെങ്കിൽ, ഈ ഡാറ്റ നിങ്ങളുടെ Google അക്കൗണ്ടിൽ സംരക്ഷിക്കപ്പെട്ടേക്കാം. <ph name="BEGIN_LINK2" />കൂടുതലറിയുക<ph name="END_LINK2" /></translation> <translation id="9176611096776448349"><ph name="WINDOW_TITLE" /> - Bluetooth ഉപകരണം കണക്റ്റ് ചെയ്തു</translation>
diff --git a/chrome/app/resources/generated_resources_mn.xtb b/chrome/app/resources/generated_resources_mn.xtb index 4bbb979..436aa24 100644 --- a/chrome/app/resources/generated_resources_mn.xtb +++ b/chrome/app/resources/generated_resources_mn.xtb
@@ -6108,7 +6108,6 @@ <translation id="7433708794692032816">Өөрийн <ph name="DEVICE_TYPE" />-г үргэлжлүүлэн ашиглахын тулд ухаалаг карт оруулна уу</translation> <translation id="7433957986129316853">Үүнийг хадгалах</translation> <translation id="7434509671034404296">Хөгжүүлэгч</translation> -<translation id="7434635829372401939">Тохиргоогоо синк хийх</translation> <translation id="7434757724413878233">Хулганын хурдасгуур</translation> <translation id="7434969625063495310">Хэвлэх серверийг нэмж чадсангүй. Серверийн тохируулгыг шалгаад дахин оролдоно уу.</translation> <translation id="7436921188514130341">Уучлаарай! Нэр өөрчлөхөд алдаа гарлаа.</translation>
diff --git a/chrome/app/resources/generated_resources_mr.xtb b/chrome/app/resources/generated_resources_mr.xtb index 49338229..d915c636 100644 --- a/chrome/app/resources/generated_resources_mr.xtb +++ b/chrome/app/resources/generated_resources_mr.xtb
@@ -2363,6 +2363,7 @@ <translation id="3413122095806433232">CA जारीकर्ता: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">आकार:</translation> <translation id="3414966631182382431"><ph name="MANAGER" /> द्वारे तुमचा <ph name="BEGIN_LINK" />ब्राउझर व्यवस्थापित केला आहे<ph name="END_LINK" /></translation> +<translation id="341589277604221596">लाइव्ह कॅप्शन - <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">नेहमी पूर्ण URL दाखवा</translation> <translation id="3417835166382867856">टॅब शोधा</translation> <translation id="3417836307470882032">२४ तासांचे घड्याळ</translation> @@ -6115,7 +6116,6 @@ <translation id="7433708794692032816">तुमचे <ph name="DEVICE_TYPE" /> वापरत राहण्यासाठी स्मार्ट कार्ड घाला</translation> <translation id="7433957986129316853">ठेवा</translation> <translation id="7434509671034404296">डेव्हलपर</translation> -<translation id="7434635829372401939">तुमच्या सेटिंग्ज सिंक करा</translation> <translation id="7434757724413878233">माउस अॅक्सिलरेशन</translation> <translation id="7434969625063495310">प्रिंट सर्व्हर जोडता आला नाही. कृपया सर्व्हरचे कॉंफिगरेशन तपासा आणि पुन्हा प्रयत्न करा.</translation> <translation id="7436921188514130341">ओहो! नाव बदलताना एक एरर आली होती.</translation> @@ -7196,6 +7196,7 @@ <translation id="8540136935098276800">योग्य प्रकारे फॉरमॅट केलेली URL एंटर करा</translation> <translation id="8540503336857689453">सुरक्षेच्या कारणांमुळे लपवलेला नेटवर्क वापरण्याची शिफारस केली जात नाही.</translation> <translation id="854071720451629801">वाचलेले म्हणून खूण करा</translation> +<translation id="8540942859441851323">पुरवठादाराचे रोमिंग उपलब्ध असणे आवश्यक आहे</translation> <translation id="8541462173655894684">प्रिंट सर्व्हरवरील कोणतेही प्रिंटर आढळले नाहीत</translation> <translation id="8541838361296720865">“<ph name="ACTION" />” साठी स्विच किंवा कीबोर्ड की असाइन करण्याकरिता, ती दाबा</translation> <translation id="8542618328173222274">साइटला तुमची आभासी वास्तविकता डिव्हाइस आणि डेटा वापरायचा असल्यास विचारा</translation>
diff --git a/chrome/app/resources/generated_resources_ms.xtb b/chrome/app/resources/generated_resources_ms.xtb index 9af5281..2cc02fbb 100644 --- a/chrome/app/resources/generated_resources_ms.xtb +++ b/chrome/app/resources/generated_resources_ms.xtb
@@ -6118,7 +6118,6 @@ <translation id="7433708794692032816">Masukkan kad pintar untuk terus menggunakan <ph name="DEVICE_TYPE" /> anda</translation> <translation id="7433957986129316853">Kekalkan</translation> <translation id="7434509671034404296">Pembangun</translation> -<translation id="7434635829372401939">Segerakkan tetapan anda</translation> <translation id="7434757724413878233">Pemecutan tetikus</translation> <translation id="7434969625063495310">Tidak dapat menambahkan pelayan cetak. Sila semak konfigurasi pelayan dan cuba lagi.</translation> <translation id="7436921188514130341">Oh, Tidak! Ralat berlaku semasa penamaan semula.</translation>
diff --git a/chrome/app/resources/generated_resources_my.xtb b/chrome/app/resources/generated_resources_my.xtb index 599facd..d0a8a89 100644 --- a/chrome/app/resources/generated_resources_my.xtb +++ b/chrome/app/resources/generated_resources_my.xtb
@@ -6112,7 +6112,6 @@ <translation id="7433708794692032816">သင်၏ <ph name="DEVICE_TYPE" /> ကို ဆက်သုံးရန် စမတ်ကတ် ထည့်သွင်းပါ</translation> <translation id="7433957986129316853">ဆက်ထားရန်</translation> <translation id="7434509671034404296">ပြုစုသူ</translation> -<translation id="7434635829372401939">သင့်ဆက်တင်များ စင့်ခ်လုပ်ခြင်း</translation> <translation id="7434757724413878233">မောက်စ် အရှိန်မြှင့်ရန်</translation> <translation id="7434969625063495310">ပုံနှိပ်စက်ဆာဗာကို ထည့်၍မရပါ။ ဆာဗာ၏ စီစဉ်သတ်မှတ်ချက်ကို စစ်ဆေးပြီး ထပ်စမ်းကြည့်ပါ။</translation> <translation id="7436921188514130341">စိတ်မကောင်းပါ။ အမည်ပြောင်းနေစဉ် မှားယွင်းမှုတစ်ခု ဖြစ်ပေါ်ခဲ့သည်။</translation>
diff --git a/chrome/app/resources/generated_resources_ne.xtb b/chrome/app/resources/generated_resources_ne.xtb index 5744cd6..252a0c9 100644 --- a/chrome/app/resources/generated_resources_ne.xtb +++ b/chrome/app/resources/generated_resources_ne.xtb
@@ -2347,6 +2347,7 @@ <translation id="3413122095806433232">CA जारीकर्ता: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">आकार:</translation> <translation id="3414966631182382431"><ph name="MANAGER" /> ले तपाईंको <ph name="BEGIN_LINK" />ब्राउजर व्यवस्थापन गर्छ<ph name="END_LINK" /></translation> +<translation id="341589277604221596">लाइभ क्याप्सन - <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">सँधै पूरा URL हरू देखाइयोस्</translation> <translation id="3417835166382867856">ट्याब खोज्नुहोस्</translation> <translation id="3417836307470882032">२४ घन्टे समय</translation> @@ -6097,7 +6098,6 @@ <translation id="7433708794692032816">आफ्नो <ph name="DEVICE_TYPE" /> प्रयोग गरिरहन स्मार्ट कार्ड इन्सर्ट गर्नुहोस्</translation> <translation id="7433957986129316853">यसलाई लागु गर्नुहोस्</translation> <translation id="7434509671034404296">विकासकर्ता</translation> -<translation id="7434635829372401939">आफ्ना सेटिङ सिंक गर्नुहोस्</translation> <translation id="7434757724413878233">माउसको गति बढाउने कार्य</translation> <translation id="7434969625063495310">छपाइसम्बन्धी सर्भर थप्न पार्न सकिएन। कृपया सर्भरको कन्फिगुरेसन जाँच गरी फेरि प्रयास गर्नुहोस्।</translation> <translation id="7436921188514130341">ओहो! पुनः नामकरण गर्ने क्रममा कुनै त्रुटि भयो।</translation> @@ -7179,6 +7179,7 @@ <translation id="8540136935098276800">सही ढाँचा भएको URL प्रविष्टि गर्नुहोस्</translation> <translation id="8540503336857689453">तपाईंको डेटाको सुरक्षार्थ, लुकाइएको नेटवर्क प्रयोग नगर्न सिफारिस गरिन्छ।</translation> <translation id="854071720451629801">पढिसकिएको भनी चिन्ह लगाउनुहोस्</translation> +<translation id="8540942859441851323">प्रदायकको हकमा रोमिङ सेवा अन भएको हुनु पर्छ</translation> <translation id="8541462173655894684">प्रिन्ट सर्भरमा कुनै पनि प्रिन्टर फेला परेन</translation> <translation id="8541838361296720865">तपाईं “<ph name="ACTION" />” गर्ने कार्यका लागि जुन स्विच वा किबोर्ड की असाइन गर्न चाहनुहुन्छ उक्त स्विच वा की थिच्नुहोस्</translation> <translation id="8542618328173222274">कुनै साइटले भर्चुअल रियालिटी चल्ने तपाईंका यन्त्रहरू र तिनमा भएका डेटा प्रयोग गर्ने अनुमति माग्दा सोध्नुहोस्</translation>
diff --git a/chrome/app/resources/generated_resources_nl.xtb b/chrome/app/resources/generated_resources_nl.xtb index 8b3df81..35760774 100644 --- a/chrome/app/resources/generated_resources_nl.xtb +++ b/chrome/app/resources/generated_resources_nl.xtb
@@ -1221,6 +1221,7 @@ <translation id="2232751457155581899">Sites kunnen vragen of ze je camerapositie mogen bijhouden</translation> <translation id="2232876851878324699">Het bestand bevat één certificaat. Dit certificaat is niet geïmporteerd:</translation> <translation id="2233502537820838181">&Meer informatie</translation> +<translation id="223356358902285214">Web- en app-activiteit</translation> <translation id="2234876718134438132">Synchronisatie en Google-services</translation> <translation id="2235344399760031203">Cookies van derden worden geblokkeerd</translation> <translation id="2238379619048995541">Gegevens van frequentiestatus</translation> @@ -1906,6 +1907,7 @@ <translation id="2923006468155067296">Je <ph name="DEVICE_TYPE" /> wordt nu vergrendeld. <ph name="DOMAIN" /> vereist dat je smartcard geplaatst blijft.</translation> <translation id="2923234477033317484">Dit account verwijderen</translation> +<translation id="2923644930701689793">De filmrol van je telefoon openen</translation> <translation id="2926085873880284723">Standaard snelkoppelingen herstellen</translation> <translation id="2926620265753325858"><ph name="DEVICE_NAME" /> wordt niet ondersteund.</translation> <translation id="2927017729816812676">Cache-opslag</translation> @@ -3099,6 +3101,7 @@ <translation id="4168015872538332605">Sommige instellingen die bij <ph name="PRIMARY_EMAIL" /> horen, worden met je gedeeld. Deze instellingen beïnvloeden je account alleen wanneer toegang tot meerdere accounts wordt gebruikt.</translation> <translation id="4169535189173047238">Niet toestaan</translation> <translation id="4170314459383239649">Wissen bij het verlaten</translation> +<translation id="417096670996204801">Profiel kiezen</translation> <translation id="4175137578744761569">Lichtpaars/wit</translation> <translation id="4175737294868205930">Permanente opslag</translation> <translation id="4176463684765177261">Uitgezet</translation> @@ -4081,6 +4084,7 @@ <translation id="5265562206369321422">Langer dan een week offline</translation> <translation id="5265797726250773323">Fout bij het installeren</translation> <translation id="5266113311903163739">Fout bij het importeren van de certificeringsinstantie</translation> +<translation id="526622169288322445">Meer acties voor <ph name="ADDRESS_SUMMARY" /></translation> <translation id="5269977353971873915">Afdrukken mislukt</translation> <translation id="5275352920323889391">Hond</translation> <translation id="527605982717517565">JavaScript altijd toestaan op <ph name="HOST" /></translation> @@ -5465,6 +5469,7 @@ <translation id="6775163072363532304">Beschikbare apparaten zie je hier.</translation> <translation id="6777817260680419853">Omleiding geblokkeerd</translation> <translation id="6778737459546443941">Je ouder of voogd heeft dit nog niet goedgekeurd</translation> +<translation id="6779092717724412415">Selecteer tekst en klik met de rechtermuisknop om een markering zoals deze te maken.</translation> <translation id="6779447100905857289">je winkelwagens</translation> <translation id="677965093459947883">Zeer klein</translation> <translation id="6781005693196527806">Zoek&machines beheren…</translation> @@ -6094,7 +6099,6 @@ <translation id="7433708794692032816">Plaats een smartcard om je <ph name="DEVICE_TYPE" /> te blijven gebruiken</translation> <translation id="7433957986129316853">Behouden</translation> <translation id="7434509671034404296">Ontwikkelaar</translation> -<translation id="7434635829372401939">Je instellingen synchroniseren</translation> <translation id="7434757724413878233">Muisversnelling</translation> <translation id="7434969625063495310">Kan de printerserver niet toevoegen. Controleer de configuratie van de server en probeer het opnieuw.</translation> <translation id="7436921188514130341">Asjemenou! Er is iets misgegaan bij het veranderen van de naam.</translation> @@ -6281,6 +6285,7 @@ <translation id="7625823789272218216">Nieuw tabblad aan de linkerkant</translation> <translation id="7628201176665550262">Vernieuwingssnelheid</translation> <translation id="7629827748548208700">Tabblad: <ph name="TAB_NAME" /></translation> +<translation id="7630426712700473382">Dit apparaat wordt beheerd door <ph name="MANAGER" /> en vereist dat je elke keer opnieuw inlogt.</translation> <translation id="7631014249255418691">Back-up maken van Linux-apps en -bestanden is geslaagd</translation> <translation id="7631205654593498032">Door je apparaten te koppelen geef je de <ph name="DEVICE_TYPE" /> toestemming om:</translation> <translation id="7631887513477658702">&Altijd bestanden van dit type openen</translation>
diff --git a/chrome/app/resources/generated_resources_no.xtb b/chrome/app/resources/generated_resources_no.xtb index c69de7d..0b572b7 100644 --- a/chrome/app/resources/generated_resources_no.xtb +++ b/chrome/app/resources/generated_resources_no.xtb
@@ -6071,7 +6071,6 @@ <translation id="7433708794692032816">Sett inn smartkortet for å fortsette å bruke <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Nei</translation> <translation id="7434509671034404296">Utvikler</translation> -<translation id="7434635829372401939">Synkroniser innstillingene dine</translation> <translation id="7434757724413878233">Museakselerasjon</translation> <translation id="7434969625063495310">Kunne ikke legge til utskriftstjeneren. Kontrollér tjenerens konfigurasjon, og prøv på nytt.</translation> <translation id="7436921188514130341">Æsj! Det oppsto en feil under navneendringen.</translation>
diff --git a/chrome/app/resources/generated_resources_or.xtb b/chrome/app/resources/generated_resources_or.xtb index 63947aa..3c30adcc 100644 --- a/chrome/app/resources/generated_resources_or.xtb +++ b/chrome/app/resources/generated_resources_or.xtb
@@ -6098,7 +6098,6 @@ <translation id="7433708794692032816">ଆପଣଙ୍କ <ph name="DEVICE_TYPE" />ର ବ୍ୟବହାର ଜାରି ରଖିବା ପାଇଁ ସ୍ମାର୍ଟ କାର୍ଡକୁ ଇନସାର୍ଟ କରନ୍ତୁ</translation> <translation id="7433957986129316853">ଏହାକୁ ରଖନ୍ତୁ</translation> <translation id="7434509671034404296">ଡେଭେଲପର୍</translation> -<translation id="7434635829372401939">ଆପଣଙ୍କର ସେଟିଂସ୍ ସିଙ୍କ୍ କରନ୍ତୁ</translation> <translation id="7434757724413878233">ମାଉସ୍ ଆକ୍ସଲରେସନ୍</translation> <translation id="7434969625063495310">ପ୍ରିଣ୍ଟ ସର୍ଭର୍ ଯୋଗ କରାଯାଇପାରିଲା ନାହିଁ। ଦୟାକରି ସର୍ଭରର କନଫିଗରେସନ୍ ଯାଞ୍ଚ କରି ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।</translation> <translation id="7436921188514130341">ଇସ୍, କିଛି ଭୁଲ୍ ହୋଇଛି! ରିନେମ୍ କରିବା ସମୟରେ ଏକ ତ୍ରୁଟି ହୋଇଥିଲା।</translation>
diff --git a/chrome/app/resources/generated_resources_pa.xtb b/chrome/app/resources/generated_resources_pa.xtb index eb162e4..1b8ca959 100644 --- a/chrome/app/resources/generated_resources_pa.xtb +++ b/chrome/app/resources/generated_resources_pa.xtb
@@ -2362,6 +2362,7 @@ <translation id="3413122095806433232">CA ਜਾਰੀਕਰਤਾ: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">ਆਕਾਰ:</translation> <translation id="3414966631182382431">ਤੁਹਾਡੇ <ph name="BEGIN_LINK" />ਬ੍ਰਾਊਜ਼ਰ ਦਾ ਪ੍ਰਬੰਧਨ<ph name="END_LINK" /> <ph name="MANAGER" /> ਵੱਲੋਂ ਕੀਤਾ ਜਾਂਦਾ ਹੈ</translation> +<translation id="341589277604221596">ਲਾਈਵ ਸੁਰਖੀਆਂ - <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">ਹਮੇਸ਼ਾਂ ਪੂਰੇ URL ਦਿਖਾਓ</translation> <translation id="3417835166382867856">ਖੋਜ ਟੈਬਾਂ</translation> <translation id="3417836307470882032">24-ਘੰਟੇ ਵਾਲੀ ਘੜੀ</translation> @@ -6115,7 +6116,6 @@ <translation id="7433708794692032816">ਆਪਣੇ <ph name="DEVICE_TYPE" /> ਨੂੰ ਵਰਤਣਾ ਜਾਰੀ ਰੱਖਣ ਲਈ ਸਮਾਰਟ ਕਾਰਡ ਸ਼ਾਮਲ ਕਰੋ</translation> <translation id="7433957986129316853">ਇਹੋ ਰੱਖੋ</translation> <translation id="7434509671034404296">ਵਿਕਾਸਕਾਰ</translation> -<translation id="7434635829372401939">ਆਪਣੀਆਂ ਸੈਟਿੰਗਾਂ ਦਾ ਸਮਕਾਲੀਕਰਨ ਕਰੋ</translation> <translation id="7434757724413878233">ਮਾਊਸ ਐਕਸੈੱਲਰੇਸ਼ਨ</translation> <translation id="7434969625063495310">ਪ੍ਰਿੰਟ ਸਰਵਰ ਨੂੰ ਸ਼ਾਮਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਕਿਰਪਾ ਕਰਕੇ ਸਰਵਰ ਦੇ ਸੰਰੂਪਣ ਦੀ ਜਾਂਚ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।</translation> <translation id="7436921188514130341">ਓਹੋ! ਨਾਮ ਬਦਲਣ ਦੌਰਾਨ ਗੜਬੜ ਹੋ ਗਈ।</translation> @@ -7196,6 +7196,7 @@ <translation id="8540136935098276800">ਸਹੀ ਢੰਗ ਨਾਲ ਫਾਰਮੈਟ ਕੀਤਾ URL ਦਾਖਲ ਕਰੋ</translation> <translation id="8540503336857689453">ਸੁਰੱਖਿਆ ਕਾਰਨਾਂ ਕਰਕੇ ਲੁਕਵੇਂ ਨੈੱਟਵਰਕ ਨੂੰ ਵਰਤਣ ਦੀ ਸਿਫ਼ਾਰਸ਼ ਨਹੀਂ ਕੀਤੀ ਜਾਂਦੀ।</translation> <translation id="854071720451629801">ਪੜ੍ਹੇ ਵਜੋਂ ਨਿਸ਼ਾਨਦੇਹੀ ਕਰੋ</translation> +<translation id="8540942859441851323">ਪ੍ਰਦਾਨਕ ਵੱਲੋਂ ਰੋਮਿੰਗ ਲੋੜੀਂਦੀ ਹੈ</translation> <translation id="8541462173655894684">ਪ੍ਰਿੰਟ ਸਰਵਰ ਤੋਂ ਕੋਈ ਪ੍ਰਿੰਟਰ ਨਹੀਂ ਮਿਲਿਆ</translation> <translation id="8541838361296720865">ਕਿਸੇ ਸਵਿੱਚ ਜਾਂ ਕੀ-ਬੋਰਡ ਕੁੰਜੀ ਨੂੰ “<ph name="ACTION" />” ਦੇ ਜ਼ਿੰਮੇ ਲਗਾਉਣ ਲਈ ਉਸਨੂੰ ਦਬਾਓ</translation> <translation id="8542618328173222274">ਕਿਸੇ ਸਾਈਟ ਵੱਲੋਂ ਤੁਹਾਡੇ ਆਭਾਸੀ ਵਾਸਤਵਿਕਤਾ ਡੀਵਾਈਸਾਂ ਅਤੇ ਡਾਟੇ ਨੂੰ ਵਰਤਣ ਵੇਲੇ ਪੁੱਛੋ</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb index 3967071..0ef13f4 100644 --- a/chrome/app/resources/generated_resources_pl.xtb +++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -91,6 +91,7 @@ <translation id="1087965115100412394">Nie zezwalaj witrynom na łączenie się z urządzeniami MIDI</translation> <translation id="1088654056000736875">Chrome usuwa złośliwe oprogramowanie z komputera...</translation> <translation id="1088659085457112967">Włącz tryb czytnika</translation> +<translation id="1089606299949659462">Sprawdzanie zakończone</translation> <translation id="1090126737595388931">Brak aplikacji uruchomionych w tle</translation> <translation id="1090541560108055381">Przed sparowaniem urządzeń sprawdź, czy wyświetla się na nich ten sam kod</translation> <translation id="1091767800771861448">Naciśnij ESCAPE, aby pominąć aktualizację (tylko nieoficjalne kompilacje).</translation> @@ -804,6 +805,7 @@ <translation id="1807246157184219062">Jasny</translation> <translation id="1809483812148634490">Aplikacje pobrane z Google Play zostaną usunięte z tego Chromebooka.<ph name="LINE_BREAKS1" />Kupione treści, np. filmy, seriale, muzyka, książki i inne zakupy w aplikacjach, również mogą zostać usunięte.<ph name="LINE_BREAKS2" />Nie ma to wpływu na aplikacje ani treści na innych urządzeniach.</translation> <translation id="1809734401532861917">Dodaj moje zakładki, historię, hasła i inne ustawienia do profilu <ph name="USER_EMAIL_ADDRESS" /></translation> +<translation id="1810366086647840386">Serwer obrazu</translation> <translation id="1813278315230285598">Usługi</translation> <translation id="18139523105317219">Nazwa strony EDI</translation> <translation id="1815083418640426271">Wklej jako zwykły tekst</translation> @@ -1373,6 +1375,7 @@ <translation id="2381499968174336913">Podgląd udostępnionej karty</translation> <translation id="2381756643783702095">Pytaj przed wysłaniem (zalecane)</translation> <translation id="2387052489799050037">Powrót do ekranu głównego</translation> +<translation id="2389775852302560582">Adres IP</translation> <translation id="2390347491606624519">Nie udało się nawiązać połączenia z serwerem proxy. Zaloguj się ponownie.</translation> <translation id="2390782873446084770">Wi-Fi Sync</translation> <translation id="2391419135980381625">Czcionka standardowa</translation> @@ -1430,6 +1433,7 @@ <translation id="2453860139492968684">Zakończ</translation> <translation id="2454247629720664989">Słowo kluczowe</translation> <translation id="2454264884354864965">Kamera jest wyłączona</translation> +<translation id="2454524890947537054">Czy chcesz zaakceptować prośbę o dostęp do strony?</translation> <translation id="245650153866130664">Aby automatycznie odświeżać zgłoszenie, zaznacz opcję „Zapamiętaj hasło”. Hasło będzie przechowywane wyłącznie na Twoim urządzeniu.</translation> <translation id="2457246892030921239"><ph name="APP_NAME" /> chce skopiować pliki z dysku <ph name="VOLUME_NAME" />.</translation> <translation id="2457842160081795172">Obecnie na kanale <ph name="CHANNEL_NAME" /></translation> @@ -1746,6 +1750,7 @@ <translation id="2773802008104670137">Plik tego typu może uszkodzić komputer.</translation> <translation id="2775104091073479743">Edytuj odciski palców</translation> <translation id="2776560192867872731">Zmień nazwę urządzenia <ph name="DEVICE_NAME" /></translation> +<translation id="2777251078198759550">Usuń ten kontener</translation> <translation id="2781692009645368755">Google Pay</translation> <translation id="2782104745158847185">Błąd podczas instalowania aplikacji na Linuksa</translation> <translation id="2783298271312924866">Pobrane</translation> @@ -1827,10 +1832,12 @@ <translation id="2851728849045278002">Coś poszło nie tak. Kliknij, by uzyskać więcej informacji.</translation> <translation id="285241945869362924">Automatycznie tworzy napisy dla dźwięku i wideo. Dźwięk ani napisy nie są wysyłane poza urządzenie.</translation> <translation id="2854896010770911740">Usuń pliki cookie innych firm</translation> +<translation id="2856776373509145513">Utwórz nowy kontener</translation> <translation id="2858138569776157458">Popularne</translation> <translation id="2861301611394761800">Aktualizacja systemu zakończona. Uruchom system ponownie.</translation> <translation id="2861941300086904918">Menedżer zabezpieczeń klienta rodzimego</translation> <translation id="2862815659905780618">Usuń środowisko programistyczne Linuksa</translation> +<translation id="2864272167277395865">Wybierz urządzenie:</translation> <translation id="2864601841139725659">Ustawianie zdjęcia profilowego</translation> <translation id="2865919525181940183">Zrzut ekranu z widocznymi na nim teraz programami</translation> <translation id="286674810810214575">Sprawdzam źródła zasilania...</translation> @@ -2397,6 +2404,7 @@ <translation id="3458794975359644386">Nie udało się cofnąć udostępniania</translation> <translation id="3459509316159669723">Drukowanie</translation> <translation id="3459697287128633276">Aby Twoje konto miało dostęp do Sklepu Google Play, uwierzytelnij je za pomocą dostawcy tożsamości.</translation> +<translation id="3461766685318630278">Twórz i usuwaj dodatkowe kontenery.</translation> <translation id="3462311546193741693">Spowoduje wylogowanie Cię z większości stron internetowych. Nie nastąpi wylogowanie z konta Google, więc będzie można wyczyścić zsynchronizowane dane.</translation> <translation id="3462413494201477527">Anulować konfigurowanie konta?</translation> <translation id="346298925039590474">Ta sieć komórkowa będzie dostępna dla wszystkich użytkowników urządzenia</translation> @@ -3241,6 +3249,7 @@ <translation id="4364830672918311045">Wyświetlanie powiadomień</translation> <translation id="4366138410738374926">Rozpoczęto drukowanie</translation> <translation id="4369121877634339065">Przeciągnij po dowolnym obrazie, aby wyszukać</translation> +<translation id="4369215744064167350">Zaakceptowano prośbę dotyczącą strony</translation> <translation id="4370975561335139969">Podany adres e-mail i hasło nie pasują do siebie</translation> <translation id="4373966964907728675">Przesyłanie pulpitu</translation> <translation id="4374831787438678295">Instalator Linuksa</translation> @@ -3934,6 +3943,7 @@ <translation id="5117139026559873716">Odłącz telefon od urządzenia <ph name="DEVICE_TYPE" />. Te urządzenia nie będą już łączyć się ze sobą automatycznie.</translation> <translation id="5117930984404104619">Monitorowanie działania innych rozszerzeń, w tym otwieranych adresów URL</translation> <translation id="5119173345047096771">Mozilla Firefox</translation> +<translation id="5120886753782992638">Aby otworzyć stronę <ph name="APPROVED_URL" />, kliknij tutaj</translation> <translation id="5121052518313988218">System operacyjny w Twoim kontenerze Linuksa nie jest już obsługiwany. Nie będzie otrzymywać kolejnych aktualizacji zabezpieczeń ani poprawek błędów, a funkcje, które teraz działają, mogą nieoczekiwanie zacząć sprawiać problemy. Aby nadal używać Linuksa, uaktualnij go do najnowszej wersji.</translation> <translation id="5121130586824819730">Dysk twardy jest pełny. Zapisz w innej lokalizacji lub zwolnij miejsce na dysku.</translation> <translation id="5123433949759960244">Piłka do koszykówki</translation> @@ -4042,6 +4052,7 @@ <translation id="523505283826916779">Ustawienia ułatwień dostępu</translation> <translation id="5235750401727657667">Zmiana strony, która wyświetla się, gdy otwierasz nową kartę</translation> <translation id="5236374273162681467">Aby łatwo korzystać z nich na wszystkich swoich urządzeniach, możesz przenieść je na swoje konto Google</translation> +<translation id="523862956770478816">Uprawnienia do strony</translation> <translation id="5242724311594467048">Włączyć rozszerzenie „<ph name="EXTENSION_NAME" />”?</translation> <translation id="5243522832766285132">Spróbuj ponownie za kilka chwil</translation> <translation id="5244474230056479698">Synchronizacja z <ph name="EMAIL" /></translation> @@ -4069,6 +4080,7 @@ <translation id="5265562206369321422">Offline od ponad tygodnia</translation> <translation id="5265797726250773323">Błąd podczas instalowania</translation> <translation id="5266113311903163739">Błąd importowania urzędu certyfikacji</translation> +<translation id="526622169288322445">Więcej działań dotyczących: <ph name="ADDRESS_SUMMARY" /></translation> <translation id="5269977353971873915">Niepowodzenie drukowania</translation> <translation id="5275352920323889391">Pies</translation> <translation id="527605982717517565">Zawsze zezwalaj na wykonywanie kodu JavaScript w witrynie <ph name="HOST" /></translation> @@ -4316,6 +4328,7 @@ <translation id="5526745900034778153">Zaloguj się ponownie, by wznowić synchronizację</translation> <translation id="5527463195266282916">Podjęto próbę zmiany rozszerzenia na starszą wersję.</translation> <translation id="5527474464531963247">Możesz także wybrać inną sieć.</translation> +<translation id="5528295196101251711">Nazwa maszyny wirtualnej</translation> <translation id="5532223876348815659">Globalne</translation> <translation id="5533001281916885985"><ph name="SITE_NAME" /> prosi o pozwolenie na:</translation> <translation id="5534304873398226603">Odrzuć zdjęcie lub film</translation> @@ -4670,6 +4683,7 @@ <ph name="LINE_BREAK" /> Obraz pojawi się na ekranie blokady i ekranie logowania się do Chromebooka.</translation> <translation id="5925147183566400388">Wskaźnik Kodeksu postępowania certyfikacyjnego</translation> +<translation id="592740088639760830">Zatrzymaj ten kontener</translation> <translation id="592880897588170157">Pobieraj pliki PDF zamiast otwierać je automatycznie w Chrome</translation> <translation id="592919310198008711">Gdy kliknę rozszerzenie</translation> <translation id="5932124097031739492">Linux został uaktualniony.</translation> @@ -5209,6 +5223,7 @@ <translation id="6498249116389603658">&Wszystkie Twoje języki</translation> <translation id="6499143127267478107">Rozpoznawanie hosta w skrypcie proxy...</translation> <translation id="6501086852992132091"><ph name="APP_ORIGIN" /> chce otworzyć ten plik:</translation> +<translation id="6501957628055559556">Wszystkie kontenery</translation> <translation id="650266656685499220">Aby utworzyć albumy, otwórz Zdjęcia Google</translation> <translation id="6503077044568424649">Najczęstsze</translation> <translation id="650457560773015827">Lewy przycisk</translation> @@ -5322,6 +5337,7 @@ <translation id="6619243162837544323">Stan sieci</translation> <translation id="6619801788773578757">Dodaj aplikację kiosku</translation> <translation id="6619990499523117484">Potwierdź kod PIN</translation> +<translation id="6620254580880484313">Nazwa kontenera</translation> <translation id="6622980291894852883">Nadal blokuj pokazywanie grafik</translation> <translation id="6624036901798307345">W trybie tabletu kliknij przycisk licznika kart na pasku narzędzi, aby otworzyć nowy pasek kart z miniaturą każdej karty.</translation> <translation id="6624535038674360844">Plik <ph name="FILE_NAME" /> zawiera treści niebezpieczne lub treści o charakterze kontrowersyjnym. Poproś właściciela, by rozwiązał problem.</translation> @@ -5332,6 +5348,7 @@ <translation id="6635674640674343739">Nie można nawiązać połączenia z siecią. Sprawdź połączenie internetowe i spróbuj jeszcze raz.</translation> <translation id="6635944431854494329">Właściciel może kontrolować tę funkcję, wybierając Ustawienia > Zaawansowane > Automatycznie wysyłaj do Google dane diagnostyczne i informacje o użytkowaniu.</translation> <translation id="6635956300022133031">Wybierz i dostosuj głosy do zamiany tekstu na mowę</translation> +<translation id="6636623428211296678">Zobacz więcej ustawień poniżej lub zakończ</translation> <translation id="6639554308659482635">Pamięć SQLite</translation> <translation id="6640268266988685324">Otwórz kartę</translation> <translation id="6642720633335369752">Aby zobaczyć wszystkie otwarte okna aplikacji, przesuń palcem w górę od dołu ekranu i przytrzymaj.</translation> @@ -5447,6 +5464,7 @@ <translation id="6775163072363532304">Tu pojawią się dostępne urządzenia.</translation> <translation id="6777817260680419853">Przekierowanie zostało zablokowane</translation> <translation id="6778737459546443941">Twój rodzic jeszcze na to nie zezwolił</translation> +<translation id="6779092717724412415">Aby utworzyć wyróżnienie takie jak to, zaznacz dowolny tekst i kliknij prawym przyciskiem myszy.</translation> <translation id="6779447100905857289">Twoje koszyki</translation> <translation id="677965093459947883">Bardzo mała</translation> <translation id="6781005693196527806">&Zarządzaj wyszukiwarkami…</translation> @@ -6076,7 +6094,6 @@ <translation id="7433708794692032816">Aby nadal używać swojego urządzenia <ph name="DEVICE_TYPE" />, włóż kartę inteligentną</translation> <translation id="7433957986129316853">Zachowaj</translation> <translation id="7434509671034404296">Deweloper</translation> -<translation id="7434635829372401939">Synchronizacja ustawień</translation> <translation id="7434757724413878233">Przyspieszenie myszy</translation> <translation id="7434969625063495310">Nie udało się dodać serwera druku. Sprawdź konfigurację serwera i spróbuj ponownie.</translation> <translation id="7436921188514130341">Kurza twarz! Podczas zmiany nazwy wystąpił błąd.</translation> @@ -6094,6 +6111,7 @@ <translation id="7450761244949417357">Otwieram w przeglądarce <ph name="ALTERNATIVE_BROWSER_NAME" /></translation> <translation id="7453008956351770337">Wybierając tę drukarkę, zezwalasz na dostęp do niej temu rozszerzeniu:</translation> <translation id="7454548535253569100">Portal: <ph name="SUBFRAME_SITE" /></translation> +<translation id="7455730275746867420">Zarządzaj dodatkowymi kontenerami</translation> <translation id="7456142309650173560">deweloperska</translation> <translation id="7456847797759667638">Otwórz lokalizację...</translation> <translation id="7457384018036134905">Zarządzaj językami w ustawieniach Chrome OS</translation> @@ -6262,6 +6280,7 @@ <translation id="7625823789272218216">Nowa karta po lewej</translation> <translation id="7628201176665550262">Częstotliwość odświeżania</translation> <translation id="7629827748548208700">Karta: <ph name="TAB_NAME" /></translation> +<translation id="7630426712700473382">Administrator tego urządzenia (<ph name="MANAGER" />) wymaga logowania się za każdym razem.</translation> <translation id="7631014249255418691">Pomyślnie utworzono kopię zapasową aplikacji i plików Linuksa</translation> <translation id="7631205654593498032">Łącząc swoje urządzenia, zgadzasz się na to, by Twój <ph name="DEVICE_TYPE" /> mógł:</translation> <translation id="7631887513477658702">&Zawsze otwieraj pliki tego typu</translation> @@ -6609,6 +6628,7 @@ <translation id="7946586320617670168">Źródło musi być bezpieczne</translation> <translation id="794676567536738329">Potwierdź uprawnienia</translation> <translation id="7947962633355574091">K&opiuj adres wideo</translation> +<translation id="7948407723851303488">Wszystkie strony w domenie <ph name="DOMAIN_NAME" /></translation> <translation id="7951265006188088697">Aby dodać formy płatności Google Pay lub nimi zarządzać, wejdź na swoje <ph name="BEGIN_LINK" />konto Google<ph name="END_LINK" /></translation> <translation id="7952708427581814389">Strony mogą prosić o dostęp do tekstu i obrazów w schowku</translation> <translation id="795282463722894016">Przywracanie ukończone</translation> @@ -7676,6 +7696,7 @@ <translation id="9053893665344928494">Zapamiętaj mój wybór</translation> <translation id="9055636786322918818">Wymusza szyfrowanie RC4. Używanie tej opcji jest ryzykowne, ponieważ szyfrowanie RC4 nie zapewnia bezpieczeństwa.</translation> <translation id="9056810968620647706">Nie znaleziono żadnych dopasowań.</translation> +<translation id="9057007989365783744"><ph name="SUPERVISED_USER_NAME" /> chce uzyskać dostęp do tych treści:</translation> <translation id="9057354806206861646">Harmonogram aktualizacji</translation> <translation id="9062468308252555888">14x</translation> <translation id="9063208415146866933">Błąd w wierszach od <ph name="ERROR_LINE_START" /> do <ph name="ERROR_LINE_END" /></translation> @@ -7760,6 +7781,7 @@ <translation id="9139258866388561662">Zaloguj się w usłudze <ph name="WEB_DRIVE" />, aby pobrać</translation> <translation id="9139988741193276691">Konfigurowanie Linuksa</translation> <translation id="9140067245205650184">Korzystasz z nieobsługiwanej flagi funkcji: <ph name="BAD_FLAG" />. Ma to negatywny wpływ na stabilność i zabezpieczenia.</translation> +<translation id="9142637293078737510">Alias obrazu</translation> <translation id="9143298529634201539">Usunąć sugestię?</translation> <translation id="9147392381910171771">&Opcje</translation> <translation id="9148058034647219655">Zakończ</translation>
diff --git a/chrome/app/resources/generated_resources_pt-BR.xtb b/chrome/app/resources/generated_resources_pt-BR.xtb index 9682534..f6793c8 100644 --- a/chrome/app/resources/generated_resources_pt-BR.xtb +++ b/chrome/app/resources/generated_resources_pt-BR.xtb
@@ -1232,6 +1232,7 @@ <translation id="2232751457155581899">Os sites podem pedir para rastrear a posição da câmera</translation> <translation id="2232876851878324699">O arquivo continha um certificado que não foi importado:</translation> <translation id="2233502537820838181">&Mais informações</translation> +<translation id="223356358902285214">Atividade na Web e de apps</translation> <translation id="2234876718134438132">Serviços do Google e de sincronização</translation> <translation id="2235344399760031203">Cookies de terceiros foram bloqueados</translation> <translation id="2238379619048995541">Dados do estado de frequência</translation> @@ -1921,6 +1922,7 @@ <translation id="2923006468155067296">Seu <ph name="DEVICE_TYPE" /> será bloqueado agora. <ph name="DOMAIN" /> requer que você mantenha o cartão inteligente inserido.</translation> <translation id="2923234477033317484">Remover esta conta</translation> +<translation id="2923644930701689793">Acessar o rolo da câmera do smartphone</translation> <translation id="2926085873880284723">Restaurar atalhos padrão</translation> <translation id="2926620265753325858"><ph name="DEVICE_NAME" /> não é compatível.</translation> <translation id="2927017729816812676">Armazenamento de cache</translation> @@ -3114,6 +3116,7 @@ <translation id="4168015872538332605">Algumas configurações pertencentes a <ph name="PRIMARY_EMAIL" /> estão sendo compartilhadas com você. Essas configurações afetam sua conta apenas quando o recurso de login múltiplo é usado.</translation> <translation id="4169535189173047238">Não permitir</translation> <translation id="4170314459383239649">Limpar ao sair</translation> +<translation id="417096670996204801">Escolha um perfil</translation> <translation id="4175137578744761569">Roxo-claro e branco</translation> <translation id="4175737294868205930">Armazenamento persistente</translation> <translation id="4176463684765177261">Desativado</translation> @@ -5627,6 +5630,7 @@ <translation id="6914783257214138813">Suas senhas ficarão visíveis para qualquer pessoa que tiver acesso ao arquivo exportado.</translation> <translation id="6916590542764765824">Gerenciar extensões</translation> <translation id="6919868320029503575">Senhas fracas</translation> +<translation id="6919952941889172531">Ativar também o Navegação segura com maior proteção neste perfil do Chrome?</translation> <translation id="6920989436227028121">Abrir como guia normal</translation> <translation id="6921104647315081813">Limpar atividades</translation> <translation id="692114467174262153">Não foi possível abrir o <ph name="ALTERNATIVE_BROWSER_NAME" /></translation> @@ -6109,7 +6113,6 @@ <translation id="7433708794692032816">Insira o cartão inteligente para continuar usando seu <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Manter assim</translation> <translation id="7434509671034404296">Desenvolvedor</translation> -<translation id="7434635829372401939">Sincronizar as configurações</translation> <translation id="7434757724413878233">Aceleração do mouse</translation> <translation id="7434969625063495310">Não foi possível adicionar o servidor de impressão. Verifique a configuração do servidor e tente novamente.</translation> <translation id="7436921188514130341">Ah, não! Ocorreu um erro durante a renomeação.</translation>
diff --git a/chrome/app/resources/generated_resources_pt-PT.xtb b/chrome/app/resources/generated_resources_pt-PT.xtb index 3bb7741..4dfc8e8 100644 --- a/chrome/app/resources/generated_resources_pt-PT.xtb +++ b/chrome/app/resources/generated_resources_pt-PT.xtb
@@ -1220,6 +1220,7 @@ <translation id="2232751457155581899">Os sites podem solicitar a monitorização da posição da câmara</translation> <translation id="2232876851878324699">O ficheiro continha um certificado que não foi importado:</translation> <translation id="2233502537820838181">&Mais informações</translation> +<translation id="223356358902285214">Atividade da Web e de apps</translation> <translation id="2234876718134438132">Sincronização e serviços Google</translation> <translation id="2235344399760031203">Os cookies de terceiros estão bloqueados.</translation> <translation id="2238379619048995541">Dados do estado de frequência</translation> @@ -1906,6 +1907,7 @@ <translation id="2923006468155067296">O dispositivo <ph name="DEVICE_TYPE" /> será bloqueado agora. <ph name="DOMAIN" /> requer que mantenha o seu cartão inteligente inserido.</translation> <translation id="2923234477033317484">Remover esta conta</translation> +<translation id="2923644930701689793">Aceda ao rolo da câmara do seu telemóvel</translation> <translation id="2926085873880284723">Restaurar atalhos predefinidos</translation> <translation id="2926620265753325858"><ph name="DEVICE_NAME" /> não é suportado.</translation> <translation id="2927017729816812676">Armazenamento de cache</translation> @@ -2347,6 +2349,7 @@ <translation id="3413122095806433232">Emissores de AC: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">Tamanho:</translation> <translation id="3414966631182382431">O <ph name="BEGIN_LINK" />navegador é gerido<ph name="END_LINK" /> por <ph name="MANAGER" /></translation> +<translation id="341589277604221596">Legendas instantâneas – <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">Mostrar sempre URLs completos</translation> <translation id="3417835166382867856">Pesquisar separadores</translation> <translation id="3417836307470882032">Formato de 24 horas</translation> @@ -3099,6 +3102,7 @@ <translation id="4168015872538332605">Algumas definições pertencentes a <ph name="PRIMARY_EMAIL" /> estão a ser partilhadas consigo. Estas definições afetam apenas a sua conta quando utilizar o início de sessão integrado.</translation> <translation id="4169535189173047238">Não permitir</translation> <translation id="4170314459383239649">Limpar ao sair</translation> +<translation id="417096670996204801">Escolha um perfil</translation> <translation id="4175137578744761569">Roxo claro e branco</translation> <translation id="4175737294868205930">Armazenamento persistente</translation> <translation id="4176463684765177261">Desativado</translation> @@ -4081,6 +4085,7 @@ <translation id="5265562206369321422">Offline durante mais de uma semana</translation> <translation id="5265797726250773323">Ocorreu um erro ao instalar</translation> <translation id="5266113311903163739">Erro ao importar autoridade de certificação</translation> +<translation id="526622169288322445">Mais ações para <ph name="ADDRESS_SUMMARY" /></translation> <translation id="5269977353971873915">Falha de Impressão</translation> <translation id="5275352920323889391">Cão</translation> <translation id="527605982717517565">Permitir sempre JavaScript em <ph name="HOST" /></translation> @@ -5465,6 +5470,7 @@ <translation id="6775163072363532304">Os dispositivos disponíveis aparecem aqui.</translation> <translation id="6777817260680419853">Redirecionamento bloqueado</translation> <translation id="6778737459546443941">O teu pai/a tua mãe ainda não o aprovou</translation> +<translation id="6779092717724412415">Para criar um realce como este, selecione qualquer texto e clique com o botão direito do rato.</translation> <translation id="6779447100905857289">os seus carrinhos</translation> <translation id="677965093459947883">Muito pequeno</translation> <translation id="6781005693196527806">&Gerir motores de pesquisa…</translation> @@ -6094,7 +6100,6 @@ <translation id="7433708794692032816">Insira o cartão inteligente para continuar a utilizar o dispositivo <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Manter</translation> <translation id="7434509671034404296">Programador</translation> -<translation id="7434635829372401939">Sincronize as suas definições</translation> <translation id="7434757724413878233">Aceleração do rato</translation> <translation id="7434969625063495310">Não foi possível adicionar o servidor de impressão. Verifique a configuração do servidor e tente novamente.</translation> <translation id="7436921188514130341">Ah, bolas! Ocorreu um erro durante a mudança de nome.</translation> @@ -6281,6 +6286,7 @@ <translation id="7625823789272218216">Novo separador à esquerda</translation> <translation id="7628201176665550262">Taxa de atualização</translation> <translation id="7629827748548208700">Separador: <ph name="TAB_NAME" /></translation> +<translation id="7630426712700473382">Este dispositivo é gerido por <ph name="MANAGER" /> e requer que inicie sessão sempre.</translation> <translation id="7631014249255418691">Cópia de segurança das aplicações e dos ficheiros do Linux efetuada com êxito</translation> <translation id="7631205654593498032">Ao associar os seus dispositivos, concorda que o <ph name="DEVICE_TYPE" /> pode:</translation> <translation id="7631887513477658702">&Abrir Sempre Ficheiros Deste Tipo</translation> @@ -7176,6 +7182,7 @@ <translation id="8540136935098276800">Introduza um URL formatado corretamente.</translation> <translation id="8540503336857689453">A utilização de uma rede oculta não é recomendada por motivos de segurança.</translation> <translation id="854071720451629801">Marcar como lido</translation> +<translation id="8540942859441851323">Roaming exigido pelo fornecedor</translation> <translation id="8541462173655894684">Não foram encontradas quaisquer impressoras no servidor de impressão.</translation> <translation id="8541838361296720865">Prima um interruptor ou uma tecla do teclado para atribuir a "<ph name="ACTION" />"</translation> <translation id="8542618328173222274">Perguntar quando um site pretender utilizar os seus dados e dispositivos de realidade virtual</translation>
diff --git a/chrome/app/resources/generated_resources_ro.xtb b/chrome/app/resources/generated_resources_ro.xtb index 6a1dbe9..3b97921 100644 --- a/chrome/app/resources/generated_resources_ro.xtb +++ b/chrome/app/resources/generated_resources_ro.xtb
@@ -6099,7 +6099,6 @@ <translation id="7433708794692032816">Introdu cardul inteligent pentru a folosi în continuare dispozitivul <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Păstreaz-o</translation> <translation id="7434509671034404296">Dezvoltator</translation> -<translation id="7434635829372401939">Sincronizează setările</translation> <translation id="7434757724413878233">Accelerarea mouse-ului</translation> <translation id="7434969625063495310">Nu s-a putut adăuga serverul de imprimare. Verifică ce configurație are serverul și încearcă din nou.</translation> <translation id="7436921188514130341">Of, nu mai merge! A apărut o eroare la redenumire.</translation>
diff --git a/chrome/app/resources/generated_resources_ru.xtb b/chrome/app/resources/generated_resources_ru.xtb index 6d2389b..033d186 100644 --- a/chrome/app/resources/generated_resources_ru.xtb +++ b/chrome/app/resources/generated_resources_ru.xtb
@@ -4074,6 +4074,7 @@ <translation id="5265562206369321422">Не в Сети больше недели</translation> <translation id="5265797726250773323">Ошибка при установке</translation> <translation id="5266113311903163739">Ошибка при импорте Центра сертификации</translation> +<translation id="526622169288322445">Другие действия с адресом <ph name="ADDRESS_SUMMARY" /></translation> <translation id="5269977353971873915">Печать не выполнена</translation> <translation id="5275352920323889391">Собака</translation> <translation id="527605982717517565">Всегда разрешать JavaScript для сайта <ph name="HOST" /></translation> @@ -5453,6 +5454,7 @@ <translation id="6775163072363532304">Здесь будут появляться доступные устройства.</translation> <translation id="6777817260680419853">Попытка переадресации заблокирована</translation> <translation id="6778737459546443941">Ещё не одобрено родителем</translation> +<translation id="6779092717724412415">Чтобы задать такое же выделение, выберите текст и нажмите на него правой кнопкой мыши.</translation> <translation id="6779447100905857289">корзины</translation> <translation id="677965093459947883">Очень мелкий</translation> <translation id="6781005693196527806">&Управление поисковыми системами…</translation> @@ -6082,7 +6084,6 @@ <translation id="7433708794692032816">Не вынимайте смарт-карту, чтобы и дальше использовать <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Оставить так</translation> <translation id="7434509671034404296">Разработчикам</translation> -<translation id="7434635829372401939">Синхронизация настроек</translation> <translation id="7434757724413878233">Ускорение мыши</translation> <translation id="7434969625063495310">Не удалось добавить сервер печати. Проверьте его настройки и повторите попытку.</translation> <translation id="7436921188514130341">При изменении названия произошла ошибка.</translation> @@ -6268,6 +6269,7 @@ <translation id="7625823789272218216">Новая вкладка слева</translation> <translation id="7628201176665550262">Частота обновления</translation> <translation id="7629827748548208700">Вкладка: <ph name="TAB_NAME" /></translation> +<translation id="7630426712700473382">Этим устройством управляет <ph name="MANAGER" />. Необходимо каждый раз входить в аккаунт.</translation> <translation id="7631014249255418691">Резервная копия приложений и файлов Linux сохранена.</translation> <translation id="7631205654593498032">После подключения устройство <ph name="DEVICE_TYPE" /> сможет:</translation> <translation id="7631887513477658702">Всегда открывать файлы этого типа</translation>
diff --git a/chrome/app/resources/generated_resources_si.xtb b/chrome/app/resources/generated_resources_si.xtb index 15f253a..be613041 100644 --- a/chrome/app/resources/generated_resources_si.xtb +++ b/chrome/app/resources/generated_resources_si.xtb
@@ -6104,7 +6104,6 @@ <translation id="7433708794692032816">ඔබගේ <ph name="DEVICE_TYPE" /> භාවිත කිරීම දිගටම සිදු කිරීමට ස්මාර්ට් කාඩ්පත ඇතුළු කරන්න</translation> <translation id="7433957986129316853">එය තබා ගන්න</translation> <translation id="7434509671034404296">සංවර්ධක</translation> -<translation id="7434635829372401939">ඔබේ සැකසීම් සමමුහූර්ත කරන්න</translation> <translation id="7434757724413878233">මූසික ත්වරණය</translation> <translation id="7434969625063495310">මුද්රණ සේවාදායකය එක් කළ නොහැකි විය. සේවාදායකයේ වින්යාසය පරීක්ෂා කර නැවත උත්සාහ කරන්න.</translation> <translation id="7436921188514130341">අනේ, අපොයි! යළි නම් කිරීමේ දී ගැටලුවක් ඇති විය.</translation>
diff --git a/chrome/app/resources/generated_resources_sk.xtb b/chrome/app/resources/generated_resources_sk.xtb index e500f22..390ad42 100644 --- a/chrome/app/resources/generated_resources_sk.xtb +++ b/chrome/app/resources/generated_resources_sk.xtb
@@ -6103,7 +6103,6 @@ <translation id="7433708794692032816">Ak chcete naďalej používať zariadenie <ph name="DEVICE_TYPE" />, vložte čipovú kartu</translation> <translation id="7433957986129316853">Ponechať</translation> <translation id="7434509671034404296">Vývojár</translation> -<translation id="7434635829372401939">Synchronizácia vašich nastavení</translation> <translation id="7434757724413878233">Zrýchlenie myši</translation> <translation id="7434969625063495310">Tlačový server sa nepodarilo pridať. Skontrolujte jeho konfiguráciu a skúste to znova.</translation> <translation id="7436921188514130341">Ojoj! Pri premenovaní sa vyskytla chyba.</translation>
diff --git a/chrome/app/resources/generated_resources_sl.xtb b/chrome/app/resources/generated_resources_sl.xtb index 009bbf6..e78369a 100644 --- a/chrome/app/resources/generated_resources_sl.xtb +++ b/chrome/app/resources/generated_resources_sl.xtb
@@ -6123,7 +6123,6 @@ <translation id="7433708794692032816">Vstavite pametno kartico, če želite še naprej uporabljati napravo <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Ohrani</translation> <translation id="7434509671034404296">Razvijalec</translation> -<translation id="7434635829372401939">Sinhroniziranje nastavitev</translation> <translation id="7434757724413878233">Pospeševanje miške</translation> <translation id="7434969625063495310">Tiskalnega strežnika ni bilo mogoče dodati. Preverite konfiguracijo strežnika in poskusite znova.</translation> <translation id="7436921188514130341">Ti šment! Napaka med preimenovanjem.</translation>
diff --git a/chrome/app/resources/generated_resources_sq.xtb b/chrome/app/resources/generated_resources_sq.xtb index 65aaffb1..ed6a318 100644 --- a/chrome/app/resources/generated_resources_sq.xtb +++ b/chrome/app/resources/generated_resources_sq.xtb
@@ -6062,7 +6062,6 @@ <translation id="7433708794692032816">Fut kartën smart për të vazhduar përdorimin e pajisjes sate <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Mbaje</translation> <translation id="7434509671034404296">Zhvilluesi</translation> -<translation id="7434635829372401939">Sinkronizo cilësimet e tua</translation> <translation id="7434757724413878233">Përshpejtimi i miut</translation> <translation id="7434969625063495310">Serveri i printimit nuk mund të shtohej. Kontrollo konfigurimin e serverit dhe provo përsëri.</translation> <translation id="7436921188514130341">Mos! Pati një gabim gjatë riemërtimit.</translation>
diff --git a/chrome/app/resources/generated_resources_sr-Latn.xtb b/chrome/app/resources/generated_resources_sr-Latn.xtb index c6aac40..1c554eb 100644 --- a/chrome/app/resources/generated_resources_sr-Latn.xtb +++ b/chrome/app/resources/generated_resources_sr-Latn.xtb
@@ -2346,6 +2346,7 @@ <translation id="3413122095806433232">CA izdavaoci: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">Veličina:</translation> <translation id="3414966631182382431"><ph name="BEGIN_LINK" />Pregledačem upravlja<ph name="END_LINK" /> <ph name="MANAGER" /></translation> +<translation id="341589277604221596">Titl uživo – <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">Uvek prikazuj URL-ove u celosti</translation> <translation id="3417835166382867856">Pretražite kartice</translation> <translation id="3417836307470882032">24-časovno vreme</translation> @@ -6097,7 +6098,6 @@ <translation id="7433708794692032816">Umetnite pametnu karticu da biste nastavili da koristite <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Zadrži</translation> <translation id="7434509671034404296">Programer</translation> -<translation id="7434635829372401939">Sinhronizujte podešavanja</translation> <translation id="7434757724413878233">Ubrzavanje miša</translation> <translation id="7434969625063495310">Dodavanje servera za štampanje nije uspelo. Proverite konfiguraciju servera i probajte ponovo.</translation> <translation id="7436921188514130341">O, ne! Došlo je do greške tokom promene naziva.</translation> @@ -7179,6 +7179,7 @@ <translation id="8540136935098276800">Unesite ispravno formatiran URL</translation> <translation id="8540503336857689453">Ne preporučuje se korišćenje skrivene mreže iz bezbednosnih razloga.</translation> <translation id="854071720451629801">Označi kao pročitano</translation> +<translation id="8540942859441851323">Dobavljač zahteva roming</translation> <translation id="8541462173655894684">Nije pronađen nijedan štampač sa servera za štampanje</translation> <translation id="8541838361296720865">Pritisnite prekidač ili taster na tastaturi da biste ga dodelili radnji <ph name="ACTION" /></translation> <translation id="8542618328173222274">Pitaj kada sajt želi da koristi uređaje i podatke virtuelne realnosti</translation>
diff --git a/chrome/app/resources/generated_resources_sr.xtb b/chrome/app/resources/generated_resources_sr.xtb index 5642eda4..7513da3 100644 --- a/chrome/app/resources/generated_resources_sr.xtb +++ b/chrome/app/resources/generated_resources_sr.xtb
@@ -2346,6 +2346,7 @@ <translation id="3413122095806433232">CA издаваоци: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">Величина:</translation> <translation id="3414966631182382431"><ph name="BEGIN_LINK" />Прегледачем управља<ph name="END_LINK" /> <ph name="MANAGER" /></translation> +<translation id="341589277604221596">Титл уживо – <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">Увек приказуј URL-ове у целости</translation> <translation id="3417835166382867856">Претражите картице</translation> <translation id="3417836307470882032">24-часовно време</translation> @@ -6097,7 +6098,6 @@ <translation id="7433708794692032816">Уметните паметну картицу да бисте наставили да користите <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Задржи</translation> <translation id="7434509671034404296">Програмер</translation> -<translation id="7434635829372401939">Синхронизујте подешавања</translation> <translation id="7434757724413878233">Убрзавање миша</translation> <translation id="7434969625063495310">Додавање сервера за штампање није успело. Проверите конфигурацију сервера и пробајте поново.</translation> <translation id="7436921188514130341">О, не! Дошло је до грешке током промене назива.</translation> @@ -7179,6 +7179,7 @@ <translation id="8540136935098276800">Унесите исправно форматиран URL</translation> <translation id="8540503336857689453">Не препоручује се коришћење скривене мреже из безбедносних разлога.</translation> <translation id="854071720451629801">Означи као прочитано</translation> +<translation id="8540942859441851323">Добављач захтева роминг</translation> <translation id="8541462173655894684">Није пронађен ниједан штампач са сервера за штампање</translation> <translation id="8541838361296720865">Притисните прекидач или тастер на тастатури да бисте га доделили радњи <ph name="ACTION" /></translation> <translation id="8542618328173222274">Питај када сајт жели да користи уређаје и податке виртуелне реалности</translation>
diff --git a/chrome/app/resources/generated_resources_sv.xtb b/chrome/app/resources/generated_resources_sv.xtb index 1189a46..8fb507e3 100644 --- a/chrome/app/resources/generated_resources_sv.xtb +++ b/chrome/app/resources/generated_resources_sv.xtb
@@ -2410,6 +2410,7 @@ <translation id="3449393517661170867">Nytt fönster med flikar</translation> <translation id="3449839693241009168">Tryck på <ph name="SEARCH_KEY" /> om du vill skicka kommandon till <ph name="EXTENSION_NAME" /></translation> <translation id="3450157232394774192">Kapacitetsprocentsats för inaktivitet</translation> +<translation id="3450180775417907283"><ph name="MANAGER" /> kräver att du ansluter till wifi och laddar ned en uppdatering nu.</translation> <translation id="3451753556629288767">Får öppna vissa filtyper</translation> <translation id="3452999110156026232">Föräldraåtkomst</translation> <translation id="3453612417627951340">Auktorisering behövs</translation> @@ -4098,6 +4099,7 @@ <translation id="5265562206369321422">Offline i mer än en vecka</translation> <translation id="5265797726250773323">Ett fel uppstod under installationen</translation> <translation id="5266113311903163739">Fel vid import av certifikatutfärdare</translation> +<translation id="526622169288322445">Fler åtgärder för <ph name="ADDRESS_SUMMARY" /></translation> <translation id="5269977353971873915">Det gick inte att skriva ut dokumentet</translation> <translation id="5275352920323889391">Hund</translation> <translation id="527605982717517565">Tillåt alltid JavaScript på <ph name="HOST" /></translation> @@ -4279,6 +4281,7 @@ <translation id="5472627187093107397">Spara lösenord för den här webbplatsen</translation> <translation id="5473075389972733037">IBM</translation> <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{Pinkoden måste innehålla minst ett tecken}other{Pinkoden måste innehålla minst # tecken}}</translation> +<translation id="5474859849784484111"><ph name="MANAGER" /> kräver att du ansluter till wifi och laddar ned en uppdatering nu. Du kan även ladda ned via en anslutning med datapriser (avgifter kan tillkomma).</translation> <translation id="5481273127572794904">Får inte ladda ned flera filer automatiskt</translation> <translation id="5481941284378890518">Lägg till skrivare i närheten</translation> <translation id="5483785310822538350">Återkalla åtkomst till enheten och filer</translation> @@ -4704,6 +4707,7 @@ <translation id="592880897588170157">Ladda ned PDF-filer i stället för att låta dem öppnas automatiskt i Chrome</translation> <translation id="592919310198008711">När jag klickar på tillägget</translation> <translation id="5932124097031739492">Linux har uppgraderats.</translation> +<translation id="5932209916647644605"><ph name="MANAGER" /> kräver att du uppdaterar din <ph name="DEVICE_TYPE" /> omedelbart.</translation> <translation id="5932224571077948991">Påträngande eller vilseledande annonser visas på webbplatsen</translation> <translation id="59324397759951282">USB-enhet från <ph name="MANUFACTURER_NAME" /></translation> <translation id="5932441198730183141">Du har inte tillräckligt många licenser tillgängliga för att registrera den här maskinvaruenheten för Google Meet. Kontakta säljavdelningen om du vill köpa fler. Om du anser att detta meddelande visas på felaktig grund kontaktar du supporten.</translation> @@ -5480,6 +5484,7 @@ <translation id="6775163072363532304">Tillgängliga enheter visas här.</translation> <translation id="6777817260680419853">Omdirigeringen blockerades</translation> <translation id="6778737459546443941">Din förälder har inte godkänt den ännu</translation> +<translation id="6779092717724412415">Om du vill lyfta fram text på det här sättet markerar du texten och högerklickar.</translation> <translation id="6779447100905857289">dina kundvagnar</translation> <translation id="677965093459947883">Mycket liten</translation> <translation id="6781005693196527806">&Hantera sökmotorer …</translation> @@ -6109,7 +6114,6 @@ <translation id="7433708794692032816">Sätt i smartkort för att fortsätta använda din <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">Behåll den</translation> <translation id="7434509671034404296">Utvecklare</translation> -<translation id="7434635829372401939">Synkronisera inställningar</translation> <translation id="7434757724413878233">Musacceleration</translation> <translation id="7434969625063495310">Det gick inte att lägga till utskriftsservern. Kontrollera serverns konfiguration och försök igen.</translation> <translation id="7436921188514130341">Ett fel uppstod när namnet skulle bytas.</translation> @@ -6296,6 +6300,7 @@ <translation id="7625823789272218216">Ny flik till vänster</translation> <translation id="7628201176665550262">Uppdateringsfrekvens</translation> <translation id="7629827748548208700">Flik: <ph name="TAB_NAME" /></translation> +<translation id="7630426712700473382">Den här enheten hanteras av <ph name="MANAGER" /> och du måste logga in varje gång.</translation> <translation id="7631014249255418691">Säkerhetskopieringen av Linux-appar och Linux-filer är klar</translation> <translation id="7631205654593498032">När du ansluter enheter godkänner du att <ph name="DEVICE_TYPE" /> kan</translation> <translation id="7631887513477658702">Öppna &alltid filer av denna typ</translation>
diff --git a/chrome/app/resources/generated_resources_sw.xtb b/chrome/app/resources/generated_resources_sw.xtb index cbd6e0e..ee9b259e 100644 --- a/chrome/app/resources/generated_resources_sw.xtb +++ b/chrome/app/resources/generated_resources_sw.xtb
@@ -6109,7 +6109,6 @@ <translation id="7433708794692032816">Weka kadi mahiri ili uendelee kutumia <ph name="DEVICE_TYPE" /> yako</translation> <translation id="7433957986129316853">Usibadilishe</translation> <translation id="7434509671034404296">Wasanidi Programu</translation> -<translation id="7434635829372401939">Sawazisha mipangilio yako</translation> <translation id="7434757724413878233">Kuongeza kasi ya kipanya</translation> <translation id="7434969625063495310">Imeshindwa kuweka seva ya kuchapisha. Tafadhali kagua mipangilio ya seva yako kisha ujaribu tena.</translation> <translation id="7436921188514130341">Samahani. Hitilafu imetokea wakati wa kubadilisha jina.</translation>
diff --git a/chrome/app/resources/generated_resources_ta.xtb b/chrome/app/resources/generated_resources_ta.xtb index 6755364..01bdf2d 100644 --- a/chrome/app/resources/generated_resources_ta.xtb +++ b/chrome/app/resources/generated_resources_ta.xtb
@@ -2362,6 +2362,7 @@ <translation id="3413122095806433232">CA வழங்குநர்கள்: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">அளவு:</translation> <translation id="3414966631182382431"><ph name="MANAGER" /> உங்கள் <ph name="BEGIN_LINK" />உலாவியை நிர்வகிக்கிறது<ph name="END_LINK" /></translation> +<translation id="341589277604221596">உடனடி வசனம் - <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">முழு URLகளை எப்போதும் காட்டு</translation> <translation id="3417835166382867856">தாவல்களைத் தேடும்</translation> <translation id="3417836307470882032">ராணுவ நேரம்</translation> @@ -6115,7 +6116,6 @@ <translation id="7433708794692032816"><ph name="DEVICE_TYPE" /> சாதனத்தைத் தொடர்ந்து பயன்படுத்த ஸ்மார்ட் கார்டைச் செருகுங்கள்</translation> <translation id="7433957986129316853">ரத்துசெய்ய வேண்டாம்</translation> <translation id="7434509671034404296">டெவலப்பர்</translation> -<translation id="7434635829372401939">உங்கள் அமைப்புகளை ஒத்திசைத்தல்</translation> <translation id="7434757724413878233">மவுஸ் ஆக்ஸிலரேஷன்</translation> <translation id="7434969625063495310">பிரிண்ட் சேவையகத்தைச் சேர்க்க முடியவில்லை. உங்கள் சேவையகத்தின் உள்ளமைவைச் சரிபார்த்துவிட்டு மீண்டும் முயலவும்.</translation> <translation id="7436921188514130341">அச்சச்சோ! பெயரை மாற்றும் போது பிழை ஏற்பட்டது.</translation> @@ -7198,6 +7198,7 @@ <translation id="8540136935098276800">சரியான வடிவமைப்பில் URLலை உள்ளிடவும்</translation> <translation id="8540503336857689453">பாதுகாப்புக் காரணங்களுக்காக மறைக்கப்பட்ட நெட்வொர்க்கைப் பயன்படுத்துவது பரிந்துரைக்கப்படவில்லை.</translation> <translation id="854071720451629801">படித்ததாகக் குறி</translation> +<translation id="8540942859441851323">நெட்வொர்க் வழங்குநருக்கு ரோமிங் தேவை</translation> <translation id="8541462173655894684">பிரிண்ட் சேவையகத்தில் எந்தப் பிரிண்டர்களும் இல்லை</translation> <translation id="8541838361296720865">ஸ்விட்ச்சையோ கீபோர்டு பட்டனையோ “<ph name="ACTION" />” என்பதற்கு ஒதுக்க, அதை அழுத்தவும்</translation> <translation id="8542618328173222274">விர்ச்சுவல் ரியாலிட்டி சாதனத்தையும் தரவையும் தளங்கள் பயன்படுத்த விரும்பினால் அனுமதி கேள்</translation>
diff --git a/chrome/app/resources/generated_resources_te.xtb b/chrome/app/resources/generated_resources_te.xtb index 9d63a24..be07e8b 100644 --- a/chrome/app/resources/generated_resources_te.xtb +++ b/chrome/app/resources/generated_resources_te.xtb
@@ -6117,7 +6117,6 @@ <translation id="7433708794692032816">మీ <ph name="DEVICE_TYPE" />ను ఉపయోగిస్తూ ఉండటానికి స్మార్ట్ కార్డ్ను ఇన్సర్ట్ చేయండి</translation> <translation id="7433957986129316853">అలాగే ఉంచండి</translation> <translation id="7434509671034404296">డెవలపర్</translation> -<translation id="7434635829372401939">మీ సెట్టింగ్లను సింక్ చేయండి</translation> <translation id="7434757724413878233">మౌస్ యాక్సిలరేషన్</translation> <translation id="7434969625063495310">ప్రింట్ సర్వర్ని జోడించడం సాధ్యపడలేదు. దయచేసి సర్వర్ కాన్ఫిగరేషన్ తనిఖీ చేసుకుని, ఆపై మళ్లీ ప్రయత్నించండి.</translation> <translation id="7436921188514130341">అయ్యో! పేరు మారుస్తున్నప్పుడు ఎర్రర్ ఏర్పడింది.</translation>
diff --git a/chrome/app/resources/generated_resources_th.xtb b/chrome/app/resources/generated_resources_th.xtb index b5638ca..b67cba2af 100644 --- a/chrome/app/resources/generated_resources_th.xtb +++ b/chrome/app/resources/generated_resources_th.xtb
@@ -6077,7 +6077,6 @@ <translation id="7433708794692032816">เสียบสมาร์ทการ์ดเพื่อให้ใช้ <ph name="DEVICE_TYPE" /> ได้ต่อไป</translation> <translation id="7433957986129316853">เก็บไว้</translation> <translation id="7434509671034404296">นักพัฒนา</translation> -<translation id="7434635829372401939">ซิงค์การตั้งค่า</translation> <translation id="7434757724413878233">การเร่งความเร็วเมาส์</translation> <translation id="7434969625063495310">เพิ่มเซิร์ฟเวอร์การพิมพ์ไม่ได้ โปรดตรวจสอบการกำหนดค่าของเซิร์ฟเวอร์แล้วลองอีกครั้ง</translation> <translation id="7436921188514130341">แย่จัง! เกิดข้อผิดพลาดในระหว่างการตั้งชื่อ</translation>
diff --git a/chrome/app/resources/generated_resources_tr.xtb b/chrome/app/resources/generated_resources_tr.xtb index 2724363..a83055d7 100644 --- a/chrome/app/resources/generated_resources_tr.xtb +++ b/chrome/app/resources/generated_resources_tr.xtb
@@ -1220,6 +1220,7 @@ <translation id="2232751457155581899">Siteler, kameranızın konumunu izlemek isteyebilir</translation> <translation id="2232876851878324699">Dosya bir sertifika içeriyordu ve bu sertifika içe aktarılmadı:</translation> <translation id="2233502537820838181">&Daha fazla bilgi</translation> +<translation id="223356358902285214">Web ve Uygulama Etkinliği</translation> <translation id="2234876718134438132">Senkronizasyon ve Google hizmetleri</translation> <translation id="2235344399760031203">Üçüncü taraf çerezler engellendi</translation> <translation id="2238379619048995541">Frekans Durumu Verileri</translation> @@ -1905,6 +1906,7 @@ <translation id="2923006468155067296"><ph name="DEVICE_TYPE" /> cihazınız şimdi kilitlenecek. <ph name="DOMAIN" />, akıllı kartınızın takılı kalmasını gerektiriyor.</translation> <translation id="2923234477033317484">Bu hesabı kaldır</translation> +<translation id="2923644930701689793">Telefonunuzun film rulosuna erişin</translation> <translation id="2926085873880284723">Varsayılan kısayolları geri yükle</translation> <translation id="2926620265753325858"><ph name="DEVICE_NAME" /> desteklenmiyor.</translation> <translation id="2927017729816812676">Önbellek Depolama Alanı</translation> @@ -2393,6 +2395,7 @@ <translation id="3449393517661170867">Sekmeli yeni pencere</translation> <translation id="3449839693241009168">Komutları <ph name="EXTENSION_NAME" /> uygulamasına göndermek için <ph name="SEARCH_KEY" /> tuşuna basın</translation> <translation id="3450157232394774192">Boşta Kalma Durumu Kullanma Yüzdesi</translation> +<translation id="3450180775417907283"><ph name="MANAGER" />, şimdi kablosuz ağa bağlanarak bir güncelleme indirmenizi gerektiriyor.</translation> <translation id="3451753556629288767">Dosya türlerini açmasına izin verilen siteler</translation> <translation id="3452999110156026232">Ebeveyn Erişimi</translation> <translation id="3453612417627951340">Yetkilendirme gerektiriyor</translation> @@ -3096,6 +3099,7 @@ <translation id="4168015872538332605"><ph name="PRIMARY_EMAIL" /> kullanıcısına ait bazı ayarlar sizinle paylaşılıyor. Bu ayarlar sadece çoklu oturum açma işlevi kullanılırken hesabınızı etkiler.</translation> <translation id="4169535189173047238">İzin verme</translation> <translation id="4170314459383239649">Çıkışta Temizle</translation> +<translation id="417096670996204801">Profil seçin</translation> <translation id="4175137578744761569">Açık mor ve beyaz</translation> <translation id="4175737294868205930">Kalıcı depolama</translation> <translation id="4176463684765177261">Devre dışı</translation> @@ -4262,6 +4266,7 @@ <translation id="5472627187093107397">Bu site için şifreleri kaydet</translation> <translation id="5473075389972733037">IBM</translation> <translation id="5473156705047072749">{NUM_CHARACTERS,plural, =1{PIN en az bir karakter olmalıdır}other{PIN en az # karakter olmalıdır}}</translation> +<translation id="5474859849784484111"><ph name="MANAGER" />, şimdi kablosuz ağa bağlanarak bir güncelleme indirmenizi gerektiriyor. İsterseniz sayaçlı bir bağlantı üzerinden indirebilirsiniz (bunun için ödeme alınabilir).</translation> <translation id="5481273127572794904">Birden fazla dosyayı otomatik olarak indirmesine izin verilmeyen siteler</translation> <translation id="5481941284378890518">Yakınlardaki Yazıcıları Ekle</translation> <translation id="5483785310822538350">Dosya ve cihaz erişimini iptal et</translation> @@ -4688,6 +4693,7 @@ <translation id="592880897588170157">PDF dosyalarını Chrome'da otomatik olarak açmak yerine indir</translation> <translation id="592919310198008711">Uzantıyı tıkladığımda</translation> <translation id="5932124097031739492">Linux başarıyla yeni sürüme geçirildi.</translation> +<translation id="5932209916647644605"><ph name="MANAGER" />, hemen <ph name="DEVICE_TYPE" /> cihazınızı güncellemenizi gerektiriyor.</translation> <translation id="5932224571077948991">Site, araya giren veya yanıltıcı reklamlar gösteriyor</translation> <translation id="59324397759951282"><ph name="MANUFACTURER_NAME" /> marka USB cihaz</translation> <translation id="5932441198730183141">Bu Google Meet hardware cihazını kaydetmek için yeterli kullanılabilir lisansa sahip değilsiniz. Daha fazla lisans satın almak için lütfen satış temsilcisiyle iletişime geçin. Bu mesajın yanlışlıkla görüntülendiğini düşünüyorsanız lütfen destek birimiyle bağlantı kurun.</translation> @@ -6094,7 +6100,6 @@ <translation id="7433708794692032816"><ph name="DEVICE_TYPE" /> cihazınızı kullanmaya devam etmek için akıllı kartı takın</translation> <translation id="7433957986129316853">Değişiklikleri koru</translation> <translation id="7434509671034404296">Geliştirici</translation> -<translation id="7434635829372401939">Ayarlarınızı senkronize edin</translation> <translation id="7434757724413878233">Fare hızlandırması</translation> <translation id="7434969625063495310">Yazdırma sunucusu eklenemedi. Lütfen sunucunun yapılandırmasını kontrol edip tekrar deneyin.</translation> <translation id="7436921188514130341">Hay aksi! Yeniden adlandırma sırasında bir hata oluştu.</translation>
diff --git a/chrome/app/resources/generated_resources_uk.xtb b/chrome/app/resources/generated_resources_uk.xtb index 46a3fa4..870e26b2 100644 --- a/chrome/app/resources/generated_resources_uk.xtb +++ b/chrome/app/resources/generated_resources_uk.xtb
@@ -2358,6 +2358,7 @@ <translation id="3413122095806433232">Видавці ЦС: <ph name="LOCATION" /></translation> <translation id="3414952576877147120">Розмір:</translation> <translation id="3414966631182382431">Вашим <ph name="BEGIN_LINK" />веб-переглядачем керує<ph name="END_LINK" /> <ph name="MANAGER" /></translation> +<translation id="341589277604221596">Живі субтитри – <ph name="LANGUAGE" /></translation> <translation id="3416468988018290825">Завжди показувати повні URL-адреси</translation> <translation id="3417835166382867856">Шукати вкладки</translation> <translation id="3417836307470882032">24-годинний формат часу</translation> @@ -6099,7 +6100,6 @@ <translation id="7433708794692032816">Щоб далі використовувати <ph name="DEVICE_TYPE" />, вставте розумну картку</translation> <translation id="7433957986129316853">Залишити</translation> <translation id="7434509671034404296">Для розробників</translation> -<translation id="7434635829372401939">Синхронізація налаштувань</translation> <translation id="7434757724413878233">Прискорення миші</translation> <translation id="7434969625063495310">Не вдалося додати сервер для друку. Перевірте його налаштування й повторіть спробу.</translation> <translation id="7436921188514130341">От халепа! Сталася помилка під час перейменування.</translation> @@ -7179,6 +7179,7 @@ <translation id="8540136935098276800">Введіть URL-адресу правильного формату</translation> <translation id="8540503336857689453">З міркувань безпеки ми не радимо використовувати приховану мережу.</translation> <translation id="854071720451629801">Позначити як прочитане</translation> +<translation id="8540942859441851323">Постачальник вимагає ввімкнути мобільний Інтернет у роумінгу</translation> <translation id="8541462173655894684">На сервері друку немає принтерів</translation> <translation id="8541838361296720865">Натисніть перемикач або клавішу клавіатури, щоб призначити їх дії "<ph name="ACTION" />"</translation> <translation id="8542618328173222274">Запитувати, коли сайт хоче отримати доступ до даних або пристроїв віртуальної реальності</translation>
diff --git a/chrome/app/resources/generated_resources_ur.xtb b/chrome/app/resources/generated_resources_ur.xtb index 2c4508b..afac7f7 100644 --- a/chrome/app/resources/generated_resources_ur.xtb +++ b/chrome/app/resources/generated_resources_ur.xtb
@@ -6099,7 +6099,6 @@ <translation id="7433708794692032816">اپنے <ph name="DEVICE_TYPE" /> کا استعمال جاری رکھنے کیلئے سمارٹ کارڈ داخل کریں</translation> <translation id="7433957986129316853">اسے رکھیں</translation> <translation id="7434509671034404296">ڈویلپر</translation> -<translation id="7434635829372401939">اپنی ترتیبات کو مطابقت پذیر بنائیں</translation> <translation id="7434757724413878233">ماؤس کا ایکسیلریشن</translation> <translation id="7434969625063495310">پرنٹ سرور شامل نہیں کر سکا۔ براہ کرم سرور کی کنفیگریشن کو چیک کریں اور دوبارہ کوشش کریں۔</translation> <translation id="7436921188514130341">افوہ! نام کی تبدیلی کے دوران ایک خرابی تھی۔</translation>
diff --git a/chrome/app/resources/generated_resources_uz.xtb b/chrome/app/resources/generated_resources_uz.xtb index 946d2e5..25788ecc 100644 --- a/chrome/app/resources/generated_resources_uz.xtb +++ b/chrome/app/resources/generated_resources_uz.xtb
@@ -6106,7 +6106,6 @@ <translation id="7433708794692032816"><ph name="DEVICE_TYPE" /> qurilmasidan foydalanishda davom etish uchun smart kartani kiriting</translation> <translation id="7433957986129316853">Saqlab qolinsin</translation> <translation id="7434509671034404296">Dasturchilar uchun</translation> -<translation id="7434635829372401939">Sozlamalarni sinxronlash</translation> <translation id="7434757724413878233">Sichqonchani tezlatish</translation> <translation id="7434969625063495310">Bosma server kiritilmadi. Server sozlamalarini tekshiring va qaytadan urining.</translation> <translation id="7436921188514130341">Ana xolos! Nomni o‘zgartirishda xatolik yuz berdi.</translation>
diff --git a/chrome/app/resources/generated_resources_vi.xtb b/chrome/app/resources/generated_resources_vi.xtb index a43aeff..5f6b3be 100644 --- a/chrome/app/resources/generated_resources_vi.xtb +++ b/chrome/app/resources/generated_resources_vi.xtb
@@ -6092,7 +6092,6 @@ <translation id="7433708794692032816">Lắp thẻ thông minh để tiếp tục sử dụng <ph name="DEVICE_TYPE" /> của bạn</translation> <translation id="7433957986129316853">Giữ nguyên</translation> <translation id="7434509671034404296">Nhà phát triển</translation> -<translation id="7434635829372401939">Đồng bộ hóa các tùy chọn cài đặt của bạn</translation> <translation id="7434757724413878233">Tăng tốc chuột</translation> <translation id="7434969625063495310">Không thể thêm máy chủ máy in. Vui lòng kiểm tra cấu hình của máy chủ rồi thử lại.</translation> <translation id="7436921188514130341">Ôi, hỏng! Đã xảy ra lỗi trong khi đổi tên.</translation>
diff --git a/chrome/app/resources/generated_resources_zh-CN.xtb b/chrome/app/resources/generated_resources_zh-CN.xtb index eb1a415e..9025d08 100644 --- a/chrome/app/resources/generated_resources_zh-CN.xtb +++ b/chrome/app/resources/generated_resources_zh-CN.xtb
@@ -6093,7 +6093,6 @@ <translation id="7433708794692032816">插入智能卡以继续使用您的 <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">保持现状</translation> <translation id="7434509671034404296">开发者</translation> -<translation id="7434635829372401939">同步您的设置</translation> <translation id="7434757724413878233">鼠标加速</translation> <translation id="7434969625063495310">无法添加打印服务器。请检查服务器的配置,然后重试。</translation> <translation id="7436921188514130341">糟糕!重命名过程中出错了。</translation>
diff --git a/chrome/app/resources/generated_resources_zh-HK.xtb b/chrome/app/resources/generated_resources_zh-HK.xtb index 5a6a4b3..38ac8da 100644 --- a/chrome/app/resources/generated_resources_zh-HK.xtb +++ b/chrome/app/resources/generated_resources_zh-HK.xtb
@@ -6118,7 +6118,6 @@ <translation id="7433708794692032816">插入智能卡才能繼續使用 <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">保留</translation> <translation id="7434509671034404296">開發人員</translation> -<translation id="7434635829372401939">同步您的設定</translation> <translation id="7434757724413878233">滑鼠加速</translation> <translation id="7434969625063495310">無法新增列印伺服器。請檢查伺服器設定,然後再試一次。</translation> <translation id="7436921188514130341">很抱歉!重新命名過程中發生錯誤。</translation> @@ -7201,7 +7200,7 @@ <translation id="8540136935098276800">請輸入正確格式的網址</translation> <translation id="8540503336857689453">基於安全理由,建議您不要使用隱藏的網絡。</translation> <translation id="854071720451629801">標示為已讀</translation> -<translation id="8540942859441851323">服務供應商要求使用漫遊服務</translation> +<translation id="8540942859441851323">供應商要求漫遊</translation> <translation id="8541462173655894684">在列印伺服器中找不到任何打印機</translation> <translation id="8541838361296720865">按下按鈕裝置或鍵盤按鍵,即可指派為「<ph name="ACTION" />」</translation> <translation id="8542618328173222274">在網站要求使用您的虛擬實境裝置和資料時詢問您</translation>
diff --git a/chrome/app/resources/generated_resources_zh-TW.xtb b/chrome/app/resources/generated_resources_zh-TW.xtb index 821aba1..9d6e2d6 100644 --- a/chrome/app/resources/generated_resources_zh-TW.xtb +++ b/chrome/app/resources/generated_resources_zh-TW.xtb
@@ -6101,7 +6101,6 @@ <translation id="7433708794692032816">插入智慧型卡片才能繼續使用 <ph name="DEVICE_TYPE" /></translation> <translation id="7433957986129316853">保留</translation> <translation id="7434509671034404296">開發人員選項</translation> -<translation id="7434635829372401939">同步處理你的設定</translation> <translation id="7434757724413878233">滑鼠加速</translation> <translation id="7434969625063495310">無法新增列印伺服器。請檢查伺服器設定,然後再試一次。</translation> <translation id="7436921188514130341">糟糕!重新命名過程中發生錯誤。</translation>
diff --git a/chrome/app/resources/generated_resources_zu.xtb b/chrome/app/resources/generated_resources_zu.xtb index df2d2c2..d5154db0 100644 --- a/chrome/app/resources/generated_resources_zu.xtb +++ b/chrome/app/resources/generated_resources_zu.xtb
@@ -1232,6 +1232,7 @@ <translation id="2232751457155581899">Amasayithi angacela ukulandelela isimo sekhamera yakho</translation> <translation id="2232876851878324699">Ifayela belikade liqukethe isitifiketi esisodwa, esingazange singeniswe:</translation> <translation id="2233502537820838181">Olunye ulwazi</translation> +<translation id="223356358902285214">Umsebenzi wewebhu nohlelo lokusebenza</translation> <translation id="2234876718134438132">Ukuvumelanisa namasevisi e-Google</translation> <translation id="2235344399760031203">Amakhukhi enkampani yangaphandle avinjiwe</translation> <translation id="2238379619048995541">Idatha yesifunda semvamisa</translation> @@ -1921,6 +1922,7 @@ <translation id="2923006468155067296">I-<ph name="DEVICE_TYPE" /> yakho izokhiywa manje. I-<ph name="DOMAIN" /> idinga ukuba ugcine ikhadi lakho elimsathi lifakiwe.</translation> <translation id="2923234477033317484">Susa le akhawunti</translation> +<translation id="2923644930701689793">Finyelela kuroli yekhamera yefoni yakho</translation> <translation id="2926085873880284723">Buyisela izinqamuleli ezizenzakalelayo</translation> <translation id="2926620265753325858">I-<ph name="DEVICE_NAME" /> ayisekelwe.</translation> <translation id="2927017729816812676">Isitoreji senqolobane</translation> @@ -3112,6 +3114,7 @@ <translation id="4168015872538332605">Ezinye izilungiselelo ze-<ph name="PRIMARY_EMAIL" /> zabiwa nawe. Lezi zilungiselelo zingathinta kuphela i-akhawunti yakho uma usebenzisa ukungena ngemvume okuningi.</translation> <translation id="4169535189173047238">Ungavumeli</translation> <translation id="4170314459383239649">Sula ekuphumeni</translation> +<translation id="417096670996204801">Khetha iphrofayela</translation> <translation id="4175137578744761569">Okuphephuli ngokukhanyayo nokumhlophe</translation> <translation id="4175737294868205930">Isitoreji esiqhubekayo</translation> <translation id="4176463684765177261">Kukhutshaziwe</translation> @@ -6115,7 +6118,6 @@ <translation id="7433708794692032816">Faka ikhadi elismathi ukuze uqhubeke usebenzisa i-<ph name="DEVICE_TYPE" /> yakho</translation> <translation id="7433957986129316853">Ligcine</translation> <translation id="7434509671034404296">Unjiniyela</translation> -<translation id="7434635829372401939">Vumelanisa izilungiselelo zakho</translation> <translation id="7434757724413878233">Ukushesha kwegundane</translation> <translation id="7434969625063495310">Ayikwazanga ukungeza iseva yokuphrinta. Sicela uhlole ukulungiswa kweseva bese uyazama futhi.</translation> <translation id="7436921188514130341">Hawu, iphutha! Kube nephutha ngesikhathi sokuqamba kabusha.</translation>
diff --git a/chrome/app/resources/google_chrome_strings_am.xtb b/chrome/app/resources/google_chrome_strings_am.xtb index 6cd45e8..02b855e 100644 --- a/chrome/app/resources/google_chrome_strings_am.xtb +++ b/chrome/app/resources/google_chrome_strings_am.xtb
@@ -52,6 +52,7 @@ <translation id="2123055963409958220"><ph name="BEGIN_LINK" />የአሁኖቹን ቅንብሮች<ph name="END_LINK" /> ሪፖርት በማድረግ Chromium የተሻለ እንዲሆን ያግዙ።</translation> <translation id="2151406531797534936">እባክዎ Chrome ን አሁን ዳግም ያስጀምሩ</translation> <translation id="2189289170880510015">አንዳንድ የChrome በጣም አስፈላጊ የግላዊነት ምርጫዎችን ያብጁ</translation> +<translation id="2258103955319320201">በሁሉም መሣሪያዎችዎ ላይ የእርስዎን የChrome አሳሽ ነገሮች ለመድረስ ይግቡ፣ ከዚያ ስምረትን ያብሩ</translation> <translation id="2290014774651636340">የGoogle ኤ ፒ አይ ቁልፎች ይጎድላሉ። አንዳንድ የGoogle Chrome ተግባራት ይሰናከላሉ።</translation> <translation id="2290095356545025170">እርግጠኛ ነዎት Google Chromeን ማራገፍ ይፈልጋሉ?</translation> <translation id="2309047409763057870">ይሄ ሁለተኛ የGoogle Chrome ጭነት ነው፣ እና ነባሪ አሳሽዎ ማድረግ አይቻልም።</translation> @@ -216,6 +217,7 @@ <translation id="6506909944137591434">Chrome የዙሪያዎን የ3ል ካርታ ለመፍጠር የካሜራ ፈቃድ ያስፈልገዋል</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome ግንባታ</translation> <translation id="6568793831116033768">የChrome OS ሥርዓት</translation> +<translation id="6594121454516132231">Chrome ክፍት ድርን በሚጠብቁበት ጊዜ እርስዎን ከጣቢያ-ተሻጋሪ መከታተያ ለመጠበቅ እንዴት እንደሚያቅድ ይመልከቱ</translation> <translation id="6676384891291319759">በይነመረብን ተዳረስ</translation> <translation id="6679975945624592337">Google Chrome ጀርባ ውስጥ ይሂድ</translation> <translation id="6696915334902295848">Chrome ለዚህ ጣቢያ የማይክሮፎን ፈቃድ ያስፈልገዋል</translation> @@ -230,6 +232,7 @@ <translation id="6989339256997917931">Google Chrome ተዘምኗል፣ ግን ቢያንስ ለ30 ቀኖች አልተጠቀሙበትም።</translation> <translation id="7025800014283535195">እዚህ በChrome መገለጫዎች መካከል መቀያየር ይችላሉ</translation> <translation id="7062128746136194023">የእርስዎ ወላጅ ለChrome «የጣቢያዎች፣ መተግበሪያዎች እና ቅጥያዎች ፈቃዶች»ን አጥፍተዋል። ይህን <ph name="EXTENSION_TYPE_PARAMETER" /> ማከል አይፈቀድም።</translation> +<translation id="7085332316435785646">በGoogle አገልግሎቶች ውስጥ ተጨማሪ ግላዊነት የተላበሱ ተሞክሮዎችን ለማግኘት የChrome ታሪክን ለማካተት እና ላለማካተት ይምረጡ</translation> <translation id="7088681679121566888">Chrome የተዘመነ ነው</translation> <translation id="7098166902387133879">Google Chrome የእርስዎን ማይክሮፎን እየተጠቀመ ነው።</translation> <translation id="7106741999175697885">ተግባር መሪ - Google Chrome</translation> @@ -254,6 +257,7 @@ <translation id="7651907282515937834">Chrome Enterprise አርማ</translation> <translation id="7665553140559834626">&Chrome OSን ለማዘመን ዳግም ያስነሱት</translation> <translation id="7747138024166251722">ጫኝው ጊዜያዊ ማውጫ መፍጠር አልቻለም። እባክዎ ነፃ የዲስክ ቦታ እና ሶፍትዌር የመጫን ፍቃድ እንዳለ ይፈትሹ።</translation> +<translation id="7748512868279796735">የሚከተሉት መለያዎች ለዚህ Chrome መገለጫ ይገኛሉ</translation> <translation id="7761834446675418963">Chromeን ለመክፈት እና ማሰስ ለመጀመር ስምዎን ጠቅ ያድርጉት።</translation> <translation id="7777080907402804672">አንድ ምስል ጠቃሚ መግለጫ ከሌለው Chrome ለእርስዎ አንድ ለማቅረብ ይሞክራል። ዝርዝር መግለጫዎችን ለመፍጠር፣ ምስሎች ወደ Google ይላካሉ። ይህን በማንኛውም ጊዜ በቅንብሮች ውስጥ ሊያጠፉት ይችላሉ።</translation> <translation id="7781002470561365167">የGoogle Chrome አዲስ ስሪት አለ።</translation> @@ -285,6 +289,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">ይህ የስራ መገለጫ ከግል መገለጫዎ ሙሉ ለሙሉ የተለየ ነው።</translation> <translation id="8556340503434111824">አዲስ የGoogle Chrome ስሪት አለ፣ እና ከመቼውም በበለጠ ፈጣን ነው።</translation> +<translation id="8571790202382503603">በChrome መገለጫዎች ሁሉንም የChrome ነገሮችዎን መለየት ይችላሉ። ይህ በስራ እና በመዝናኛ መካከል መከፋፈልን ቀላል ያደርገዋል።</translation> <translation id="8614913330719544658">Google Chrome መልስ አይሰጥም። አሁን ዳግም ይጀምር?</translation> <translation id="861702415419836452">Chrome የዙሪያዎ 3ል ካርታ መፍጠር እንዲችል ካሜራዎን የመድረስ ፈቃድ ያስፈልገዋል</translation> <translation id="8625237574518804553">{0,plural, =1{Chrome በ1 ደቂቃ ውስጥ ዳግም ይጀመራል}one{Chrome በ# ደቂቃዎች ውስጥ ዳግም ይጀመራል}other{Chrome በ# ደቂቃዎች ውስጥ ዳግም ይጀመራል}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_as.xtb b/chrome/app/resources/google_chrome_strings_as.xtb index 9e26a80..dc90f64d 100644 --- a/chrome/app/resources/google_chrome_strings_as.xtb +++ b/chrome/app/resources/google_chrome_strings_as.xtb
@@ -53,6 +53,7 @@ <translation id="2123055963409958220"><ph name="BEGIN_LINK" />বর্তমানৰ ছেটিংসমূহ<ph name="END_LINK" />ৰ সম্পর্কে প্ৰতিবেদন দি Chromeক উন্নত কৰাত সহায় কৰক</translation> <translation id="2151406531797534936">অনুগ্ৰহ কৰি Chrome এতিয়া ৰিষ্টাৰ্ট কৰক</translation> <translation id="2189289170880510015">Chromeৰ কিছুমান আটাইতকৈ গুৰুত্বপূৰ্ণ গোপনীয়তা সম্পৰ্কীয় বাছনি কাষ্টমাইজ কৰক</translation> +<translation id="2258103955319320201">আপোনাৰ আটাইবোৰ ডিভাইচত আপোনাৰ Chrome ব্ৰাউজাৰৰ বস্তু এক্সেছ কৰিবলৈ, ছাইন ইন কৰি তাৰ পাছত ছিংক অন কৰক</translation> <translation id="2290014774651636340">Google API কীসমূহ নাই। Google Chromeৰ কিছুমান কার্যক্ৰম অক্ষম কৰা হ’ব।</translation> <translation id="2290095356545025170">আপুনি Google Chrome আনইনষ্টল কৰিবলৈ বিচাৰে বুলি নিশ্চিতনে?</translation> <translation id="2309047409763057870">এয়া Google Chromeৰ এক গৌণ ইনষ্টলেশ্বন আৰু ইয়াক আপোনাৰ ডিফ’ল্ট ব্ৰাউজাৰ কৰিব নোৱাৰি।</translation> @@ -217,6 +218,7 @@ <translation id="6506909944137591434">আপোনাৰ ওচৰ-পাজৰৰ ঠাইসমূহৰ এখন 3D মেপ সৃষ্টি কৰিবলৈ Chromeক কেমেৰাৰ অনুমতিৰ আৱশ্যক</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6568793831116033768">Chrome OS ছিষ্টেম</translation> +<translation id="6594121454516132231">মুক্ত ৱেব সুৰক্ষিত কৰি ৰাখি ক্ৰছ-ছাইট ট্ৰেকিঙৰ পৰা আপোনাক সুৰক্ষা প্ৰদান কৰিবলৈ Chromeএ কেনেকৈ পৰিকল্পনা কৰে সেয়া চাওক</translation> <translation id="6676384891291319759">ইণ্টাৰনেট এক্সেছ কৰক</translation> <translation id="6679975945624592337">Google Chromeক নেপথ্যত চলিবলৈ দিয়ক</translation> <translation id="6696915334902295848">Chromeক এই ছাইটটোৰ বাবে মাইক্ৰ’ফ’নৰ অনুমতিৰ আৱশ্যক</translation> @@ -231,6 +233,7 @@ <translation id="6989339256997917931">Google Chrome আপডে’ট কৰা হৈছে কিন্তু যোৱা ৩০ দিন ধৰি আপুনি ইয়াক ব্যৱহাৰ কৰা নাই।</translation> <translation id="7025800014283535195">ইয়াত আপুনি Chromeৰ প্ৰ’ফাইলসমূহৰ মাজত সালসলনি কৰিব পাৰে</translation> <translation id="7062128746136194023">আপোনাৰ অভিভাৱকে Chromeৰ বাবে "ছাইট, এপ্ আৰু এক্সটেনশ্বনসমূহৰ বাবে অনুমতি" অফ কৰিছে। এই <ph name="EXTENSION_TYPE_PARAMETER" />টো যোগ দিয়াৰ অনুমতি নাই।</translation> +<translation id="7085332316435785646">Google সেৱাসমূহত অধিক ব্যক্তিগতকৃত অভিজ্ঞতা লাভ কৰিবলৈ Chromeৰ ইতিহাস অন্তৰ্ভুক্ত কৰিবনে নকৰে সেয়া বাছনি কৰক</translation> <translation id="7088681679121566888">Chrome আপ টু ডে’ট আছে</translation> <translation id="7098166902387133879">Google Chromeএ আপোনাৰ মাইক্ৰ’ফ’ন ব্যৱহাৰ কৰি আছে।</translation> <translation id="7106741999175697885">কাৰ্য পৰিচালক - Google Chrome</translation> @@ -255,6 +258,7 @@ <translation id="7651907282515937834">Chrome এণ্টাৰপ্ৰাইজৰ ল’গ’</translation> <translation id="7665553140559834626">&Chrome OS আপডে'ট কৰিবলৈ পুনৰ লঞ্চ কৰক</translation> <translation id="7747138024166251722">ইনষ্টলাৰটোৱে কোনো অস্থায়ী ডাইৰেক্ট'ৰী সৃষ্টি কৰিব নোৱাৰিলে। ছফ্টৱেৰ ইনষ্টল কৰিবলৈ অনুগ্ৰহ কৰি খালী ঠাই আৰু লগতে অনুমতি আছেনে নাই পৰীক্ষা কৰক।</translation> +<translation id="7748512868279796735">এই Chrome প্ৰ’ফাইলটোৰ বাবে তলত দিয়া একাউণ্টসমূহ উপলব্ধ</translation> <translation id="7761834446675418963">Chrome খুলিবলৈ আপোনাৰ নামত ক্লিক কৰক আৰু ব্ৰাউজিং আৰম্ভ কৰক।</translation> <translation id="7777080907402804672">যদি কোনো প্ৰতিচ্ছবিত উপযোগী বিৱৰণ নাই তেন্তে Chromeএ আপোনাক সেয়া প্ৰদান কৰিবলৈ চেষ্টা কৰিব। বিৱৰণ সৃষ্টি কৰিবলৈ প্ৰতিচ্ছবি Googleলৈ প্ৰেৰণ কৰা হয়। আপুনি যিকোনো সময়তে ছেটিঙলৈ গৈ ইয়াক অফ কৰিব পাৰে।</translation> <translation id="7781002470561365167">এটা নতুন সংস্কৰণ আছে।</translation> @@ -286,6 +290,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">এই কৰ্মস্থানৰ প্ৰ’ফাইলটো আপোনাৰ ব্যক্তিগত প্ৰ’ফাইলৰ পৰা সম্পূৰ্ণৰূপে পৃথক।</translation> <translation id="8556340503434111824">Google Chromerৰ এটা নতুন সংস্কৰণ উপলব্ধ হৈছে আৰু এইটো সকলোতকৈ দ্ৰুত।</translation> +<translation id="8571790202382503603">Chromeৰ প্ৰ’ফাইলৰ জৰিয়তে আপুনি নিজৰ আটাইবোৰ Chromeৰ বস্তু পৃথক কৰিব পাৰে। এইটোৱে কৰ্মস্থান আৰু মনোৰঞ্জনৰ মাজত বিভাজন কৰাটো অধিক সহজ কৰি তোলে।</translation> <translation id="8614913330719544658">Google Chromeএ সঁহাৰি জনোৱা নাই। এতিয়াই পুনৰ লঞ্চ কৰিবনে?</translation> <translation id="861702415419836452">আপোনাৰ চৌপাশৰ এখন 3D মেপ সৃষ্টি কৰিবলৈ Chromeক আপোনাৰ কেমেৰা এক্সেছ কৰাৰ অনুমতিৰ প্ৰয়োজন</translation> <translation id="8625237574518804553">{0,plural, =1{১ মিনিটত Chrome পুনৰ লঞ্চ হ’ব}one{# মিনিটত Chrome পুনৰ লঞ্চ হ’ব}other{# মিনিটত Chrome পুনৰ লঞ্চ হ’ব}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_bn.xtb b/chrome/app/resources/google_chrome_strings_bn.xtb index d763c9a..8e36cdf 100644 --- a/chrome/app/resources/google_chrome_strings_bn.xtb +++ b/chrome/app/resources/google_chrome_strings_bn.xtb
@@ -51,6 +51,7 @@ <translation id="2123055963409958220"><ph name="BEGIN_LINK" />বর্তমান সেটিংস<ph name="END_LINK" />-এর রিপোর্ট করে Chrome-কে আরও ভাল করে তুলতে সাহায্য করুন</translation> <translation id="2151406531797534936">এখনই Chrome রিস্টার্ট করুন</translation> <translation id="2189289170880510015">Chrome এর কিছু সবচেয়ে গুরুত্বপূর্ণ গোপনীয়তা বিকল্প কাস্টমাইজ করুন</translation> +<translation id="2258103955319320201">সব ডিভাইস জুড়ে Chrome ব্রাউজারে থাকা ডেটা অ্যাক্সেস করতে, প্রথমে সাইন-ইন করে সিঙ্ক চালু করুন।</translation> <translation id="2290014774651636340">Google এপিআই কীগুলি অনুপস্থিত৷ Google Chrome-এর কিছু বৈশিষ্ট্য নিষ্ক্রিয় হয়ে যাবে৷</translation> <translation id="2290095356545025170">আপনি কি Google Chrome আনইনস্টল করার ব্যাপারে নিষ্চিত ?</translation> <translation id="2309047409763057870">এটা Google Chrome-এর সেকেন্ডারি ইনস্টলেশন এবং একে আপনার ডিফল্ট ব্রাউজার করা যাবে না।</translation> @@ -213,6 +214,7 @@ <translation id="6506909944137591434">আপনার আশেপাশের জায়গার একটি 3D ম্যাপ তৈরি করার জন্য Chrome-এর ক্যামেরা অ্যাক্সেসের অনুমতি প্রয়োজন</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6568793831116033768">Chrome OS সিস্টেম</translation> +<translation id="6594121454516132231">Chrome কীভাবে আপনাকে ওপেন ওয়েব সুরক্ষিত করার মাধ্যমে ক্রস-সাইট ট্র্যাক করা থেকে রক্ষা করে তা দেখুন</translation> <translation id="6676384891291319759">ইন্টারনেটটি অ্যাক্সেস করুন</translation> <translation id="6679975945624592337">Google Chrome-কে ব্যাকগ্রাউন্ডে চলতে দিন</translation> <translation id="6696915334902295848">এই সাইটের জন্য Chrome-এর মাইক্রোফোন অ্যাক্সেসের অনুমতি প্রয়োজন</translation> @@ -227,6 +229,7 @@ <translation id="6989339256997917931">Google Chrome আপডেট হয়েছে তবে আপনি এটি কমপক্ষে 30 দিন যাবত ব্যবহার করেন নি৷</translation> <translation id="7025800014283535195">আপনি এখানে একটি Chrome প্রোফাইল থেকে আরেকটিতে পাল্টাতে পারেন</translation> <translation id="7062128746136194023">তোমার অভিভাবক Chrome-এ "সাইট, অ্যাপ ও এক্সটেনশনের অনুমতি" বন্ধ করে দিয়েছেন। এই <ph name="EXTENSION_TYPE_PARAMETER" /> যোগ করার অনুমতি নেই।</translation> +<translation id="7085332316435785646">Google পরিষেবাতে আরও পছন্দমতো অভিজ্ঞতার জন্য Chrome ইতিহাস অন্তর্ভুক্ত করবেন কিনা তা বেছে নিন</translation> <translation id="7088681679121566888">Chrome আপ-টু-ডেট আছে</translation> <translation id="7098166902387133879">Google Chrome আপনার মাইক্রোফোন ব্যবহার করছে৷</translation> <translation id="7106741999175697885">কার্য পরিচালক - Google Chrome</translation> @@ -251,6 +254,7 @@ <translation id="7651907282515937834">Chrome এন্টারপ্রাইজ লোগো</translation> <translation id="7665553140559834626">&Chrome OS আপডেট করতে আবার লঞ্চ করুন</translation> <translation id="7747138024166251722">ইনস্টলারটি অস্থায়ী ডাইরেক্টরি তৈরি করতে পারে নি৷ অনুগ্রহ করে খালি ডিস্ক স্পেশ এবং সফটওয়্যারটি ইনস্টল করার অনুমতি যাচাই করে নিন৷</translation> +<translation id="7748512868279796735">এই Chrome প্রোফাইলের জন্য নিম্নলিখিত অ্যাকাউন্ট উপলভ্য</translation> <translation id="7761834446675418963">Chrome খোলার জন্য আপনার নামের উপরে ক্লিক করুন এবং ব্রাউজ করা শুরু করুন৷</translation> <translation id="7777080907402804672">যদি ছবিতে প্রয়োজনীয় বিবরণ দেওয়া না থাকে, তাহলে Chrome আপনাকে একটি বিবরণ দেওয়ার চেষ্টা করবে। বিবরণ তৈরির জন্য, Google-এ ছবি পাঠানো হয়। সেটিংসে গিয়ে আপনি যেকোনও সময়ে এটি বন্ধ করতে পারেন।</translation> <translation id="7781002470561365167">Google Chrome-এর একটি নতুন ভার্সন উপলভ্য।</translation> @@ -282,6 +286,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">এই অফিস প্রোফাইল আপনার ব্যক্তিগত প্রোফাইল থেকে সম্পূর্ণ আলাদা।</translation> <translation id="8556340503434111824">Google Chrome-এর একটি নতুন ভার্সন উপলভ্য এবং এটি আগের তুলনায় দ্রুততর৷</translation> +<translation id="8571790202382503603">Chrome প্রোফাইলের সাহায্যে আপনি সব Chrome-এ থাকা ডেটা আলাদা করতে পারবেন। এর ফলে সহজেই অফিস এবং বিনোদনের প্রোফাইল আলাদা করা যায়।</translation> <translation id="8614913330719544658">Google Chrome প্রতিক্রিয়া করছে না৷ এখনই পুনঃলঞ্চ করবেন?</translation> <translation id="861702415419836452">আপনার আশেপাশের 3D ম্যাপ তৈরি করতে এই সাইটটির জন্য Chrome-কে আপনার ক্যামেরা অ্যাক্সেস করার অনুমতি দিতে হবে</translation> <translation id="8625237574518804553">{0,plural, =1{Chrome ১ মিনিটের মধ্যে আবার লঞ্চ হবে}one{Chrome # মিনিটের মধ্যে আবার লঞ্চ হবে}other{Chrome # মিনিটের মধ্যে আবার লঞ্চ হবে}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_el.xtb b/chrome/app/resources/google_chrome_strings_el.xtb index 57c8a88..d13374f 100644 --- a/chrome/app/resources/google_chrome_strings_el.xtb +++ b/chrome/app/resources/google_chrome_strings_el.xtb
@@ -51,6 +51,7 @@ <translation id="2123055963409958220">Συμβάλετε στη βελτίωση του Chrome, αναφέροντας τις <ph name="BEGIN_LINK" />τρέχουσες ρυθμίσεις<ph name="END_LINK" /></translation> <translation id="2151406531797534936">Επανεκκινήστε το Chrome τώρα</translation> <translation id="2189289170880510015">Προσαρμόστε κάποιες από τις πιο σημαντικές επιλογές απορρήτου του Chrome</translation> +<translation id="2258103955319320201">Για να έχετε πρόσβαση από όλες τις συσκευές σας στο περιεχόμενο που διαθέτετε στο πρόγραμμα περιήγησης Chrome, συνδεθείτε και, στη συνέχεια, ενεργοποιήστε τον συγχρονισμό.</translation> <translation id="2290014774651636340">Λείπουν κλειδιά του Google API. Ορισμένες λειτουργίες του Google Chrome θα απενεργοποιηθούν.</translation> <translation id="2290095356545025170">Είστε βέβαιοι ότι θέλετε να απεγκαταστήσετε του Google Chrome;</translation> <translation id="2309047409763057870">Αυτή είναι μια δευτερεύουσα εγκατάσταση του Google Chrome και δεν μπορεί να γίνει το προεπιλεγμένο πρόγραμμα περιήγησης.</translation> @@ -213,6 +214,7 @@ <translation id="6506909944137591434">Το Chrome χρειάζεται άδεια κάμερας για να δημιουργήσει έναν τρισδιάστατο χάρτη του περιβάλλοντα χώρου σας.</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6568793831116033768">Σύστημα Chrome OS</translation> +<translation id="6594121454516132231">Δείτε πώς το Chrome θα σας προστατέψει από την παρακολούθηση μεταξύ ιστοτόπων, διατηρώντας παράλληλα τον ανοικτό ιστό.</translation> <translation id="6676384891291319759">Πρόσβαση στο Διαδίκτυο</translation> <translation id="6679975945624592337">Να επιτρέπεται στο Google Chrome να εκτελείται στο παρασκήνιο</translation> <translation id="6696915334902295848">Το Chrome χρειάζεται άδεια μικροφώνου για αυτόν τον ιστότοπο.</translation> @@ -227,6 +229,7 @@ <translation id="6989339256997917931">Το Google Chrome έχει ενημερωθεί, αλλά δεν το έχετε χρησιμοποιήσει για 30 ημέρες τουλάχιστον.</translation> <translation id="7025800014283535195">Μπορείτε εδώ να κάνετε εναλλαγή μεταξύ των προφίλ του Chrome</translation> <translation id="7062128746136194023">Ο γονέας σου απενεργοποίησε την επιλογή "Άδειες για ιστοτόπους, εφαρμογές και επεκτάσεις" για το Chrome. Η προσθήκη του στοιχείου <ph name="EXTENSION_TYPE_PARAMETER" /> δεν επιτρέπεται.</translation> +<translation id="7085332316435785646">Επιλέξτε αν θέλετε να συμπεριλαμβάνεται το ιστορικό Chrome για πιο εξατομικευμένες εμπειρίες στις υπηρεσίες Google.</translation> <translation id="7088681679121566888">Το Chrome έχει ενημερωθεί.</translation> <translation id="7098166902387133879">Το Google Chrome χρησιμοποιεί το μικρόφωνό σας.</translation> <translation id="7106741999175697885">Διαχείριση Εργασιών - Google Chrome</translation> @@ -251,6 +254,7 @@ <translation id="7651907282515937834">Λογότυπο Chrome Enterprise</translation> <translation id="7665553140559834626">Επανεκκίνηση για ενημέρωση του &Chrome OS</translation> <translation id="7747138024166251722">Δεν ήταν δυνατή η δημιουργία ενός προσωρινού καταλόγου από το πρόγραμμα εγκατάστασης. Ελέγξτε τον κενό χώρο του δίσκου και το δικαίωμα εγκατάστασης του λογισμικού.</translation> +<translation id="7748512868279796735">Οι παρακάτω λογαριασμοί είναι διαθέσιμοι για αυτό το προφίλ Chrome</translation> <translation id="7761834446675418963">Κάντε κλικ στο όνομά σας, για να ανοίξετε το Chrome και να ξεκινήσετε την περιήγηση.</translation> <translation id="7777080907402804672">Εάν μια εικόνα δεν έχει κάποια χρήσιμη περιγραφή, το Chrome θα προσπαθήσει να σας προσφέρει μια περιγραφή. Για τη δημιουργία περιγραφών, αποστέλλονται εικόνες στην Google. Μπορείτε να απενεργοποιήσετε αυτήν τη λειτουργία στις ρυθμίσεις οποιαδήποτε στιγμή.</translation> <translation id="7781002470561365167">Μια νέα έκδοση του Google Chrome είναι διαθέσιμη.</translation> @@ -282,6 +286,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">Αυτό το προφίλ εργασίας είναι εντελώς ξεχωριστό από το προσωπικό προφίλ σας.</translation> <translation id="8556340503434111824">Υπάρχει μια νέα έκδοση του Google Chrome και είναι ταχύτερη από ποτέ.</translation> +<translation id="8571790202382503603">Με τα προφίλ του Chrome μπορείτε να διαχωρίσετε όλο το περιεχόμενό σας στο Chromium. Αυτό σας βοηθά να διαχωρίζετε την εργασία από την ψυχαγωγία.</translation> <translation id="8614913330719544658">Το Google Chrome δεν αποκρίνεται. Επανεκκίνηση τώρα;</translation> <translation id="861702415419836452">Το Chrome χρειάζεται άδεια πρόσβασης στην κάμερά σας, για να δημιουργήσει έναν τρισδιάστατο χάρτη του περιβάλλοντα χώρου σας.</translation> <translation id="8625237574518804553">{0,plural, =1{Η επανεκκίνηση του Chrome θα γίνει σε 1 λεπτό}other{Η επανεκκίνηση του Chrome θα γίνει σε # λεπτά}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_eu.xtb b/chrome/app/resources/google_chrome_strings_eu.xtb index 40ddc8d9..4d26247 100644 --- a/chrome/app/resources/google_chrome_strings_eu.xtb +++ b/chrome/app/resources/google_chrome_strings_eu.xtb
@@ -52,6 +52,7 @@ <translation id="2123055963409958220">Lagundu Chrome hobetzen <ph name="BEGIN_LINK" />oraingo ezarpenen<ph name="END_LINK" /> berri emanda</translation> <translation id="2151406531797534936">Berrabiarazi Chrome</translation> <translation id="2189289170880510015">Pertsonalizatu Chrome-ren pribatutasun-aukera garrantzitsuenetako batzuk</translation> +<translation id="2258103955319320201">Chrome arakatzaileko gauzak gailu guztietan atzitzeko, hasi saioa eta aktibatu sinkronizazioa</translation> <translation id="2290014774651636340">Google APIko gakoak falta dira. Agian Google Chrome-ren funtzio batzuk desgaituta egongo dira.</translation> <translation id="2290095356545025170">Ziur Google Chrome desinstalatu nahi duzula?</translation> <translation id="2309047409763057870">Google Chrome-ren bigarren mailako instalazio bat da hau; beraz, ezin duzu ezarri arakatzaile lehenetsi gisa.</translation> @@ -216,6 +217,7 @@ <translation id="6506909944137591434">Chrome-k kamera atzitzeko baimena behar du zure inguruaren 3D-ko mapa bat sortzeko</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6568793831116033768">Chrome OS sistema</translation> +<translation id="6594121454516132231">Ikusi zer egin nahi duen Chrome-k sare irekia mantendu bitartean zu webguneen arteko jarraipenetik babesteko</translation> <translation id="6676384891291319759">Sartu Interneten</translation> <translation id="6679975945624592337">Utzi Google Chrome-ri atzeko planoan abiarazten</translation> <translation id="6696915334902295848">Chrome-k mikrofonoa atzitzeko baimena behar du webgune honetan</translation> @@ -230,6 +232,7 @@ <translation id="6989339256997917931">Google Chrome eguneratu egin da, baina ez duzu 30 egunetan erabili.</translation> <translation id="7025800014283535195">Aldatu Chrome-ko profila hemen</translation> <translation id="7062128746136194023">Zure gurasoak "Webguneen, aplikazioen eta luzapenen baimenak" desaktibatu ditu Chrome-n. Ezin da gehitu <ph name="EXTENSION_TYPE_PARAMETER" />.</translation> +<translation id="7085332316435785646">Aukeratu ea Chrome-ko historia kontuan hartu nahi duzun ala ez Google-ren zerbitzuak modu pertsonalizatuago batean erabiltzeko</translation> <translation id="7088681679121566888">Eguneratuta dago Chrome</translation> <translation id="7098166902387133879">Google Chrome zure mikrofonoa erabiltzen ari da.</translation> <translation id="7106741999175697885">Zeregin-kudeatzailea - Google Chrome</translation> @@ -254,6 +257,7 @@ <translation id="7651907282515937834">Chrome Enterprise logotipoa</translation> <translation id="7665553140559834626">Abiaraz ezazu berriro &Chrome OS eguneratzeko</translation> <translation id="7747138024166251722">Instalatzaileak ezin izan du sortu behin behineko direktoriorik. Softwarea instalatzeko, egiaztatu diskoan duzun espazio librea eta baimena.</translation> +<translation id="7748512868279796735">Kontu hauek erabil daitezke Chrome-ko profil honekin:</translation> <translation id="7761834446675418963">Sakatu zure izena Chrome irekitzeko eta arakatzen hasteko.</translation> <translation id="7777080907402804672">Irudiren batek ez badu azalpen lagungarririk, halako bat lortzen ahaleginduko da Chrome. Azalpen horiek sortzeko, irudiak Google-ri bidaltzen zaizkio. Aukera hori desaktibatu nahi baduzu, joan ezarpenetara.</translation> <translation id="7781002470561365167">Google Chrome-ren bertsio berri bat erabilgarri dago.</translation> @@ -285,6 +289,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">Laneko profila eta profil pertsonala guztiz bereizita daude.</translation> <translation id="8556340503434111824">Google Chrome-ren bertsio berri bat erabilgarri dago; inoiz baino bizkorragoa da.</translation> +<translation id="8571790202382503603">Chrome-ko profilekin, Chrome-n dituzun gauza guztiak bereiz ditzakezu. Hala, errazago edukiko dituzu bananduta gauza pertsonalak eta lanekoak.</translation> <translation id="8614913330719544658">Google Chrome-k ez du erantzuten. Berrabiarazi nahi duzu?</translation> <translation id="861702415419836452">Chrome-k kamera atzitzeko baimena behar du, ingurunearen hiru dimentsioko mapa bat sortzeko</translation> <translation id="8625237574518804553">{0,plural, =1{1 minutu barru berrabiaraziko da Chrome}other{# minutu barru berrabiaraziko da Chrome}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_fa.xtb b/chrome/app/resources/google_chrome_strings_fa.xtb index 26eae68..5f8bb6c3 100644 --- a/chrome/app/resources/google_chrome_strings_fa.xtb +++ b/chrome/app/resources/google_chrome_strings_fa.xtb
@@ -49,6 +49,7 @@ <translation id="2123055963409958220">با گزارش <ph name="BEGIN_LINK" />تنظیمات کنونی<ph name="END_LINK" />، به بهتر شدن Chrome کمک کنید</translation> <translation id="2151406531797534936">لطفاً اکنون Chrome را بازراهاندازی کنید</translation> <translation id="2189289170880510015">سفارشی کردن بعضیاز مهمترین انتخابهای حریمخصوصی Chrome</translation> +<translation id="2258103955319320201">برای دسترسی به چیزهایتان در مرورگر Chrome در همه دستگاههایتان، به سیستم وارد شوید، سپس همگامسازی را روشن کنید</translation> <translation id="2290014774651636340">کلیدهای Google API وجود ندارد. برخی از عملکردهای Google Chrome از کار خواهد افتاد.</translation> <translation id="2290095356545025170">آیا میخواهید Google Chrome را غیر فعال کنید؟</translation> <translation id="2309047409763057870">این نصب ثانویه Google Chrome است و نمیتواند مرورگر پیشفرضتان شود.</translation> @@ -209,6 +210,7 @@ <translation id="6506909944137591434">Chrome برای ایجاد نقشه سهبعدی از محیط اطرافتان به اجازه دوربین نیاز دارد</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6568793831116033768">سیستم Chrome OS</translation> +<translation id="6594121454516132231">ببینید Chrome چگونه قصد دارد با حفظ وبِ باز، از شما دربرابر ردیابی بینسایتی محافظت کند</translation> <translation id="6676384891291319759">دسترسی به اینترنت</translation> <translation id="6679975945624592337">اجازه به Google Chrome برای اجرا در پسزمینه</translation> <translation id="6696915334902295848">Chrome برای این سایت به اجازه میکروفون نیاز دارد</translation> @@ -223,6 +225,7 @@ <translation id="6989339256997917931">Google Chrome به روز شده است اما حداقل ۳۰ روز از آن استفاده نکردهاید.</translation> <translation id="7025800014283535195">میتوانید در اینجا بین نمایههای Chrome جابهجا شوید</translation> <translation id="7062128746136194023">ولیتان «اجازههای مربوط به سایتها، برنامهها، و افزونهها» را برای Chrome خاموش کرده است. افزودن این <ph name="EXTENSION_TYPE_PARAMETER" /> مجاز نیست.</translation> +<translation id="7085332316435785646">انتخاب کنید که آیا سابقه Chrome برای تجربههای شخصیشدهتر در سرویسهای Google لحاظ شود یا نه</translation> <translation id="7088681679121566888">Chrome بهروز است</translation> <translation id="7098166902387133879">Google Chrome درحال استفاده از میکروفون شما است.</translation> <translation id="7106741999175697885">مدیر فعالیتها - Google Chrome</translation> @@ -247,6 +250,7 @@ <translation id="7651907282515937834">نشانواره Chrome Enterprise</translation> <translation id="7665553140559834626">راهاندازی مجدد برای بهروزرسانی Chrome OS</translation> <translation id="7747138024166251722">نصبکننده نتوانست دایرکتوری موقت ایجاد کند. لطفاً فضای خالی دیسک و اجازه نصب نرمافزار را بررسی کنید.</translation> +<translation id="7748512868279796735">حسابهای زیر برای این نمایه Chrome دردسترس هستند</translation> <translation id="7761834446675418963">برای باز کردن Chrome و شروع به مرور، روی نامتان کلیک کنید.</translation> <translation id="7777080907402804672">اگر تصویری توضیح مفیدی نداشته باشد، Chrome توضیحی برای شما ارائه خواهد کرد. برای ایجاد توضیحات، تصاویر به Google ارسال میشود. هروقت خواستید میتوانید این گزینه را در تنظیمات خاموش کنید.</translation> <translation id="7781002470561365167">نسخه جدیدی از Google Chrome موجود است.</translation> @@ -278,6 +282,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">این نمایه کاری کاملاً مجزا از نمایه شخصیتان است.</translation> <translation id="8556340503434111824">نسخه جدیدی از Google Chrome وجود دارد که سریعتر از همیشه است.</translation> +<translation id="8571790202382503603">با نمایههای Chrome میتوانید همهچیزتان را در Chrome جدا کنید. با این کار، راحتتر میتوان کار و سرگرمی را ازهم جدا کرد.</translation> <translation id="8614913330719544658">Google Chrome پاسخ نمیدهد. مجدداً راهاندازی شود؟</translation> <translation id="861702415419836452">Chrome برای دسترسی به دوربین به اجازه نیاز دارد تا بتواند نقشه سهبعدی محیط شما را ایجاد کند</translation> <translation id="8625237574518804553">{0,plural, =1{Chrome ۱ دقیقه دیگر راهاندازی مجدد میشود}one{Chrome # دقیقه دیگر راهاندازی مجدد میشود}other{Chrome # دقیقه دیگر راهاندازی مجدد میشود}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_hr.xtb b/chrome/app/resources/google_chrome_strings_hr.xtb index a559a7ce..2ba7900 100644 --- a/chrome/app/resources/google_chrome_strings_hr.xtb +++ b/chrome/app/resources/google_chrome_strings_hr.xtb
@@ -49,6 +49,7 @@ <translation id="2123055963409958220">Pomognite poboljšati Chrome tako što ćete prijaviti <ph name="BEGIN_LINK" />trenutačne postavke<ph name="END_LINK" /></translation> <translation id="2151406531797534936">Sada ponovo pokrenite Chrome</translation> <translation id="2189289170880510015">Prilagodite neke od najvažnijih opcija privatnosti Chromea</translation> +<translation id="2258103955319320201">Da biste mogli pristupiti svojim sadržajima u pregledniku Chrome na svim svojim uređajima, prijavite se i zatim uključite sinkronizaciju.</translation> <translation id="2290014774651636340">Nedostaju ključevi Google API-ja. Neke funkcije Google Chromea bit će onemogućene.</translation> <translation id="2290095356545025170">Jeste li sigurni da želite deinstalirati Google Chrome?</translation> <translation id="2309047409763057870">Ovo je sekundarna instalacija Google Chromea, pa on ne može biti vaš zadani preglednik.</translation> @@ -209,6 +210,7 @@ <translation id="6506909944137591434">Chrome treba dopuštenje za fotoaparat kako bi mogao izraditi 3D kartu vašeg okruženja</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6568793831116033768">OS Chrome</translation> +<translation id="6594121454516132231">Pogledajte kako vas Chrome planira štititi od praćenja na različitim web-lokacijama, a istovremeno očuvati otvorenost weba</translation> <translation id="6676384891291319759">Pristup Internetu</translation> <translation id="6679975945624592337">Neka Google Chrome radi u pozadini</translation> <translation id="6696915334902295848">Chrome treba dopuštenje za mikrofon za ovu web-lokaciju</translation> @@ -223,6 +225,7 @@ <translation id="6989339256997917931">Google Chrome ažuriran je, ali vi ga niste upotrebljavali barem 30 dana.</translation> <translation id="7025800014283535195">Ovdje se možete prebacivati između profila u Chromeu</translation> <translation id="7062128746136194023">Tvoj je roditelj isključio "Dopuštenja za web-lokacije, aplikacije i proširenja" za Chrome. Nije dopušteno dodati <ph name="EXTENSION_TYPE_PARAMETER" />.</translation> +<translation id="7085332316435785646">Odaberite želite li uključiti povijest na Chromeu za prilagođenije doživljaje na Googleovim uslugama</translation> <translation id="7088681679121566888">Chrome je ažuriran</translation> <translation id="7098166902387133879">Google Chrome upotrebljava vaš mikrofon.</translation> <translation id="7106741999175697885">Upravitelj zadacima - Google Chrome:</translation> @@ -247,6 +250,7 @@ <translation id="7651907282515937834">Logotip Chrome Enterprise</translation> <translation id="7665553140559834626">Ponovo pokrenite da biste ažurirali OS &Chrome</translation> <translation id="7747138024166251722">Program za instalaciju nije izradio privremeni direktorij. Provjerite ima li slobodnog prostora na disku i postoji li dopuštenje za instalaciju softvera.</translation> +<translation id="7748512868279796735">Sljedeći računi dostupni su za ovaj Chrome profil</translation> <translation id="7761834446675418963">Kliknite svoje ime da biste otvorili Chrome i počeli s pregledavanjem.</translation> <translation id="7777080907402804672">Ako slika nema koristan opis, Chrome će ga pokušati pružiti. Da bi se izradili opisi, slike se šalju Googleu. To možete isključiti u bilo kojem trenutku u postavkama.</translation> <translation id="7781002470561365167">Dostupna je nova verzija preglednika Google Chrome.</translation> @@ -278,6 +282,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">Ovaj poslovni profil potpuno je zaseban od vašeg osobnog profila.</translation> <translation id="8556340503434111824">Dostupna je nova verzija preglednika Google Chrome, brža no ikad.</translation> +<translation id="8571790202382503603">Chromeovi profili omogućuju vam da razdvojite sve svoje sadržaje u Chromeu. To olakšava odvajanje posla i zabave.</translation> <translation id="8614913330719544658">Google Chrome ne reagira. Ponovo pokrenuti sada?</translation> <translation id="861702415419836452">Chrome treba dopuštenje za pristup kameri radi izrade 3D karte vašeg okruženja</translation> <translation id="8625237574518804553">{0,plural, =1{Chrome će se ponovo pokrenuti za jednu minutu}one{Chrome će se ponovo pokrenuti za # min}few{Chrome će se ponovo pokrenuti za # min}other{Chrome će se ponovo pokrenuti za # min}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_hy.xtb b/chrome/app/resources/google_chrome_strings_hy.xtb index 2e08e0e..1b77859 100644 --- a/chrome/app/resources/google_chrome_strings_hy.xtb +++ b/chrome/app/resources/google_chrome_strings_hy.xtb
@@ -50,6 +50,7 @@ <translation id="2123055963409958220">Օգնեք կատարելագործել Chrome-ը՝ հաղորդելով <ph name="BEGIN_LINK" />ընթացիկ կարգավորումների<ph name="END_LINK" /> մասին</translation> <translation id="2151406531797534936">Վերագործարկեք Chrome-ը</translation> <translation id="2189289170880510015">Անհատականացրեք Chrome-ի գաղտնիության կարևորագույն կարգավորումները</translation> +<translation id="2258103955319320201">Chrome դիտարկիչի ձեր տվյալները ձեր բոլոր սարքերում օգտագործելու համար մտեք հաշիվ և միացրեք համաժամացումը</translation> <translation id="2290014774651636340">Google API-ի բանալիները չկան: Google Chrome-ի որոշ գործառույթներ կանջատվեն:</translation> <translation id="2290095356545025170">Իսկապե՞ս հեռացնել Google Chrome-ը:</translation> <translation id="2309047409763057870">Սա Google Chrome-ի երկրորդային տեղադրումն է: Այն չի կարող դառնալ ձեր կանխադրված դիտարկիչը:</translation> @@ -200,6 +201,7 @@ <translation id="5941830788786076944">Դարձնել Google Chrome-ը կանխադրված դիտարկիչը</translation> <translation id="6070348360322141662">Լրացուցիչ անվտանգության համար Google Chrome-ը կգաղտնագրի ձեր տվյալները</translation> <translation id="608006075545470555">Աշխատանքային պրոֆիլի ավելացում այս դիտարկիչում</translation> +<translation id="608496399798299674">CloudReady 2.0</translation> <translation id="6113794647360055231">Chrome-ը բարելավվել է</translation> <translation id="6145313976051292476">Բացել PDF ֆայլեր Chrome-ում</translation> <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation> @@ -213,6 +215,7 @@ <translation id="6506909944137591434">Ձեր շրջակայքի եռաչափ քարտեզը ստեղծելու համար Chrome-ին անհրաժեշտ է տեսախցիկն օգտագործելու թույլտվություն</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6568793831116033768">Chrome OS համակարգ</translation> +<translation id="6594121454516132231">Դիտեք, թե ինչպես է Chromе-ը պաշտպանելու ձեզ գործողությունների միջկայքային հետագծման մեխանիզմներից</translation> <translation id="6676384891291319759">Մտնել համացանց</translation> <translation id="6679975945624592337">Թույլատրել Google Chrome-ին աշխատել ֆոնային ռեժիմում</translation> <translation id="6696915334902295848">Այս կայքի համար Chrome-ին անհրաժեշտ է խոսափողն օգտագործելու թույլտվություն</translation> @@ -227,6 +230,7 @@ <translation id="6989339256997917931">Google Chrome-ը թարմացվել է, բայց դուք չեք օգտագործել այն առնվազն 30 օր:</translation> <translation id="7025800014283535195">Այստեղ կարող եք անցնել Chrome-ի այլ պրոֆիլի</translation> <translation id="7062128746136194023">Ձեր ծնողն անջատել է «Թույլտվություններ կայքերի, հավելվածների և ընդլայնումների համար» պարամետրը Chrome-ում։ Այս <ph name="EXTENSION_TYPE_PARAMETER" />ն արգելափակված է և չի կարող ավելացվել։</translation> +<translation id="7085332316435785646">Ընտրեք, թե արդյոք ներառել Chromе-ի պատմությունը՝ Google-ի ծառայությունների ավելի անհատականացված օգտագործման համար։</translation> <translation id="7088681679121566888">Chrome-ը թարմացված է</translation> <translation id="7098166902387133879">Google Chrome-ն օգտագործում է ձեր խոսափողը:</translation> <translation id="7106741999175697885">Խնդիրների կառավարիչ - Google Chrome</translation> @@ -251,6 +255,7 @@ <translation id="7651907282515937834">Chrome Enterprise-ի լոգո</translation> <translation id="7665553140559834626">Վերագործարկել՝ &Chrome OS-ը թարմացնելու համար</translation> <translation id="7747138024166251722">Տեղադրիչը չկարողացավ ստեղծել ժամանակավոր գրացուցակ: Ստուգեք սկավառակում ազատ տարածքի առկայությունը և ծրագրակազմը տեղադրելու թույլտվությունը:</translation> +<translation id="7748512868279796735">Հետևյալ հաշիվները հասանելի են այս Chromе պրոֆիլի համար</translation> <translation id="7761834446675418963">Chrome-ը բացելու և աշխատանքն սկսելու համար սեղմեք ձեր անվան վրա:</translation> <translation id="7777080907402804672">Եթե պատկերն օգտակար նկարագրություն չունի, Chrome-ը կփորձի նոր նկարագրություն տրամադրել: Պատկերներն ուղարկվում են Google-ին՝ նկարագրություններ ստեղծելու համար։ Ցանկացած պահի կարգավորումներում կարող եք անջատել սա:</translation> <translation id="7781002470561365167">Google Chrome-ի նոր տարբերակը մատչելի է:</translation> @@ -282,6 +287,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">Այս աշխատանքային պրոֆիլն ամբողջովին առանձնացված է ձեր անձնական պրոֆիլից։</translation> <translation id="8556340503434111824">Google Chrome-ի նոր տարբերակը մատչելի է և այն շատ ավելի արագ է:</translation> +<translation id="8571790202382503603">Chromе պրոֆիլների միջոցով դուք կարող եք օգտագործել դիտարկիչն առանձին այլ օգտատերերից։ Այդպես ավելի հեշտ է տարանջատել գործնական և անձնական նպատակներով օգտագործումը։</translation> <translation id="8614913330719544658">Google Chrome-ը չի պատասխանում: Վերագործարկե՞լ:</translation> <translation id="861702415419836452">Chrome-ին անհրաժեշտ է տեսախցիկն օգտագործելու թույլտվություն՝ ձեր շրջակայքի եռաչափ քարտեզը ստեղծելու համար։</translation> <translation id="8625237574518804553">{0,plural, =1{Chrome-ը կվերագործարկվի 1 րոպեից}one{Chrome-ը կվերագործարկվի # րոպեից}other{Chrome-ը կվերագործարկվի # րոպեից}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_it.xtb b/chrome/app/resources/google_chrome_strings_it.xtb index 9e771858..9626474a 100644 --- a/chrome/app/resources/google_chrome_strings_it.xtb +++ b/chrome/app/resources/google_chrome_strings_it.xtb
@@ -193,6 +193,7 @@ <translation id="5941830788786076944">Imposta Google Chrome come browser predefinito</translation> <translation id="6070348360322141662">Per maggiore sicurezza, Google Chrome cripterà i tuoi dati</translation> <translation id="608006075545470555">Aggiungi profilo di lavoro a questo browser</translation> +<translation id="608496399798299674">CloudReady 2.0</translation> <translation id="6113794647360055231">Da oggi Chrome è ancora meglio</translation> <translation id="6145313976051292476">Apri PDF in Chrome</translation> <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> - Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_kk.xtb b/chrome/app/resources/google_chrome_strings_kk.xtb index bae06f6..baf4763 100644 --- a/chrome/app/resources/google_chrome_strings_kk.xtb +++ b/chrome/app/resources/google_chrome_strings_kk.xtb
@@ -52,6 +52,7 @@ <translation id="2123055963409958220"><ph name="BEGIN_LINK" />Ағымдағы параметрлерді<ph name="END_LINK" /> хабарлау арқылы Chrome браузерін жақсартуға көмектесіңіз</translation> <translation id="2151406531797534936">Chrome браузерін өшіріп, қайта қосыңыз</translation> <translation id="2189289170880510015">Chrome-ның ең маңызды құпиялылық параметрлерін реттеңіз</translation> +<translation id="2258103955319320201">Chrome браузерінің материалдарын барлық құрылғыда пайдалану үшін аккаунтқа кіріп, синхрондау параметрін қосыңыз.</translation> <translation id="2290014774651636340">Google API пернелері жоқ. Кейбір Google Chrome функционалдықтары өшіріледі.</translation> <translation id="2290095356545025170">Google Chrome жою қажет пе?</translation> <translation id="2309047409763057870">Бұл – Google Chrome браузерінің қайта орнатылған нұсқасы және әдепкі браузер бола алмайды.</translation> @@ -215,6 +216,7 @@ <translation id="6506909944137591434">Chrome айналаңыздың 3D картасын жасау үшін камераны пайдалануға рұқсат сұрайды.</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome әзірлеуші нұсқасы</translation> <translation id="6568793831116033768">Chrome OS жүйесі</translation> +<translation id="6594121454516132231">Chrome ашық желіні қолдай отырып, сізді сайтаралық бақылаудан қалай қорғайтынын көріңіз.</translation> <translation id="6676384891291319759">Интернетке кіру</translation> <translation id="6679975945624592337">Google Chrome браузеріне фондық режимде жұмыс істеуге рұқсат беру</translation> <translation id="6696915334902295848">Chrome бұл сайт үшін микрофонды пайдалануға рұқсат сұрайды.</translation> @@ -229,6 +231,7 @@ <translation id="6989339256997917931">Google Chrome жаңартылды, бірақ оны кемінде 30 күн бойы пайдаланбадыңыз.</translation> <translation id="7025800014283535195">Осы жерде Chrome профильдерін ауыстыра аласыз.</translation> <translation id="7062128746136194023">Ата-анаңыз Chrome браузері үшін "Сайттар, қолданбалар және кеңейтімдер бойынша рұқсаттар" параметрін өшірді. <ph name="EXTENSION_TYPE_PARAMETER" /> кеңейтімін енгізуге болмайды.</translation> +<translation id="7085332316435785646">Google қызметтерінде жекелендірілген мүмкіндіктерді пайдалану үшін Chrome тарихын қосу-қоспау нұсқасын таңдаңыз.</translation> <translation id="7088681679121566888">Chrome жаңартылған.</translation> <translation id="7098166902387133879">Google Chrome микрофоныңызды пайдалануда.</translation> <translation id="7106741999175697885">Тапсырмалар реттегіші – Google Chrome</translation> @@ -253,6 +256,7 @@ <translation id="7651907282515937834">Chrome Enterprise логотипі</translation> <translation id="7665553140559834626">&Chrome OS жүйесін жаңарту үшін қайта іске қосу</translation> <translation id="7747138024166251722">Орнату құралы уақытша каталогті жасай алмады. Дисктегі бос орынды және бағдарламалық жасақтама рұқсатын тексеріңіз.</translation> +<translation id="7748512868279796735">Бұл Chrome профилі үшін келесі аккаунттар қолжетімді.</translation> <translation id="7761834446675418963">Chrome ашып, шолуды бастау үшін атыңызды басыңыз.</translation> <translation id="7777080907402804672">Егер суреттің пайдалы сипаттамасы болмаса, Chrome оны өзі ұсынып көреді. Сипаттамалар жасау үшін суреттер Google-ға жіберіледі. Бұл функцияны кез келген уақытта параметрлерден өшіріп қоюға болады.</translation> <translation id="7781002470561365167">Жаңа Google Chrome нұсқасы қолжетімді.</translation> @@ -284,6 +288,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">Бұл жұмыс профилі жеке профиліңізден толық ажыратылған.</translation> <translation id="8556340503434111824">Жаңа жылдамырақ Google Chrome нұсқасы қолжетімді.</translation> +<translation id="8571790202382503603">Chrome профильдері арқылы Chrome-дағы барлық материалыңызды бөле аласыз. Осылайша оларды жұмыс немесе көңіл көтеру топтарына оңай іріктеуге болады.</translation> <translation id="8614913330719544658">Google Chrome жауап бермейді. Қазір қайта іске қосасыз ба?</translation> <translation id="861702415419836452">Chrome браузеріне айналаңыздың 3D картасын жасау үшін камераны пайдалану рұқсаты керек.</translation> <translation id="8625237574518804553">{0,plural, =1{Chrome браузері 1 минуттан кейін қайта іске қосылады}other{Chrome браузері # минуттан кейін қайта іске қосылады}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_kn.xtb b/chrome/app/resources/google_chrome_strings_kn.xtb index d065ab0..af180bc 100644 --- a/chrome/app/resources/google_chrome_strings_kn.xtb +++ b/chrome/app/resources/google_chrome_strings_kn.xtb
@@ -50,6 +50,7 @@ <translation id="2123055963409958220"><ph name="BEGIN_LINK" />ಪ್ರಸ್ತುತ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು<ph name="END_LINK" /> ವರದಿ ಮಾಡುವುದರ ಮೂಲಕ Chrome ಅನ್ನು ಉತ್ತಮಗೊಳಿಸಲು ಸಹಾಯ ಮಾಡಿ</translation> <translation id="2151406531797534936">ಇದೀಗ Chrome ಅನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿ</translation> <translation id="2189289170880510015">Chrome ನ ಕೆಲವು ಮುಖ್ಯ ಗೌಪ್ಯತೆ ಆಯ್ಕೆಗಳನ್ನು ಕಸ್ಟಮೈಸ್ ಮಾಡಿ</translation> +<translation id="2258103955319320201">ನಿಮ್ಮ Chrome ಬ್ರೌಸರ್ನ ವಿಷಯಗಳನ್ನು ಎಲ್ಲಾ ಸಾಧನಗಳಾದ್ಯಂತ ಪ್ರವೇಶಿಸಲು, ಸೈನ್ ಇನ್ ಮಾಡಿ, ನಂತರ ಸಿಂಕ್ ಅನ್ನು ಆನ್ ಮಾಡಿ</translation> <translation id="2290014774651636340">Google API ಕೀಗಳು ಕಾಣೆಯಾಗಿವೆ. Google Chrome ನ ಕೆಲವು ಕಾರ್ಯವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗುತ್ತದೆ.</translation> <translation id="2290095356545025170">ನೀವು ಖಚಿತವಾಗಿ Google Chrome ಅನ್ನು ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಬಯಸುತ್ತೀರಾ?</translation> <translation id="2309047409763057870">ಇದು Google Chrome ನ ದ್ವಿತೀಯ ಸ್ಥಾಪನೆಯಾಗಿದೆ ಮತ್ತು ಅದನ್ನು ನಿಮ್ಮ ಡಿಫಾಲ್ಟ್ ಬ್ರೌಸರ್ ಆಗಿ ಮಾಡಲಾಗುವುದಿಲ್ಲ.</translation> @@ -209,6 +210,7 @@ <translation id="6506909944137591434">ನಿಮ್ಮ ಸುತ್ತಮುತ್ತಲಿನ ಪ್ರದೇಶದ 3D ನಕ್ಷೆಯನ್ನು ರಚಿಸಲು Chrome ಗೆ ಕ್ಯಾಮರಾ ಅನುಮತಿಯ ಅಗತ್ಯವಿದೆ</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6568793831116033768">Chrome OS ಸಿಸ್ಟಂ</translation> +<translation id="6594121454516132231">ತೆರೆದ ವೆಬ್ ಅನ್ನು ಕಾಪಾಡುವಾಗ ಕ್ರಾಸ್-ಸೈಟ್ ಟ್ರ್ಯಾಕಿಂಗ್ನಿಂದ ನಿಮ್ಮನ್ನು ಹೇಗೆ ರಕ್ಷಿಸಲು Chrome ಪ್ಲಾನ್ ಮಾಡುತ್ತದೆ ಎಂಬುದನ್ನು ನೋಡಿ</translation> <translation id="6676384891291319759">ಇಂಟರ್ನೆಟ್ ಅನ್ನು ಪ್ರವೇಶಿಸಿ</translation> <translation id="6679975945624592337">Google Chrome ಹಿನ್ನೆಲೆಯಲ್ಲಿ ರನ್ ಆಗಲು ಅನುಮತಿಸಿ</translation> <translation id="6696915334902295848">ಈ ಸೈಟ್ಗೆ ಸಂಬಂಧಿಸಿದಂತೆ Chrome ಗೆ ಮೈಕ್ರೊಫೋನ್ ಅನುಮತಿಯ ಅಗತ್ಯವಿದೆ</translation> @@ -223,6 +225,7 @@ <translation id="6989339256997917931">Google Chrome ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ, ಆದರೆ ನೀವು ಕನಿಷ್ಠ 30 ದಿನಗಳವರೆಗಾದರೂ ಇದನ್ನು ಬಳಸಿರಲಿಕ್ಕಿಲ್ಲ. </translation> <translation id="7025800014283535195">ನೀವು ಇಲ್ಲಿ Chrome ಪ್ರೊಫೈಲ್ಗಳನ್ನು ಬದಲಾಯಿಸಬಹುದು</translation> <translation id="7062128746136194023">ನಿಮ್ಮ ಪೋಷಕರು Chrome ನಲ್ಲಿ "ಸೈಟ್ಗಳು, ಆ್ಯಪ್ಗಳು ಮತ್ತು ವಿಸ್ತರಣೆಗಳಿಗಾಗಿ ಅನುಮತಿಗಳನ್ನು" ಆಫ್ ಮಾಡಿದ್ದಾರೆ. ಈ <ph name="EXTENSION_TYPE_PARAMETER" /> ಅನ್ನು ಸೇರಿಸಲು ಅನುಮತಿಯಿಲ್ಲ.</translation> +<translation id="7085332316435785646">Google ಸೇವೆಗಳಲ್ಲಿ ಹೆಚ್ಚು ವೈಯಕ್ತೀಕರಿಸಿದ ಅನುಭವಗಳಿಗಾಗಿ Chrome ಇತಿಹಾಸವನ್ನು ಸೇರಿಸಬೇಕೆ ಬೇಡವೇ ಎಂಬುದನ್ನು ಆಯ್ಕೆಮಾಡಿ</translation> <translation id="7088681679121566888">Chrome ಅಪ್ ಟು ಡೇಟ್ ಆಗಿದೆ</translation> <translation id="7098166902387133879">Google Chrome ನಿಮ್ಮ ಮೈಕ್ರೋಫೋನ್ ಅನ್ನು ಬಳಸುತ್ತಿದೆ.</translation> <translation id="7106741999175697885">ಕಾರ್ಯ ನಿರ್ವಾಹಕ - Google Chrome</translation> @@ -247,6 +250,7 @@ <translation id="7651907282515937834">Chrome ಎಂಟರ್ಪ್ರೈಸ್ ಲೋಗೋ</translation> <translation id="7665553140559834626">&Chrome OS ಅಪ್ಡೇಟ್ ಮಾಡಲು ಮರುಪ್ರಾರಂಭಿಸಿ</translation> <translation id="7747138024166251722">ಇನ್ಸ್ಟಾಲರ್ಗೆ ತಾತ್ಕಾಲಿಕ ಡೈರೆಕ್ಟರಿಯನ್ನು ರಚಿಸಲಾಗಲಿಲ್ಲ. ಸಾಫ್ಟ್ವೇರ್ ಇನ್ಸ್ಟಾಲ್ ಮಾಡಲು ಮುಕ್ತ ಡಿಸ್ಕ್ ಜಾಗ ಮತ್ತು ಅನುಮತಿಗಾಗಿ ದಯವಿಟ್ಟು ಪರಿಶೀಲಿಸಿ.</translation> +<translation id="7748512868279796735">ಈ Chrome ಪ್ರೊಫೈಲ್ಗಾಗಿ ಈ ಕೆಳಗಿನ ಖಾತೆಗಳು ಲಭ್ಯವಿದೆ</translation> <translation id="7761834446675418963">Chrome ತೆರೆಯಲು ಮತ್ತು ಬ್ರೌಸ್ ಮಾಡುವುದನ್ನು ಪ್ರಾರಂಭಿಸಲು ನಿಮ್ಮ ಹೆಸರನ್ನು ಕ್ಲಿಕ್ ಮಾಡಿ.</translation> <translation id="7777080907402804672">ಚಿತ್ರದಲ್ಲಿ ಉಪಯುಕ್ತ ವಿವರಣೆಯು ಇಲ್ಲದಿದ್ದರೆ, Chrome ನಿಮಗಾಗಿ ಒಂದು ವಿವರಣೆಯನ್ನು ಒದಗಿಸಲು ಪ್ರಯತ್ನಿಸುತ್ತದೆ. ವಿವರಣೆಗಳನ್ನು ರಚಿಸಲು, ಚಿತ್ರಗಳನ್ನು Google ಗೆ ಕಳುಹಿಸಲಾಗುತ್ತದೆ. ಇದನ್ನು ನೀವು ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಯಾವಾಗ ಬೇಕಾದರೂ ಆಫ್ ಮಾಡಬಹುದು.</translation> <translation id="7781002470561365167">Google Chrome ನ ಹೊಸ ಆವೃತ್ತಿ ಲಭ್ಯವಿದೆ.</translation> @@ -278,6 +282,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">ಈ ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ನಿಮ್ಮ ವೈಯಕ್ತಿಕ ಪ್ರೊಫೈಲ್ನಿಂದ ಸಂಪೂರ್ಣವಾಗಿ ಪ್ರತ್ಯೇಕವಾಗಿದೆ.</translation> <translation id="8556340503434111824">Google Chrome ನ ಹೊಸ ಆವೃತ್ತಿ ಲಭ್ಯವಿದೆ, ಮತ್ತು ಇದು ಎಂದಿಗಿಂತಲೂ ವೇಗವಾಗಿದೆ.</translation> +<translation id="8571790202382503603">Chrome ಪ್ರೊಫೈಲ್ಗಳ ಮೂಲಕ Chrome ಗೆ ಸಂಬಂಧಿಸಿದ ನಿಮ್ಮ ಎಲ್ಲಾ ಸಂಗತಿಗಳನ್ನು ಪ್ರತ್ಯೇಕವಾಗಿಸಬಹುದು. ಇದು ಕೆಲಸ ಮತ್ತು ಮೋಜಿನ ನಡುವೆ ವಿಭಜನೆಯನ್ನು ಸುಲಭಗೊಳಿಸುತ್ತದೆ.</translation> <translation id="8614913330719544658">Google Chrome ಸ್ಪಂದಿಸುತ್ತಿಲ್ಲ. ಇದೀಗ ಮರುಪ್ರಾರಂಭಿಸುವುದೆ? </translation> <translation id="861702415419836452">ನಿಮ್ಮ ಸುತ್ತಮುತ್ತಲಿನ ಪರಿಸರದ 3D ನಕ್ಷೆಯನ್ನು ರಚಿಸುವುದಕ್ಕಾಗಿ ನಿಮ್ಮ ಕ್ಯಾಮರಾವನ್ನು ಪ್ರವೇಶಿಸಲು Chrome ಗೆ ಅನುಮತಿ ಬೇಕಾಗಿದೆ</translation>
diff --git a/chrome/app/resources/google_chrome_strings_mk.xtb b/chrome/app/resources/google_chrome_strings_mk.xtb index 4b416ba..5bb15e4 100644 --- a/chrome/app/resources/google_chrome_strings_mk.xtb +++ b/chrome/app/resources/google_chrome_strings_mk.xtb
@@ -204,6 +204,7 @@ <translation id="5941830788786076944">Постави го Google Chrome за стандарден прелистувач</translation> <translation id="6070348360322141662">За дополнителна безбедност, Google Chrome ќе ги шифрира вашите податоци</translation> <translation id="608006075545470555">Додајте работен профил во овој прелистувач</translation> +<translation id="608496399798299674">CloudReady 2.0</translation> <translation id="6113794647360055231">Chrome тукушто се подобри</translation> <translation id="6145313976051292476">Отворај PDF-формат во Chrome</translation> <translation id="6169866489629082767"><ph name="PAGE_TITLE" /> – Google Chrome</translation>
diff --git a/chrome/app/resources/google_chrome_strings_nl.xtb b/chrome/app/resources/google_chrome_strings_nl.xtb index 97e9645..de335a0 100644 --- a/chrome/app/resources/google_chrome_strings_nl.xtb +++ b/chrome/app/resources/google_chrome_strings_nl.xtb
@@ -52,6 +52,7 @@ <translation id="2123055963409958220">Help Chrome beter te maken door de <ph name="BEGIN_LINK" />huidige instellingen<ph name="END_LINK" /> te melden</translation> <translation id="2151406531797534936">Chrome nu opnieuw opstarten</translation> <translation id="2189289170880510015">Pas enkele van de belangrijkste privacyinstellingen van Chrome aan</translation> +<translation id="2258103955319320201">Log in en zet synchronisatie aan voor toegang tot je Chrome-browsergegevens op al je apparaten</translation> <translation id="2290014774651636340">Google API-sleutels ontbreken. Sommige functies van Google Chrome worden uitgezet.</translation> <translation id="2290095356545025170">Weet je zeker dat je Google Chrome wilt verwijderen?</translation> <translation id="2309047409763057870">Dit is een tweede installatie van Google Chrome en kan niet als standaardbrowser worden ingesteld.</translation> @@ -213,6 +214,7 @@ <translation id="6506909944137591434">Chrome heeft camerarechten nodig om een 3D-kaart van je omgeving te maken</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6568793831116033768">Chrome OS-systeem</translation> +<translation id="6594121454516132231">Bekijk hoe Chrome je wil beschermen tegen tracking op verschillende sites terwijl het open web behouden blijft</translation> <translation id="6676384891291319759">Verbinding maken met internet</translation> <translation id="6679975945624592337">Google Chrome op de achtergrond laten uitvoeren</translation> <translation id="6696915334902295848">Chrome heeft microfoonrechten nodig voor deze site</translation> @@ -227,6 +229,7 @@ <translation id="6989339256997917931">Google Chrome is bijgewerkt, maar je hebt het programma minstens 30 dagen niet gebruikt.</translation> <translation id="7025800014283535195">Je kunt hier schakelen tussen verschillende Chrome-profielen</translation> <translation id="7062128746136194023">Je ouder heeft Rechten voor sites, apps en extensies uitgezet voor Chrome. Je mag deze <ph name="EXTENSION_TYPE_PARAMETER" /> niet toevoegen.</translation> +<translation id="7085332316435785646">Kies of je de Chrome-geschiedenis wilt opnemen voor meer gepersonaliseerde functies in Google-services</translation> <translation id="7088681679121566888">Chrome is up-to-date</translation> <translation id="7098166902387133879">Google Chrome gebruikt je microfoon.</translation> <translation id="7106741999175697885">Taakbeheer - Google Chrome</translation> @@ -251,6 +254,7 @@ <translation id="7651907282515937834">Chrome Enterprise-logo</translation> <translation id="7665553140559834626">Opnieuw starten om &Chrome OS te updaten</translation> <translation id="7747138024166251722">Het installatieprogramma kan geen tijdelijke directory maken. Controleer of je nog schijfruimte hebt en of je rechten hebt om software te installeren.</translation> +<translation id="7748512868279796735">De volgende accounts zijn beschikbaar voor dit Chrome-profiel</translation> <translation id="7761834446675418963">Klik op je naam om Chrome te openen en begin met surfen.</translation> <translation id="7777080907402804672">Als een afbeelding geen nuttige beschrijving bevat, probeert Chrome je er een te geven. Afbeeldingen worden naar Google gestuurd om beschrijvingen te maken. Je kunt dit op elk gewenst moment uitzetten in Instellingen.</translation> <translation id="7781002470561365167">Er is een nieuwe versie van Google Chrome beschikbaar.</translation> @@ -282,6 +286,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">Dit werkprofiel is volledig gescheiden van je persoonlijke profiel.</translation> <translation id="8556340503434111824">Er is een nieuwe versie van Google Chrome en deze is sneller dan ooit.</translation> +<translation id="8571790202382503603">Met Chrome-profielen kun je alle Chrome-gegevens gescheiden houden. Zo kun je makkelijker onderscheid maken tussen werk en privé.</translation> <translation id="8614913330719544658">Google Chrome reageert niet meer. Nu opnieuw starten?</translation> <translation id="861702415419836452">Chrome heeft toegangsrechten voor de camera nodig om een 3D-kaart van je omgeving te maken.</translation> <translation id="8625237574518804553">{0,plural, =1{Chrome wordt over één minuut opnieuw gestart}other{Chrome wordt over # minuten opnieuw gestart}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_pt-BR.xtb b/chrome/app/resources/google_chrome_strings_pt-BR.xtb index f36926157..5fa1bf2 100644 --- a/chrome/app/resources/google_chrome_strings_pt-BR.xtb +++ b/chrome/app/resources/google_chrome_strings_pt-BR.xtb
@@ -49,6 +49,7 @@ <translation id="2123055963409958220">Ajude a melhorar o Chrome informando as <ph name="BEGIN_LINK" />configurações atuais<ph name="END_LINK" /></translation> <translation id="2151406531797534936">Reinicie o Chrome agora</translation> <translation id="2189289170880510015">Personalize as opções de privacidade mais importantes do Chrome</translation> +<translation id="2258103955319320201">Para ter acesso aos recursos do navegador Chrome em todos os seus dispositivos, faça login e ative a sincronização</translation> <translation id="2290014774651636340">As chaves da API do Google não foram encontradas. Algumas funcionalidades do Google Chrome serão desativadas.</translation> <translation id="2290095356545025170">Você quer mesmo desinstalar o Google Chrome?</translation> <translation id="2309047409763057870">Como esta é uma instalação secundária do Google Chrome, ele não pode se tornar seu navegador padrão.</translation> @@ -207,6 +208,7 @@ <translation id="6506909944137591434">O Chrome precisa da permissão de acesso à câmera para criar um mapa 3D do ambiente</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" />: Google Chrome Dev</translation> <translation id="6568793831116033768">Sistema Chrome OS</translation> +<translation id="6594121454516132231">Veja como o Chrome pretende proteger você contra mecanismos de rastreamento entre sites ao mesmo tempo em que preserva uma Internet livre</translation> <translation id="6676384891291319759">Acessar a internet</translation> <translation id="6679975945624592337">Permitir a execução do Google Chrome em segundo plano</translation> <translation id="6696915334902295848">O Chrome precisa da permissão de acesso ao microfone para este site</translation> @@ -221,6 +223,7 @@ <translation id="6989339256997917931">O Google Chrome foi atualizado, mas ele não é utilizado há pelo menos trinta dias.</translation> <translation id="7025800014283535195">Aqui, você pode alternar entre os perfis do Chrome</translation> <translation id="7062128746136194023">Seu pai/mãe desativou "Permissões para sites, apps e extensões" no Chrome. Não é permitido adicionar <ph name="EXTENSION_TYPE_PARAMETER" />.</translation> +<translation id="7085332316435785646">Escolha se você quer incluir o histórico do Chrome para ter experiências mais personalizadas nos Serviços do Google</translation> <translation id="7088681679121566888">O Chrome está atualizado</translation> <translation id="7098166902387133879">O Google Chrome está usando seu microfone.</translation> <translation id="7106741999175697885">Gerenciador de tarefas - Google Chrome</translation> @@ -245,6 +248,7 @@ <translation id="7651907282515937834">Logotipo do Chrome Enterprise</translation> <translation id="7665553140559834626">Reinicializar para atualizar o &Chrome OS</translation> <translation id="7747138024166251722">O instalador não conseguiu criar um diretório temporário. Verifique se há espaço livre em disco e se há permissão para a instalação de software.</translation> +<translation id="7748512868279796735">As seguintes contas estão disponíveis neste perfil do Chrome</translation> <translation id="7761834446675418963">Clique no seu nome para abrir o Chrome e começar a navegar.</translation> <translation id="7777080907402804672">Se uma imagem não tiver uma descrição útil, o Chrome tentará fornecer uma para você. As imagens serão enviadas ao Google para a criação de descrições. É possível desativar essa opção nas configurações a qualquer momento.</translation> <translation id="7781002470561365167">Uma nova versão do Google Chrome está disponível.</translation> @@ -276,6 +280,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">Este perfil de trabalho é completamente separado do seu perfil pessoal.</translation> <translation id="8556340503434111824">Há uma nova versão ainda mais rápida do Google Chrome disponível.</translation> +<translation id="8571790202382503603">Você pode usar os perfis do Chrome para separar todos os seus dados nele. Assim, fica mais fácil dividir suas atividades entre trabalho e diversão.</translation> <translation id="8614913330719544658">O Google Chrome não responde. Reiniciar agora?</translation> <translation id="861702415419836452">O Chrome precisa de permissão para acessar sua câmera e criar um mapa 3D do ambiente a sua volta</translation> <translation id="8625237574518804553">{0,plural, =1{O Chrome será reiniciado em 1 minuto}one{O Chrome será reiniciado em # minuto}other{O Chrome será reiniciado em # minutos}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_pt-PT.xtb b/chrome/app/resources/google_chrome_strings_pt-PT.xtb index aca24f5..a5daaca3 100644 --- a/chrome/app/resources/google_chrome_strings_pt-PT.xtb +++ b/chrome/app/resources/google_chrome_strings_pt-PT.xtb
@@ -49,6 +49,7 @@ <translation id="2123055963409958220">Ajude a melhorar o Chrome ao comunicar as <ph name="BEGIN_LINK" />definições atuais<ph name="END_LINK" /></translation> <translation id="2151406531797534936">Reinicie o Chrome agora</translation> <translation id="2189289170880510015">Personalize algumas das opções de privacidade mais importantes do Chrome</translation> +<translation id="2258103955319320201">Para aceder aos seus itens do navegador Chrome em todos os seus dispositivos, inicie sessão e, em seguida, ative a sincronização</translation> <translation id="2290014774651636340">As chaves da API do Google estão em falta. Algumas funcionalidades do Google Chrome serão desativadas.</translation> <translation id="2290095356545025170">Tem a certeza de que pretende desinstalar o Google Chrome?</translation> <translation id="2309047409763057870">Esta é uma instalação secundária do Google Chrome, pelo que não pode tornar-se o navegador predefinido.</translation> @@ -208,6 +209,7 @@ <translation id="6506909944137591434">O Chrome necessita da autorização da câmara para criar um mapa 3D do ambiente à sua volta</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> – Google Chrome Dev</translation> <translation id="6568793831116033768">Sistema Chrome OS</translation> +<translation id="6594121454516132231">Veja como o Chrome planeia proteger o utilizador contra a monitorização entre sites, ao mesmo tempo que preserva a Web aberta</translation> <translation id="6676384891291319759">Aceder à Internet</translation> <translation id="6679975945624592337">Permitir que o Google Chrome seja executado em segundo plano</translation> <translation id="6696915334902295848">O Chrome necessita da autorização do microfone para este site</translation> @@ -222,6 +224,7 @@ <translation id="6989339256997917931">O Google Chrome foi atualizado, mas já não o utiliza há, pelo menos, 30 dias.</translation> <translation id="7025800014283535195">Pode alternar entre perfis do Chrome aqui</translation> <translation id="7062128746136194023">O teu pai/mãe desativou as "Autorizações para sites, apps e extensões" para o Chrome. Não é permitido adicionar esta <ph name="EXTENSION_TYPE_PARAMETER" />.</translation> +<translation id="7085332316435785646">Escolha se pretende incluir o Histórico do Chrome para obter mais experiências personalizadas nos serviços Google</translation> <translation id="7088681679121566888">O Chrome está atualizado.</translation> <translation id="7098166902387133879">O Google Chrome está a utilizar o microfone.</translation> <translation id="7106741999175697885">Gestor de tarefas - Google Chrome</translation> @@ -246,6 +249,7 @@ <translation id="7651907282515937834">Logótipo do Chrome Enterprise</translation> <translation id="7665553140559834626">Reiniciar para atualizar o &Chrome OS</translation> <translation id="7747138024166251722">O programa de instalação não conseguiu criar um directório temporário. Verifique se há espaço livre no disco e permissão para a instalação do software.</translation> +<translation id="7748512868279796735">As seguintes contas estão disponíveis para este perfil do Chrome</translation> <translation id="7761834446675418963">Clique no seu nome para abrir o Chrome e começar a navegar.</translation> <translation id="7777080907402804672">Se uma imagem não tiver uma descrição útil, o Chrome tenta fornecer uma. Para criar as descrições, são enviadas imagens para a Google. Pode desativar esta opção nas definições em qualquer altura.</translation> <translation id="7781002470561365167">Está disponível uma versão nova do Google Chrome.</translation> @@ -277,6 +281,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">Este perfil de trabalho está completamente separado do seu perfil pessoal.</translation> <translation id="8556340503434111824">Está disponível uma nova versão do Google Chrome, mais rápida do que nunca.</translation> +<translation id="8571790202382503603">Com os perfis do Chrome, pode separar todos os seus itens do Chrome. Desta forma, é mais fácil alternar entre o trabalho e o lazer.</translation> <translation id="8614913330719544658">O Google Chrome não responde. Reiniciar agora?</translation> <translation id="861702415419836452">O Chrome necessita de autorização de acesso à câmara para criar um mapa 3D do ambiente à sua volta.</translation> <translation id="8625237574518804553">{0,plural, =1{O Chrome será reiniciado dentro de 1 minuto}one{O Chrome será reiniciado dentro de # minuto(s)}other{O Chrome será reiniciado dentro de # minutos}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_tr.xtb b/chrome/app/resources/google_chrome_strings_tr.xtb index f361081..2a765df0 100644 --- a/chrome/app/resources/google_chrome_strings_tr.xtb +++ b/chrome/app/resources/google_chrome_strings_tr.xtb
@@ -48,6 +48,7 @@ <translation id="2123055963409958220"><ph name="BEGIN_LINK" />Mevcut ayarlarınızı<ph name="END_LINK" /> bildirerek Chrome'u daha iyi hale getirmemize yardımcı olun</translation> <translation id="2151406531797534936">Lütfen Chrome'u şimdi yeniden başlatın</translation> <translation id="2189289170880510015">Chrome'un en önemli gizlilik seçeneklerinden bazılarını özelleştirme</translation> +<translation id="2258103955319320201">Chrome öğelerinize tüm cihazlarınızda erişmek için oturum açın ve senkronizasyonu etkinleştirin</translation> <translation id="2290014774651636340">Google API anahtarları eksik. Google Chrome'un bazı işlevleri devre dışı bırakılacak.</translation> <translation id="2290095356545025170">Google Chrome'u kaldırmak istediğinizden emin misiniz?</translation> <translation id="2309047409763057870">Bu, Google Chrome'un ikincil bir yüklemesidir ve varsayılan tarayıcınız yapılamaz.</translation> @@ -210,6 +211,7 @@ <translation id="6506909944137591434">Çevrenizin 3D haritasını oluşturmak için Chrome'un kamera iznine ihtiyacı var</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6568793831116033768">Chrome OS sistemi</translation> +<translation id="6594121454516132231">Chrome'un açık web'i korurken sizi siteler arası izlemeden nasıl koruduğunu öğrenin</translation> <translation id="6676384891291319759">İnternet'e erişin</translation> <translation id="6679975945624592337">Google Chrome'un Arka Planda Çalışmasına İzin Ver</translation> <translation id="6696915334902295848">Bu site için Chrome'un mikrofon iznine ihtiyacı var</translation> @@ -224,6 +226,7 @@ <translation id="6989339256997917931">Google Chrome güncellendi, ancak programı en azından 30 gündür kullanmıyorsunuz.</translation> <translation id="7025800014283535195">Chrome profilleri arasında burada geçiş yapabilirsiniz</translation> <translation id="7062128746136194023">Ebeveyniniz, Chrome'a yönelik "Siteler, uygulamalar ve uzantılar için izinler"i kapattı. Bu <ph name="EXTENSION_TYPE_PARAMETER" /> uzantısını eklemeye izin verilmiyor.</translation> +<translation id="7085332316435785646">Google hizmetlerinde daha fazla kişiselleştirilmiş deneyimden faydalanmak için Chrome geçmişinin eklenip eklenmeyeceğini seçin</translation> <translation id="7088681679121566888">Chrome güncel</translation> <translation id="7098166902387133879">Google Chrome mikrofonunuzu kullanıyor.</translation> <translation id="7106741999175697885">Görev Yöneticisi - Google Chrome</translation> @@ -248,6 +251,7 @@ <translation id="7651907282515937834">Chrome Enterprise logosu</translation> <translation id="7665553140559834626">&Chrome OS'i güncellemek için yeniden başlat</translation> <translation id="7747138024166251722">Yükleyici geçici bir dizin oluşturamadı. Lütfen, kullanılabilir disk alanını ve yazılım yükleme iznini kontrol edin.</translation> +<translation id="7748512868279796735">Bu Chrome profili için aşağıdaki hesaplar kullanılabilir</translation> <translation id="7761834446675418963">Chrome'u açmak ve göz atmaya başlamak için adınızı tıklayın.</translation> <translation id="7777080907402804672">Bir resmin işe yarar bir açıklaması yoksa, Chrome sizin için bir açıklama sağlamaya çalışır. Açıklama oluşturmak için resimler Google'a gönderilir. Bu özelliği istediğiniz zaman ayarlardan kapatabilirsiniz.</translation> <translation id="7781002470561365167">Google Chrome'un yeni bir sürümü çıktı.</translation> @@ -279,6 +283,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">Bu iş profili, kişisel profilinizden tamamen ayrıdır.</translation> <translation id="8556340503434111824">Kullanabileceğiniz yeni bir Google Chrome sürümü var ve bu sürüm, her zamankinden daha hızlı.</translation> +<translation id="8571790202382503603">Chrome profilleri ile tüm Chrome öğelerinizi ayırabilirsiniz. Bu özellik, iş ile eğlenceyi daha kolay ayırmayı sağlar.</translation> <translation id="8614913330719544658">Google Chrome yanıt vermiyor. Yeniden başlatılsın mı?</translation> <translation id="861702415419836452">Çevrenizin 3D haritasını oluşturmak için Chrome'un kameranıza erişim iznine ihtiyacı var</translation> <translation id="8625237574518804553">{0,plural, =1{Chrome 1 dakika içinde yeniden başlatılacak}other{Chrome # dakika içinde yeniden başlatılacak}}</translation>
diff --git a/chrome/app/resources/google_chrome_strings_zu.xtb b/chrome/app/resources/google_chrome_strings_zu.xtb index fde5c0a..5f6fbe0 100644 --- a/chrome/app/resources/google_chrome_strings_zu.xtb +++ b/chrome/app/resources/google_chrome_strings_zu.xtb
@@ -53,6 +53,7 @@ <translation id="2123055963409958220">Siza ukwenza i-Chrome ibengcono ngokubika <ph name="BEGIN_LINK" />izilungiselelo zamanje<ph name="END_LINK" /></translation> <translation id="2151406531797534936">Sicela uqalise kabusha -Chrome manje</translation> <translation id="2189289170880510015">Enza ngendlela oyifisayo ezinye izinqumo zobumfihlo ezibaluleke kakhulu ze-Chrome</translation> +<translation id="2258103955319320201">Ukuze ufinyelele ezintweni zakho ze-browser ye-Chrome kuwo wonke amadivayisi wakho, ngena ngemvume, bese uvula ukuvumelanisa</translation> <translation id="2290014774651636340">Okhiye be-Google API abekho. Okunye ukusebenza kwe-Google Chrome kuzokhutshazwa.</translation> <translation id="2290095356545025170">Ingabe uqinisekile ukuthi ufuna ukukhipha i-Google Chrome?</translation> <translation id="2309047409763057870">Lokhu ukufakwa kwesibili kwe-Google Chrome, futhi akukwazi ukwenziwa isiphequluli sakho esizenzakalelayo.</translation> @@ -217,6 +218,7 @@ <translation id="6506909944137591434">I-Chrome idinga imvume yekhamera ukudala imephu ye-3D yendawo yakho ekuzungezile</translation> <translation id="6515495397637126556"><ph name="PAGE_TITLE" /> - Google Chrome Dev</translation> <translation id="6568793831116033768">Isistimu ye-Chrome OS</translation> +<translation id="6594121454516132231">Bona ukuthi i-Chrome ihlela kanjani ukukuvikela ekulandeleleni amasayithi amaningi ngenkathi ilondoloza iwebhu evuliwe</translation> <translation id="6676384891291319759">Finyelela i-inthanethi?</translation> <translation id="6679975945624592337">Vumela i-Google Chrome isebenze ngemuva</translation> <translation id="6696915334902295848">I-Chrome idinga imvume yemakrofoni kule sayithi</translation> @@ -231,6 +233,7 @@ <translation id="6989339256997917931">I-Google Chrome ibuyekeziwe, kodwa awukayisebenzisi ngokungenani izinsuku ezingu-30.</translation> <translation id="7025800014283535195">Ungashintsha phakathi kwamaphrofayela we-Chrome lapha</translation> <translation id="7062128746136194023">Umzali wakho uvale "Izimvume zamasayithi, izinhlelo zokusebenza, nezandiso" ze-Chrome. Ukwengeza le <ph name="EXTENSION_TYPE_PARAMETER" /> akuvumelekile.</translation> +<translation id="7085332316435785646">Khetha ukuthi ufake phakathi umlando we-Chrome ukuze uthole umuzwa womuntu siqu kumasevisi e-Google</translation> <translation id="7088681679121566888">I-Chrome isesimweni sakamuva</translation> <translation id="7098166902387133879">I-Google Chrome isebenzisa imakrofoni yakho.</translation> <translation id="7106741999175697885">Isiphathi somsebenzi - i-Google Chrome</translation> @@ -255,6 +258,7 @@ <translation id="7651907282515937834">Ilogo yebhizinisi le-Chrome</translation> <translation id="7665553140559834626">Qalisa kabusha ukuze ubuyekeze i-&Chrome OS</translation> <translation id="7747138024166251722">Isifaki asikwazanga ukudala umkhombandlela wesikhashana. Sicela uhlolele isikhala esikhululekile sediski nemvume ukuze ufake isofthiwe.</translation> +<translation id="7748512868279796735">Ama-akhawunti alandelayo ayatholakala kule phrofayela ye-Chrome</translation> <translation id="7761834446675418963">Chofoza igama lakho ukuze uvule i-Chrome uphinde uqale ukudlulisa amehlo.</translation> <translation id="7777080907402804672">Uma isithombe singenayo incazelo ephelele, i-Chrome izozama ukukunikezela eyodwa. Ukuze udale izincazelo, izithombe zithunyelwa ku-Google. Ungavala lokhu kuzilungiselelo noma kunini.</translation> <translation id="7781002470561365167">Kukhona inguqulo entsha etholakalayo ye-Google Chrome.</translation> @@ -286,6 +290,7 @@ <translation id="8540666473246803645">Google Chrome</translation> <translation id="8550334526674375523">Le phrofayela yomsebenzi ihluke ngokugcwele kusukela kuphrofayela yakho siqu.</translation> <translation id="8556340503434111824">Kukhona inguqulo entsha ye-Google Chrome etholakalayo, futhi ishesha kakhulu kunakuqala.</translation> +<translation id="8571790202382503603">Ngamaphrofayela we-Chrome ungahlukanisa zonke izinto zakho ze-Chrome. Lokhu kwenza kube lula ukuhlukanisa phakathi komsebenzi nokuzijabulisa.</translation> <translation id="8614913330719544658">I-Google Chrome ayiphenduli. Qalisa kabusha manje?</translation> <translation id="861702415419836452">I-Chrome idinga imvume yokufinyelela kwikhamera yakho ukudala imephu engu-3D yendawo yakho ekuzungezile</translation> <translation id="8625237574518804553">{0,plural, =1{I-Chrome izoqalisa kabusha kuminithi elingu-1}one{I-Chrome izoqalisa kabusha kumaminithi angu-#}other{I-Chrome izoqalisa kabusha kumaminithi angu-#}}</translation>
diff --git a/chrome/app/sharesheet_strings.grdp b/chrome/app/sharesheet_strings.grdp index 8f0aedf..c3f1fbfdc 100644 --- a/chrome/app/sharesheet_strings.grdp +++ b/chrome/app/sharesheet_strings.grdp
@@ -26,6 +26,6 @@ other {{COUNT} files}} </message> <message name="IDS_SHARESHEET_COPY_TO_CLIPBOARD_SHARE_ACTION_LABEL" desc="The label for the button in the sharesheet that copies the data the user has selected to the clipboard."> - Copy to clipboard + Copy </message> </grit-part>
diff --git a/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_COPY_TO_CLIPBOARD_SHARE_ACTION_LABEL.png.sha1 b/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_COPY_TO_CLIPBOARD_SHARE_ACTION_LABEL.png.sha1 index a5597f8..30438a0 100644 --- a/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_COPY_TO_CLIPBOARD_SHARE_ACTION_LABEL.png.sha1 +++ b/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_COPY_TO_CLIPBOARD_SHARE_ACTION_LABEL.png.sha1
@@ -1 +1 @@ -1edb14e77abe212b4a59151818d31c58d3ea9ac2 \ No newline at end of file +e3bc1e8b928cd4f6f30d9780bbbfbd3f26523291 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 5b9b2f0..840c214 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1281,6 +1281,8 @@ "prefetch/no_state_prefetch/no_state_prefetch_tab_helper.h", "prefetch/pref_names.cc", "prefetch/pref_names.h", + "prefetch/prefetch_prefs.cc", + "prefetch/prefetch_prefs.h", "prefetch/prefetch_proxy/chrome_speculation_host_delegate.cc", "prefetch/prefetch_proxy/chrome_speculation_host_delegate.h", "prefetch/prefetch_proxy/prefetch_proxy_cookie_listener.cc", @@ -3236,8 +3238,8 @@ "password_manager/android/password_ui_view_android.h", "password_manager/android/save_password_infobar_delegate_android.cc", "password_manager/android/save_password_infobar_delegate_android.h", - "password_manager/android/save_password_message_delegate.cc", - "password_manager/android/save_password_message_delegate.h", + "password_manager/android/save_update_password_message_delegate.cc", + "password_manager/android/save_update_password_message_delegate.h", "password_manager/android/update_password_infobar_delegate_android.cc", "password_manager/android/update_password_infobar_delegate_android.h", "password_manager/password_scripts_fetcher_factory.cc", @@ -3267,6 +3269,7 @@ "policy/cloud/user_policy_signin_service_mobile.cc", "policy/cloud/user_policy_signin_service_mobile.h", "policy/policy_service_factory_android.cc", + "prefetch/android/preload_pages_settings_bridge.cc", "privacy/secure_dns_bridge.cc", "privacy_sandbox/android/privacy_sandbox_bridge.cc", "profiles/android/profile_manager_utils.cc", @@ -3391,6 +3394,7 @@ "//chrome/browser/policy/android:android", "//chrome/browser/policy/android:jni_headers", "//chrome/browser/power_bookmarks", + "//chrome/browser/prefetch/android:jni_headers", "//chrome/browser/privacy:jni_headers", "//chrome/browser/privacy_sandbox/android:jni_headers", "//chrome/browser/reading_list/android", @@ -5639,6 +5643,10 @@ if (is_linux || is_win || is_mac || is_chromeos_ash) { sources += [ + "enterprise/connectors/device_trust/device_trust_connector_service.cc", + "enterprise/connectors/device_trust/device_trust_connector_service.h", + "enterprise/connectors/device_trust/device_trust_connector_service_factory.cc", + "enterprise/connectors/device_trust/device_trust_connector_service_factory.h", "enterprise/connectors/device_trust/device_trust_service.cc", "enterprise/connectors/device_trust/device_trust_service.h", "enterprise/connectors/device_trust/device_trust_service_factory.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 38b3a5c9..69a74812 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -6617,10 +6617,6 @@ flag_descriptions::kProductivityLauncherAnimationName, flag_descriptions::kProductivityLauncherAnimationDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kProductivityLauncherAnimation)}, - {"enable-launcher-app-paging", - flag_descriptions::kNewDragSpecInLauncherName, - flag_descriptions::kNewDragSpecInLauncherDescription, kOsCrOS, - FEATURE_VALUE_TYPE(app_list_features::kNewDragSpecInLauncher)}, {"shelf-drag-to-pin", flag_descriptions::kShelfDragToPinName, flag_descriptions::kShelfDragToPinDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kDragUnpinnedAppToPin)},
diff --git a/chrome/browser/apps/app_service/BUILD.gn b/chrome/browser/apps/app_service/BUILD.gn index 538a43e..3e9327a 100644 --- a/chrome/browser/apps/app_service/BUILD.gn +++ b/chrome/browser/apps/app_service/BUILD.gn
@@ -13,6 +13,8 @@ deps = [ "//build:chromeos_buildflags", "//chrome/test:test_support", + "//components/services/app_service/public/cpp:app_types", + "//components/services/app_service/public/cpp:icon_types", "//components/services/app_service/public/mojom", "//skia", ]
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_source.cc b/chrome/browser/apps/app_service/app_icon/app_icon_source.cc index 8009d25c..2128daa 100644 --- a/chrome/browser/apps/app_service/app_icon/app_icon_source.cc +++ b/chrome/browser/apps/app_service/app_icon/app_icon_source.cc
@@ -16,7 +16,10 @@ #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/url_constants.h" +#include "components/services/app_service/public/cpp/app_types.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "extensions/grit/extensions_browser_resources.h" #include "ui/base/resource/resource_bundle.h" #include "url/gurl.h" @@ -37,13 +40,13 @@ } void RunCallback(content::URLDataSource::GotDataCallback callback, - apps::mojom::IconValuePtr iv) { - if (!iv->compressed.has_value() || iv->compressed.value().empty()) { + apps::IconValuePtr iv) { + if (!iv || iv->compressed.empty()) { LoadDefaultImage(std::move(callback)); return; } base::RefCountedBytes* image_bytes = - new base::RefCountedBytes(iv->compressed.value()); + new base::RefCountedBytes(iv->compressed); std::move(callback).Run(image_bytes); } @@ -99,10 +102,18 @@ const apps::mojom::AppType app_type = app_service_proxy->AppRegistryCache().GetAppType(app_id); constexpr bool allow_placeholder_icon = false; - app_service_proxy->LoadIcon( - app_type, app_id, apps::mojom::IconType::kCompressed, size_in_dip, - allow_placeholder_icon, - base::BindOnce(&RunCallback, std::move(callback))); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + app_service_proxy->LoadIcon( + ConvertMojomAppTypToAppType(app_type), app_id, IconType::kCompressed, + size_in_dip, allow_placeholder_icon, + base::BindOnce(&RunCallback, std::move(callback))); + } else { + app_service_proxy->LoadIcon( + app_type, app_id, apps::mojom::IconType::kCompressed, size_in_dip, + allow_placeholder_icon, + MojomIconValueToIconValueCallback( + base::BindOnce(&RunCallback, std::move(callback)))); + } } std::string AppIconSource::GetMimeType(const std::string&) {
diff --git a/chrome/browser/apps/app_service/app_service_test.cc b/chrome/browser/apps/app_service/app_service_test.cc index 005809a..2e5d6c2f 100644 --- a/chrome/browser/apps/app_service/app_service_test.cc +++ b/chrome/browser/apps/app_service/app_service_test.cc
@@ -7,6 +7,9 @@ #include "base/run_loop.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" +#include "chrome/common/chrome_features.h" +#include "components/services/app_service/public/cpp/app_types.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "ui/gfx/image/image_unittest_util.h" #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -65,18 +68,32 @@ base::RunLoop run_loop; base::OnceClosure load_app_icon_callback = run_loop.QuitClosure(); - app_service_proxy_->LoadIcon( - app_type, app_id, apps::mojom::IconType::kStandard, size_hint_in_dip, - false /* allow_placeholder_icon */, - base::BindOnce( - [](gfx::ImageSkia* icon, base::OnceClosure load_app_icon_callback, - apps::mojom::IconValuePtr icon_value) { - DCHECK_EQ(apps::mojom::IconType::kStandard, icon_value->icon_type); - *icon = icon_value->uncompressed; - std::move(load_app_icon_callback).Run(); - }, - &image_skia, std::move(load_app_icon_callback))); - + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + app_service_proxy_->LoadIcon( + ConvertMojomAppTypToAppType(app_type), app_id, IconType::kStandard, + size_hint_in_dip, false /* allow_placeholder_icon */, + base::BindOnce( + [](gfx::ImageSkia* icon, base::OnceClosure load_app_icon_callback, + IconValuePtr icon_value) { + DCHECK_EQ(IconType::kStandard, icon_value->icon_type); + *icon = icon_value->uncompressed; + std::move(load_app_icon_callback).Run(); + }, + &image_skia, std::move(load_app_icon_callback))); + } else { + app_service_proxy_->LoadIcon( + app_type, app_id, apps::mojom::IconType::kStandard, size_hint_in_dip, + false /* allow_placeholder_icon */, + base::BindOnce( + [](gfx::ImageSkia* icon, base::OnceClosure load_app_icon_callback, + apps::mojom::IconValuePtr icon_value) { + DCHECK_EQ(apps::mojom::IconType::kStandard, + icon_value->icon_type); + *icon = icon_value->uncompressed; + std::move(load_app_icon_callback).Run(); + }, + &image_skia, std::move(load_app_icon_callback))); + } run_loop.Run(); return image_skia; }
diff --git a/chrome/browser/apps/app_service/app_web_contents_data.cc b/chrome/browser/apps/app_service/app_web_contents_data.cc index 5f3dc0de..b1a85f1 100644 --- a/chrome/browser/apps/app_service/app_web_contents_data.cc +++ b/chrome/browser/apps/app_service/app_web_contents_data.cc
@@ -8,8 +8,9 @@ AppWebContentsData::AppWebContentsData(content::WebContents* web_contents, Client* client) - : content::WebContentsObserver(web_contents), client_(client) { - DCHECK(web_contents); + : content::WebContentsUserData<AppWebContentsData>(*web_contents), + content::WebContentsObserver(web_contents), + client_(client) { DCHECK(client); }
diff --git a/chrome/browser/apps/app_service/publishers/app_publisher.h b/chrome/browser/apps/app_service/publishers/app_publisher.h index c39bdcf..3737567 100644 --- a/chrome/browser/apps/app_service/publishers/app_publisher.h +++ b/chrome/browser/apps/app_service/publishers/app_publisher.h
@@ -15,6 +15,14 @@ namespace apps { +struct AppLaunchParams; + +struct LaunchResult { + base::UnguessableToken instance_id; +}; + +using LaunchCallback = base::OnceCallback<void(LaunchResult&&)>; + // AppPublisher parent class (in the App Service sense) for all app publishers. // See components/services/app_service/README.md. // @@ -62,6 +70,15 @@ bool allow_placeholder_icon, LoadIconCallback callback) = 0; + // Launches an app with |params|. + // + // Publishers implementing this method should: + // - Launch the app represent by the |params.app_id|. + // - Launch the app with all the params that is applicable to the platform. + // - Return launch_result if applicable. + virtual void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) = 0; + protected: // Publish one `app` to AppServiceProxy. Should be called whenever the app // represented by `app` undergoes some state change to inform AppServiceProxy
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.cc b/chrome/browser/apps/app_service/publishers/arc_apps.cc index 6737813d..8bb55a07 100644 --- a/chrome/browser/apps/app_service/publishers/arc_apps.cc +++ b/chrome/browser/apps/app_service/publishers/arc_apps.cc
@@ -21,6 +21,7 @@ #include "base/task/post_task.h" #include "base/task/thread_pool.h" #include "chrome/browser/apps/app_service/app_icon/dip_px_util.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #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/file_utils.h" @@ -662,6 +663,23 @@ } } +void ArcApps::LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) { + auto event_flags = apps::GetEventFlags(params.container, params.disposition, + /*prefer_container=*/false); + auto window_info = apps::MakeWindowInfo(params.display_id); + if (params.intent) { + LaunchAppWithIntent(params.app_id, event_flags, std::move(params.intent), + params.launch_source, std::move(window_info), + base::DoNothing()); + } else { + Launch(params.app_id, event_flags, params.launch_source, + std::move(window_info)); + } + // TODO(crbug.com/1244506): Add launch return value. + std::move(callback).Run(LaunchResult()); +} + void ArcApps::Connect( mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, apps::mojom::ConnectOptionsPtr opts) {
diff --git a/chrome/browser/apps/app_service/publishers/arc_apps.h b/chrome/browser/apps/app_service/publishers/arc_apps.h index 53c56c0..82c84e4 100644 --- a/chrome/browser/apps/app_service/publishers/arc_apps.h +++ b/chrome/browser/apps/app_service/publishers/arc_apps.h
@@ -46,6 +46,7 @@ class PublisherTest; class WebApkManager; +struct AppLaunchParams; // An app publisher (in the App Service sense) of ARC++ apps, // @@ -95,6 +96,8 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::LoadIconCallback callback) override; + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) override; // apps::mojom::Publisher overrides. void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/borealis_apps.cc b/chrome/browser/apps/app_service/publishers/borealis_apps.cc index 1c6373e..435e3c7 100644 --- a/chrome/browser/apps/app_service/publishers/borealis_apps.cc +++ b/chrome/browser/apps/app_service/publishers/borealis_apps.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/menu_util.h" #include "chrome/browser/ash/borealis/borealis_app_launcher.h" @@ -250,6 +251,14 @@ std::move(callback)); } +void BorealisApps::LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) { + Launch(params.app_id, ui::EF_NONE, apps::mojom::LaunchSource::kUnknown, + nullptr); + // TODO(crbug.com/1244506): Add launch return value. + std::move(callback).Run(LaunchResult()); +} + void BorealisApps::Connect( mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, apps::mojom::ConnectOptionsPtr opts) {
diff --git a/chrome/browser/apps/app_service/publishers/borealis_apps.h b/chrome/browser/apps/app_service/publishers/borealis_apps.h index 873da1c..afec6c2 100644 --- a/chrome/browser/apps/app_service/publishers/borealis_apps.h +++ b/chrome/browser/apps/app_service/publishers/borealis_apps.h
@@ -28,6 +28,8 @@ class PublisherHost; +struct AppLaunchParams; + // An app publisher (in the App Service sense) of Borealis apps. // See components/services/app_service/README.md. // @@ -72,6 +74,8 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::LoadIconCallback callback) override; + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) override; // apps::PublisherBase overrides. void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc index 9064d1a7..e02f32da 100644 --- a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc +++ b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.cc
@@ -13,6 +13,7 @@ #include "ash/public/cpp/keyboard_shortcut_viewer.h" #include "base/time/time.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/menu_util.h" #include "chrome/browser/apps/app_service/metrics/app_service_metrics.h" @@ -130,6 +131,14 @@ std::move(callback).Run(std::make_unique<IconValue>()); } +void BuiltInChromeOsApps::LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) { + Launch(params.app_id, ui::EF_NONE, apps::mojom::LaunchSource::kUnknown, + nullptr); + // TODO(crbug.com/1244506): Add launch return value. + std::move(callback).Run(LaunchResult()); +} + void BuiltInChromeOsApps::Connect( mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, apps::mojom::ConnectOptionsPtr opts) {
diff --git a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h index 8fa3956..96990d0 100644 --- a/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h +++ b/chrome/browser/apps/app_service/publishers/built_in_chromeos_apps.h
@@ -21,6 +21,8 @@ class PublisherHost; +struct AppLaunchParams; + // An app publisher (in the App Service sense) of built-in Chrome OS apps. // // See components/services/app_service/README.md. @@ -47,6 +49,8 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::LoadIconCallback callback) override; + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) override; // apps::mojom::Publisher overrides. void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/crostini_apps.cc b/chrome/browser/apps/app_service/publishers/crostini_apps.cc index c6ec79ea..af39385 100644 --- a/chrome/browser/apps/app_service/publishers/crostini_apps.cc +++ b/chrome/browser/apps/app_service/publishers/crostini_apps.cc
@@ -12,7 +12,9 @@ #include "base/strings/stringprintf.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h" #include "chrome/browser/apps/app_service/app_icon/dip_px_util.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" +#include "chrome/browser/apps/app_service/launch_utils.h" #include "chrome/browser/apps/app_service/menu_util.h" #include "chrome/browser/ash/crostini/crostini_features.h" #include "chrome/browser/ash/crostini/crostini_package_service.h" @@ -138,6 +140,23 @@ std::move(callback)); } +void CrostiniApps::LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) { + auto event_flags = apps::GetEventFlags(params.container, params.disposition, + /*prefer_container=*/false); + auto window_info = apps::MakeWindowInfo(params.display_id); + if (params.intent) { + LaunchAppWithIntent(params.app_id, event_flags, std::move(params.intent), + params.launch_source, std::move(window_info), + base::DoNothing()); + } else { + Launch(params.app_id, event_flags, params.launch_source, + std::move(window_info)); + } + // TODO(crbug.com/1244506): Add launch return value. + std::move(callback).Run(LaunchResult()); +} + void CrostiniApps::Connect( mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, apps::mojom::ConnectOptionsPtr opts) {
diff --git a/chrome/browser/apps/app_service/publishers/crostini_apps.h b/chrome/browser/apps/app_service/publishers/crostini_apps.h index 5f440db0..ed8c3a51c 100644 --- a/chrome/browser/apps/app_service/publishers/crostini_apps.h +++ b/chrome/browser/apps/app_service/publishers/crostini_apps.h
@@ -30,6 +30,8 @@ class PublisherHost; +struct AppLaunchParams; + // An app publisher (in the App Service sense) of Crostini apps, // // See components/services/app_service/README.md. @@ -59,6 +61,8 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::LoadIconCallback callback) override; + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) override; // apps::mojom::Publisher overrides. void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_base.cc b/chrome/browser/apps/app_service/publishers/extension_apps_base.cc index e454127..7976727 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_base.cc +++ b/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
@@ -15,6 +15,7 @@ #include "base/scoped_observation.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #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/extension_uninstaller.h" @@ -373,6 +374,13 @@ std::move(callback)); } +void ExtensionAppsBase::LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) { + LaunchImpl(std::move(params)); + // TODO(crbug.com/1244506): Add launch return value. + std::move(callback).Run(LaunchResult()); +} + void ExtensionAppsBase::Connect( mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, apps::mojom::ConnectOptionsPtr opts) {
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_base.h b/chrome/browser/apps/app_service/publishers/extension_apps_base.h index 1fe7f14..b5d59e3 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_base.h +++ b/chrome/browser/apps/app_service/publishers/extension_apps_base.h
@@ -13,7 +13,6 @@ #include "base/scoped_observation.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h" #include "chrome/browser/apps/app_service/app_icon/icon_key_util.h" -#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/publishers/app_publisher.h" #include "components/services/app_service/public/cpp/publisher_base.h" #include "components/services/app_service/public/mojom/app_service.mojom.h" @@ -39,6 +38,8 @@ namespace apps { class ExtensionAppsEnableFlow; +struct AppLaunchParams; + // An app base publisher (in the App Service sense) of extension-backed apps, // including Chrome Apps (platform apps and legacy packaged apps) and hosted // apps. @@ -138,6 +139,8 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::LoadIconCallback callback) override; + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) override; // apps::mojom::Publisher overrides. void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
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 3fb50da..ed6e9fa 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc +++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -200,8 +200,9 @@ if (launch_source == apps::mojom::LaunchSource::kFromArc && web_contents) { // Add a flag to remember this web_contents originated in the ARC context. - web_contents->SetUserData(&arc::ArcWebContentsData::kArcTransitionFlag, - std::make_unique<arc::ArcWebContentsData>()); + web_contents->SetUserData( + &arc::ArcWebContentsData::kArcTransitionFlag, + std::make_unique<arc::ArcWebContentsData>(web_contents)); } }
diff --git a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc index ad0f131..667c1db8 100644 --- a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc +++ b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.cc
@@ -12,6 +12,7 @@ #include "base/metrics/user_metrics.h" #include "base/time/time.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/menu_util.h" #include "chrome/browser/apps/app_service/metrics/app_service_metrics.h" @@ -244,6 +245,14 @@ IconValueToMojomIconValueCallback(std::move(callback))); } +void PluginVmApps::LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) { + Launch(params.app_id, ui::EF_NONE, apps::mojom::LaunchSource::kUnknown, + nullptr); + // TODO(crbug.com/1244506): Add launch return value. + std::move(callback).Run(LaunchResult()); +} + void PluginVmApps::Launch(const std::string& app_id, int32_t event_flags, apps::mojom::LaunchSource launch_source,
diff --git a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h index 1582b7e..d9409eb 100644 --- a/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h +++ b/chrome/browser/apps/app_service/publishers/plugin_vm_apps.h
@@ -27,6 +27,8 @@ class PublisherHost; +struct AppLaunchParams; + // An app publisher (in the App Service sense) of Plugin VM apps. // // See components/services/app_service/README.md. @@ -56,6 +58,8 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::LoadIconCallback callback) override; + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) override; // apps::PublisherBase overrides. void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/remote_apps.cc b/chrome/browser/apps/app_service/publishers/remote_apps.cc index eb52a6d..263a503b 100644 --- a/chrome/browser/apps/app_service/publishers/remote_apps.cc +++ b/chrome/browser/apps/app_service/publishers/remote_apps.cc
@@ -8,6 +8,7 @@ #include "base/callback.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "ui/gfx/image/image_skia.h" @@ -120,6 +121,14 @@ std::move(callback)); } +void RemoteApps::LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) { + Launch(params.app_id, ui::EF_NONE, apps::mojom::LaunchSource::kUnknown, + nullptr); + // TODO(crbug.com/1244506): Add launch return value. + std::move(callback).Run(LaunchResult()); +} + void RemoteApps::Connect( mojo::PendingRemote<mojom::Subscriber> subscriber_remote, mojom::ConnectOptionsPtr opts) {
diff --git a/chrome/browser/apps/app_service/publishers/remote_apps.h b/chrome/browser/apps/app_service/publishers/remote_apps.h index cd6f17c..a07fc6a 100644 --- a/chrome/browser/apps/app_service/publishers/remote_apps.h +++ b/chrome/browser/apps/app_service/publishers/remote_apps.h
@@ -30,6 +30,7 @@ } namespace apps { +struct AppLaunchParams; // An app publisher (in the App Service sense) of Remote apps. // @@ -86,6 +87,8 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::LoadIconCallback callback) override; + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) override; // apps::PublisherBase: void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc index 219a268..809ba9b 100644 --- a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc +++ b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.cc
@@ -10,6 +10,7 @@ #include "base/bind.h" #include "build/branding_buildflags.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/browser_app_instance_registry.h" #include "chrome/browser/apps/app_service/menu_util.h" @@ -126,6 +127,14 @@ std::move(callback)); } +void StandaloneBrowserApps::LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) { + Launch(params.app_id, ui::EF_NONE, apps::mojom::LaunchSource::kUnknown, + nullptr); + // TODO(crbug.com/1244506): Add launch return value. + std::move(callback).Run(LaunchResult()); +} + void StandaloneBrowserApps::Connect( mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, apps::mojom::ConnectOptionsPtr opts) {
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h index 872cbd6..d787643 100644 --- a/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h +++ b/chrome/browser/apps/app_service/publishers/standalone_browser_apps.h
@@ -25,6 +25,8 @@ class BrowserAppInstanceRegistry; class PublisherHost; +struct AppLaunchParams; + // An app publisher (in the App Service sense) for the "LaCrOS" app icon, // which launches the lacros-chrome binary. // @@ -64,6 +66,8 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::LoadIconCallback callback) override; + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) override; // apps::PublisherBase: void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc index 13c8f40..44ce79a 100644 --- a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc +++ b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/callback_helpers.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" #include "chrome/browser/apps/app_service/intent_util.h" #include "chrome/browser/ash/crosapi/browser_util.h" @@ -66,6 +67,18 @@ icon_type, size_hint_in_dip, std::move(callback)); } +void StandaloneBrowserExtensionApps::LaunchAppWithParams( + AppLaunchParams&& params, + LaunchCallback callback) { + if (!controller_.is_bound()) { + std::move(callback).Run(LaunchResult()); + return; + } + + // TODO(crbug.com/1244506): Add params on crosapi and implement this. + std::move(callback).Run(LaunchResult()); +} + void StandaloneBrowserExtensionApps::Connect( mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, apps::mojom::ConnectOptionsPtr opts) {
diff --git a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h index 2711a12..4ebe459 100644 --- a/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h +++ b/chrome/browser/apps/app_service/publishers/standalone_browser_extension_apps.h
@@ -23,6 +23,7 @@ class StandaloneBrowserPublisherTest; namespace apps { +struct AppLaunchParams; // An app publisher (in the App Service sense) for extension-based apps [e.g. // packaged v2 apps] published by Lacros. @@ -76,6 +77,8 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::LoadIconCallback callback) override; + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) override; // apps::PublisherBase: void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc b/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc index d2053e6..aa3fe91 100644 --- a/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc +++ b/chrome/browser/apps/app_service/publishers/web_apps_crosapi.cc
@@ -13,6 +13,7 @@ #include "base/location.h" #include "base/logging.h" #include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h" +#include "chrome/browser/apps/app_service/app_launch_params.h" #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/browser_app_instance_registry.h" @@ -77,6 +78,16 @@ icon_effects, size_hint_in_dip, std::move(callback))); } +void WebAppsCrosapi::LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) { + if (!LogIfNotConnected(FROM_HERE)) { + std::move(callback).Run(LaunchResult()); + return; + } + // TODO(crbug.com/1244506): Add params on crosapi and implement this. + std::move(callback).Run(LaunchResult()); +} + void WebAppsCrosapi::Connect( mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, apps::mojom::ConnectOptionsPtr opts) {
diff --git a/chrome/browser/apps/app_service/publishers/web_apps_crosapi.h b/chrome/browser/apps/app_service/publishers/web_apps_crosapi.h index c7d3acc5..618cca59 100644 --- a/chrome/browser/apps/app_service/publishers/web_apps_crosapi.h +++ b/chrome/browser/apps/app_service/publishers/web_apps_crosapi.h
@@ -30,6 +30,8 @@ class StandaloneBrowserPublisherTest; +struct AppLaunchParams; + // An app publisher for crosapi web apps. This is a proxy publisher that lives // in ash-chrome, and the apps will be published over crosapi. This proxy // publisher will also handle reconnection when the crosapi connection drops. @@ -65,6 +67,8 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::LoadIconCallback callback) override; + void LaunchAppWithParams(AppLaunchParams&& params, + LaunchCallback callback) override; // apps::PublisherBase overrides. void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/apps/app_service/uninstall_dialog.cc b/chrome/browser/apps/app_service/uninstall_dialog.cc index 3a92f2d..eee67cb 100644 --- a/chrome/browser/apps/app_service/uninstall_dialog.cc +++ b/chrome/browser/apps/app_service/uninstall_dialog.cc
@@ -76,8 +76,8 @@ icon_loader->LoadIconFromIconKey( app_type, app_id, std::move(mojom_icon_key), mojom_icon_type, size_hint_in_dip, kAllowPlaceholderIcon, - base::BindOnce(&UninstallDialog::OnLoadMojomIcon, - weak_ptr_factory_.GetWeakPtr())); + MojomIconValueToIconValueCallback(base::BindOnce( + &UninstallDialog::OnLoadIcon, weak_ptr_factory_.GetWeakPtr()))); } } @@ -122,9 +122,4 @@ } } -void UninstallDialog::OnLoadMojomIcon( - apps::mojom::IconValuePtr mojom_icon_value) { - OnLoadIcon(ConvertMojomIconValueToIconValue(std::move(mojom_icon_value))); -} - } // namespace apps
diff --git a/chrome/browser/apps/app_service/uninstall_dialog.h b/chrome/browser/apps/app_service/uninstall_dialog.h index a0b617e1..9ce0857 100644 --- a/chrome/browser/apps/app_service/uninstall_dialog.h +++ b/chrome/browser/apps/app_service/uninstall_dialog.h
@@ -102,9 +102,6 @@ // Callback invoked when the icon is loaded. void OnLoadIcon(IconValuePtr icon_value); - // TODO(crbug.com/1253250): Will be removed soon. - void OnLoadMojomIcon(apps::mojom::IconValuePtr mojom_icon_value); - Profile* const profile_; const apps::mojom::AppType app_type_; const std::string app_id_;
diff --git a/chrome/browser/ash/DEPS b/chrome/browser/ash/DEPS index d2fdbcc..1bea36f 100644 --- a/chrome/browser/ash/DEPS +++ b/chrome/browser/ash/DEPS
@@ -10,7 +10,7 @@ # crbug.com/728877 "+chrome/browser/ui/views/chrome_layout_provider.h", - "+chrome/services/keymaster/public", + "+chrome/services/keymaster/public", # nocheck "+chrome/services/wilco_dtc_supportd/public", "+components/account_manager_core", "+components/app_restore",
diff --git a/chrome/browser/ash/accessibility/dictation_browsertest.cc b/chrome/browser/ash/accessibility/dictation_browsertest.cc index 93523ca..ae89d08 100644 --- a/chrome/browser/ash/accessibility/dictation_browsertest.cc +++ b/chrome/browser/ash/accessibility/dictation_browsertest.cc
@@ -10,7 +10,11 @@ #include "ash/constants/ash_pref_names.h" #include "ash/shell.h" #include "base/bind.h" +#include "base/hash/hash.h" +#include "base/metrics/metrics_hashes.h" +#include "base/metrics/statistics_recorder.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/metrics/histogram_tester.h" #include "base/timer/timer.h" #include "chrome/browser/ash/accessibility/accessibility_manager.h" #include "chrome/browser/ash/accessibility/accessibility_test_utils.h" @@ -24,9 +28,11 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/metrics/content/subprocess_metrics_provider.h" #include "components/prefs/pref_service.h" #include "components/soda/soda_installer.h" #include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/fake_speech_recognition_manager.h" #include "extensions/browser/extension_host_test_helper.h" #include "media/mojo/mojom/speech_recognition_service.mojom.h" @@ -54,6 +60,13 @@ const char kFinalSpeechResult[] = "hello world"; const char16_t kFinalSpeechResult16[] = u"hello world"; const int kNoSpeechTimeoutInSeconds = 10; +const char* kOnDeviceListeningDurationMetric = + "Accessibility.CrosDictation.ListeningDuration.OnDeviceRecognition"; +const char* kNetworkListeningDurationMetric = + "Accessibility.CrosDictation.ListeningDuration.NetworkRecognition"; +const char* kLocaleMetric = "Accessibility.CrosDictation.Language"; +const char* kOnDeviceSpeechMetric = + "Accessibility.CrosDictation.UsedOnDeviceSpeech"; static const char* kEnglishDictationCommands[] = { "delete", @@ -75,6 +88,39 @@ return ProfileManager::GetActiveUserProfile()->GetPrefs(); } +// Listens for changes to the histogram provided at construction. This class +// only allows `Wait()` to be called once. If you need to call `Wait()` multiple +// times, create multiple instances of this class. +class HistogramWaiterOneShot { + public: + explicit HistogramWaiterOneShot(const char* metric_name) { + histogram_observer_ = std::make_unique< + base::StatisticsRecorder::ScopedHistogramSampleObserver>( + metric_name, + base::BindRepeating(&HistogramWaiterOneShot::OnHistogramCallback, + base::Unretained(this))); + } + ~HistogramWaiterOneShot() { histogram_observer_.reset(); } + + HistogramWaiterOneShot(const HistogramWaiterOneShot&) = delete; + HistogramWaiterOneShot& operator=(const HistogramWaiterOneShot&) = delete; + + // Waits for the next update to the observed histogram. + void Wait() { run_loop_.Run(); } + + void OnHistogramCallback(const char* metric_name, + uint64_t name_hash, + base::HistogramBase::Sample sample) { + run_loop_.Quit(); + histogram_observer_.reset(); + } + + private: + std::unique_ptr<base::StatisticsRecorder::ScopedHistogramSampleObserver> + histogram_observer_; + base::RunLoop run_loop_; +}; + } // namespace // This class performs common setup and teardown operations for Dictation tests, @@ -480,6 +526,53 @@ } } +// Ensures that the correct metrics are recorded when Dictation is toggled. +IN_PROC_BROWSER_TEST_P(DictationTest, Metrics) { + base::HistogramTester histogram_tester_; + bool on_device = GetParam() == speech::SpeechRecognitionType::kOnDevice; + const char* metric_name = on_device ? kOnDeviceListeningDurationMetric + : kNetworkListeningDurationMetric; + HistogramWaiterOneShot waiter(metric_name); + ToggleDictation(); + WaitForRecognitionStarted(); + ToggleDictation(); + WaitForRecognitionStopped(); + waiter.Wait(); + content::FetchHistogramsFromChildProcesses(); + metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + + // Ensure that we recorded the correct locale. + const std::string locale = on_device ? "en-US" : "en"; + histogram_tester_.ExpectUniqueSample(/*name=*/kLocaleMetric, + /*sample=*/base::HashMetricName(locale), + /*expected_bucket_count=*/1); + // Ensure that we recorded the type of speech recognition and listening + // duration. + if (on_device) { + histogram_tester_.ExpectUniqueSample(/*name=*/kOnDeviceSpeechMetric, + /*sample=*/true, + /*expected_bucket_count=*/1); + ASSERT_EQ(1, + histogram_tester_.GetAllSamples(kOnDeviceListeningDurationMetric) + .size()); + // Ensure there are no metrics for the other type of speech recognition. + ASSERT_EQ(0, + histogram_tester_.GetAllSamples(kNetworkListeningDurationMetric) + .size()); + } else { + histogram_tester_.ExpectUniqueSample(/*name=*/kOnDeviceSpeechMetric, + /*sample=*/false, + /*expected_bucket_count=*/1); + ASSERT_EQ(1, + histogram_tester_.GetAllSamples(kNetworkListeningDurationMetric) + .size()); + // Ensure there are no metrics for the other type of speech recognition. + ASSERT_EQ(0, + histogram_tester_.GetAllSamples(kOnDeviceListeningDurationMetric) + .size()); + } +} + class TextMatchesWaiter { public: TextMatchesWaiter(const std::string& expected, @@ -646,6 +739,52 @@ WaitForRecognitionStopped(); } +// Ensures that the correct metrics are recorded when Dictation is toggled. +IN_PROC_BROWSER_TEST_P(DictationExtensionTest, Metrics) { + base::HistogramTester histogram_tester_; + bool on_device = GetParam() == speech::SpeechRecognitionType::kOnDevice; + const char* metric_name = on_device ? kOnDeviceListeningDurationMetric + : kNetworkListeningDurationMetric; + HistogramWaiterOneShot waiter(metric_name); + ToggleDictationWithKeystroke(); + WaitForRecognitionStarted(); + ToggleDictationWithKeystroke(); + WaitForRecognitionStopped(); + waiter.Wait(); + content::FetchHistogramsFromChildProcesses(); + metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting(); + + // Ensure that we recorded the correct locale. + histogram_tester_.ExpectUniqueSample(/*name=*/kLocaleMetric, + /*sample=*/base::PersistentHash("en-US"), + /*expected_bucket_count=*/1); + // Ensure that we recorded the type of speech recognition and listening + // duration. + if (on_device) { + histogram_tester_.ExpectUniqueSample(/*name=*/kOnDeviceSpeechMetric, + /*sample=*/true, + /*expected_bucket_count=*/1); + ASSERT_EQ(1, + histogram_tester_.GetAllSamples(kOnDeviceListeningDurationMetric) + .size()); + // Ensure there are no metrics for the other type of speech recognition. + ASSERT_EQ(0, + histogram_tester_.GetAllSamples(kNetworkListeningDurationMetric) + .size()); + } else { + histogram_tester_.ExpectUniqueSample(/*name=*/kOnDeviceSpeechMetric, + /*sample=*/false, + /*expected_bucket_count=*/1); + ASSERT_EQ(1, + histogram_tester_.GetAllSamples(kNetworkListeningDurationMetric) + .size()); + // Ensure there are no metrics for the other type of speech recognition. + ASSERT_EQ(0, + histogram_tester_.GetAllSamples(kOnDeviceListeningDurationMetric) + .size()); + } +} + class CaretBoundsChangedWaiter : public ui::InputMethodObserver { public: explicit CaretBoundsChangedWaiter(ui::InputMethod* input_method)
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_view.cc b/chrome/browser/ash/app_restore/arc_ghost_window_view.cc index 4318825e..3123e90 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_view.cc +++ b/chrome/browser/ash/app_restore/arc_ghost_window_view.cc
@@ -9,6 +9,8 @@ #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/ash/app_restore/arc_window_handler.h" #include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/common/chrome_features.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/mojom/types.mojom-forward.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" @@ -92,25 +94,36 @@ user_manager::UserManager::Get()->GetPrimaryUser()->GetAccountId()); DCHECK(profile); - auto icon_type = apps::mojom::IconType::kStandard; - DCHECK( apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(profile)); - apps::AppServiceProxyFactory::GetForProfile(profile)->LoadIcon( - apps::mojom::AppType::kArc, app_id, icon_type, - ash::SharedAppListConfig::instance().default_grid_icon_dimension(), - /*allow_placeholder_icon=*/false, - icon_loaded_cb_for_testing_.is_null() - ? base::BindOnce(&ArcGhostWindowView::OnIconLoaded, - weak_ptr_factory_.GetWeakPtr(), icon_type) - : std::move(icon_loaded_cb_for_testing_)); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + apps::AppServiceProxyFactory::GetForProfile(profile)->LoadIcon( + apps::AppType::kArc, app_id, apps::IconType::kStandard, + ash::SharedAppListConfig::instance().default_grid_icon_dimension(), + /*allow_placeholder_icon=*/false, + icon_loaded_cb_for_testing_.is_null() + ? base::BindOnce(&ArcGhostWindowView::OnIconLoaded, + weak_ptr_factory_.GetWeakPtr()) + : std::move(icon_loaded_cb_for_testing_)); + } else { + apps::AppServiceProxyFactory::GetForProfile(profile)->LoadIcon( + apps::mojom::AppType::kArc, app_id, apps::mojom::IconType::kStandard, + ash::SharedAppListConfig::instance().default_grid_icon_dimension(), + /*allow_placeholder_icon=*/false, + icon_loaded_cb_for_testing_.is_null() + ? apps::MojomIconValueToIconValueCallback( + base::BindOnce(&ArcGhostWindowView::OnIconLoaded, + weak_ptr_factory_.GetWeakPtr())) + : apps::MojomIconValueToIconValueCallback( + std::move(icon_loaded_cb_for_testing_))); + } } -void ArcGhostWindowView::OnIconLoaded(apps::mojom::IconType icon_type, - apps::mojom::IconValuePtr icon_value) { - if (icon_type != icon_value->icon_type) +void ArcGhostWindowView::OnIconLoaded(apps::IconValuePtr icon_value) { + if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) return; + icon_view_->SetImage(icon_value->uncompressed); icon_view_->SetAccessibleName( l10n_util::GetStringUTF16(IDS_ARC_GHOST_WINDOW_APP_LAUNCHING_ICON));
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_view.h b/chrome/browser/ash/app_restore/arc_ghost_window_view.h index 010cfd1..cdf23b90 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_view.h +++ b/chrome/browser/ash/app_restore/arc_ghost_window_view.h
@@ -7,6 +7,7 @@ #include "base/gtest_prod_util.h" #include "base/memory/weak_ptr.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/mojom/app_service.mojom.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/view.h" @@ -36,11 +37,10 @@ FRIEND_TEST_ALL_PREFIXES(ArcGhostWindowViewTest, IconLoadTest); void InitLayout(uint32_t theme_color, int diameter); - void OnIconLoaded(apps::mojom::IconType icon_type, - apps::mojom::IconValuePtr icon_value); + void OnIconLoaded(apps::IconValuePtr icon_value); views::ImageView* icon_view_; - base::OnceCallback<void(apps::mojom::IconValuePtr icon_value)> + base::OnceCallback<void(apps::IconValuePtr icon_value)> icon_loaded_cb_for_testing_; base::WeakPtrFactory<ArcGhostWindowView> weak_ptr_factory_{this};
diff --git a/chrome/browser/ash/app_restore/arc_ghost_window_view_unittest.cc b/chrome/browser/ash/app_restore/arc_ghost_window_view_unittest.cc index e0ef5b3..3860b6f 100644 --- a/chrome/browser/ash/app_restore/arc_ghost_window_view_unittest.cc +++ b/chrome/browser/ash/app_restore/arc_ghost_window_view_unittest.cc
@@ -18,6 +18,7 @@ #include "chrome/test/base/testing_profile_manager.h" #include "chrome/test/views/chrome_test_views_delegate.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/mojom/app_service.mojom.h" #include "components/user_manager/scoped_user_manager.h" #include "content/public/test/browser_task_environment.h" @@ -110,7 +111,6 @@ std::unique_ptr<TestingProfileManager> profile_manager_; }; -#if BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(ArcGhostWindowViewTest, IconLoadTest) { const int kDiameter = 24; const uint32_t kThemeColor = SK_ColorWHITE; @@ -122,11 +122,10 @@ EXPECT_EQ(count, 0); view()->icon_loaded_cb_for_testing_ = base::BindLambdaForTesting( - [&count](apps::mojom::IconValuePtr icon_value) { count++; }); + [&count](apps::IconValuePtr icon_value) { count++; }); view()->LoadIcon(kAppId); EXPECT_EQ(count, 1); } -#endif } // namespace full_restore } // namespace ash
diff --git a/chrome/browser/ash/arc/arc_util.cc b/chrome/browser/ash/arc/arc_util.cc index 46dbb44..03d87f82 100644 --- a/chrome/browser/ash/arc/arc_util.cc +++ b/chrome/browser/ash/arc/arc_util.cc
@@ -662,8 +662,9 @@ web_contents->GetController().LoadURLWithParams(load_url_params); // Add a flag to remember this tab originated in the ARC context. - web_contents->SetUserData(&arc::ArcWebContentsData::kArcTransitionFlag, - std::make_unique<arc::ArcWebContentsData>()); + web_contents->SetUserData( + &arc::ArcWebContentsData::kArcTransitionFlag, + std::make_unique<arc::ArcWebContentsData>(web_contents.get())); return web_contents; }
diff --git a/chrome/browser/ash/arc/arc_web_contents_data.cc b/chrome/browser/ash/arc/arc_web_contents_data.cc index 219394ed..7bc33fd 100644 --- a/chrome/browser/ash/arc/arc_web_contents_data.cc +++ b/chrome/browser/ash/arc/arc_web_contents_data.cc
@@ -9,6 +9,9 @@ // static const char ArcWebContentsData::kArcTransitionFlag[] = "ArcTransition"; +ArcWebContentsData::ArcWebContentsData(content::WebContents* web_contents) + : content::WebContentsUserData<ArcWebContentsData>(*web_contents) {} + WEB_CONTENTS_USER_DATA_KEY_IMPL(ArcWebContentsData); } // namespace arc
diff --git a/chrome/browser/ash/arc/arc_web_contents_data.h b/chrome/browser/ash/arc/arc_web_contents_data.h index 50783339..20b43dde 100644 --- a/chrome/browser/ash/arc/arc_web_contents_data.h +++ b/chrome/browser/ash/arc/arc_web_contents_data.h
@@ -16,7 +16,7 @@ public: static const char kArcTransitionFlag[]; - ArcWebContentsData() = default; + explicit ArcWebContentsData(content::WebContents* web_contents); ArcWebContentsData(const ArcWebContentsData&) = delete; ArcWebContentsData& operator=(const ArcWebContentsData&) = delete;
diff --git a/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc b/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc index 7ee6b4c..05f4266f 100644 --- a/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc +++ b/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge.cc
@@ -16,6 +16,7 @@ #include <utility> #include "ash/components/arc/arc_browser_context_keyed_service_factory_base.h" +#include "ash/components/arc/bluetooth/bluetooth_type_converters.h" #include "ash/constants/ash_pref_names.h" #include "base/bind.h" #include "base/callback.h" @@ -33,7 +34,6 @@ #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/chromeos/bluetooth_pairing_dialog.h" -#include "components/arc/bluetooth/bluetooth_type_converters.h" #include "components/arc/intent_helper/arc_intent_helper_bridge.h" #include "components/arc/session/arc_bridge_service.h" #include "components/device_event_log/device_event_log.h"
diff --git a/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge_unittest.cc b/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge_unittest.cc index 8cd6060d..3e349c9 100644 --- a/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge_unittest.cc +++ b/chrome/browser/ash/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
@@ -9,6 +9,7 @@ #include <utility> #include <vector> +#include "ash/components/arc/bluetooth/bluetooth_type_converters.h" #include "ash/components/arc/test/connection_holder_util.h" #include "ash/components/arc/test/fake_bluetooth_instance.h" #include "base/bind.h" @@ -16,7 +17,6 @@ #include "base/system/sys_info.h" #include "base/test/scoped_chromeos_version_info.h" #include "base/test/task_environment.h" -#include "components/arc/bluetooth/bluetooth_type_converters.h" #include "components/arc/mojom/bluetooth.mojom.h" #include "components/arc/session/arc_bridge_service.h" #include "device/bluetooth/dbus/bluez_dbus_manager.h"
diff --git a/chrome/browser/ash/arc/intent_helper/arc_external_protocol_dialog_unittest.cc b/chrome/browser/ash/arc/intent_helper/arc_external_protocol_dialog_unittest.cc index 8ded832a..0d6d06b 100644 --- a/chrome/browser/ash/arc/intent_helper/arc_external_protocol_dialog_unittest.cc +++ b/chrome/browser/ash/arc/intent_helper/arc_external_protocol_dialog_unittest.cc
@@ -78,8 +78,9 @@ web_contents_ = browser()->tab_strip_model()->GetWebContentsAt(0); if (started_from_arc) { - web_contents_->SetUserData(&arc::ArcWebContentsData::kArcTransitionFlag, - std::make_unique<arc::ArcWebContentsData>()); + web_contents_->SetUserData( + &arc::ArcWebContentsData::kArcTransitionFlag, + std::make_unique<arc::ArcWebContentsData>(web_contents_)); } }
diff --git a/chrome/browser/ash/arc/nearby_share/ui/progress_bar_dialog_view.cc b/chrome/browser/ash/arc/nearby_share/ui/progress_bar_dialog_view.cc index 71e48fc5d..4a57be9 100644 --- a/chrome/browser/ash/arc/nearby_share/ui/progress_bar_dialog_view.cc +++ b/chrome/browser/ash/arc/nearby_share/ui/progress_bar_dialog_view.cc
@@ -6,11 +6,11 @@ #include <memory> +#include "ash/components/arc/compat_mode/style/arc_color_provider.h" #include "base/bind.h" #include "base/callback_helpers.h" #include "chrome/browser/ash/arc/nearby_share/ui/nearby_share_overlay_view.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" -#include "components/arc/compat_mode/style/arc_color_provider.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/color_palette.h"
diff --git a/chrome/browser/ash/arc/print_spooler/print_session_impl.cc b/chrome/browser/ash/arc/print_spooler/print_session_impl.cc index da0f1581..2ccd26c3 100644 --- a/chrome/browser/ash/arc/print_spooler/print_session_impl.cc +++ b/chrome/browser/ash/arc/print_spooler/print_session_impl.cc
@@ -232,6 +232,7 @@ mojo::PendingReceiver<mojom::PrintSessionHost> receiver) : ArcCustomTabModalDialogHost(std::make_unique<CustomTab>(arc_window), web_contents.get()), + content::WebContentsUserData<PrintSessionImpl>(*web_contents), instance_(std::move(instance)), session_receiver_(this, std::move(receiver)), web_contents_(std::move(web_contents)) {
diff --git a/chrome/browser/ash/arc/session/arc_service_launcher.cc b/chrome/browser/ash/arc/session/arc_service_launcher.cc index 0cae8ec..b090e06 100644 --- a/chrome/browser/ash/arc/session/arc_service_launcher.cc +++ b/chrome/browser/ash/arc/session/arc_service_launcher.cc
@@ -7,8 +7,16 @@ #include <string> #include <utility> +#include "ash/components/arc/appfuse/arc_appfuse_bridge.h" #include "ash/components/arc/arc_features.h" #include "ash/components/arc/arc_util.h" +#include "ash/components/arc/audio/arc_audio_bridge.h" +#include "ash/components/arc/camera/arc_camera_bridge.h" +#include "ash/components/arc/clipboard/arc_clipboard_bridge.h" +#include "ash/components/arc/compat_mode/arc_resize_lock_manager.h" +#include "ash/components/arc/crash_collector/arc_crash_collector_bridge.h" +#include "ash/components/arc/dark_theme/arc_dark_theme_bridge.h" +#include "ash/components/arc/disk_quota/arc_disk_quota_bridge.h" #include "ash/constants/ash_features.h" #include "base/bind.h" #include "base/check_op.h" @@ -62,14 +70,6 @@ #include "chrome/browser/ui/app_list/arc/arc_usb_host_permission_manager.h" #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" #include "chrome/common/channel_info.h" -#include "components/arc/appfuse/arc_appfuse_bridge.h" -#include "components/arc/audio/arc_audio_bridge.h" -#include "components/arc/camera/arc_camera_bridge.h" -#include "components/arc/clipboard/arc_clipboard_bridge.h" -#include "components/arc/compat_mode/arc_resize_lock_manager.h" -#include "components/arc/crash_collector/arc_crash_collector_bridge.h" -#include "components/arc/dark_theme/arc_dark_theme_bridge.h" -#include "components/arc/disk_quota/arc_disk_quota_bridge.h" #include "components/arc/ime/arc_ime_service.h" #include "components/arc/input_overlay/arc_input_overlay_manager.h" #include "components/arc/intent_helper/arc_intent_helper_bridge.h"
diff --git a/chrome/browser/ash/child_accounts/time_limits/web_time_navigation_observer.cc b/chrome/browser/ash/child_accounts/time_limits/web_time_navigation_observer.cc index bd5fadb..98d2133 100644 --- a/chrome/browser/ash/child_accounts/time_limits/web_time_navigation_observer.cc +++ b/chrome/browser/ash/child_accounts/time_limits/web_time_navigation_observer.cc
@@ -83,7 +83,8 @@ WebTimeNavigationObserver::WebTimeNavigationObserver( content::WebContents* web_contents) - : content::WebContentsObserver(web_contents) {} + : content::WebContentsUserData<WebTimeNavigationObserver>(*web_contents), + content::WebContentsObserver(web_contents) {} WEB_CONTENTS_USER_DATA_KEY_IMPL(WebTimeNavigationObserver);
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc index c2a42a40..ef67cfd 100644 --- a/chrome/browser/ash/crosapi/browser_util.cc +++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -42,6 +42,7 @@ #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" #include "chrome/browser/web_applications/web_app_utils.h" #include "chrome/common/channel_info.h" #include "chrome/common/chrome_features.h" @@ -877,6 +878,12 @@ params->is_unfiltered_bluetooth_device_enabled = chromeos::switches::IsUnfilteredBluetoothDevicesEnabled(); + + // Pass the accepted internal urls to lacros. Only accepted urls are allowed + // to be passed via OpenURL from Lacros to Ash. + params->accepted_internal_ash_urls = + std::move(ChromeWebUIControllerFactory::GetInstance()) + ->GetListOfAcceptableURLs(); return params; }
diff --git a/chrome/browser/ash/crosapi/url_handler_ash.cc b/chrome/browser/ash/crosapi/url_handler_ash.cc index 7bb3f8b..615da82e8 100644 --- a/chrome/browser/ash/crosapi/url_handler_ash.cc +++ b/chrome/browser/ash/crosapi/url_handler_ash.cc
@@ -8,10 +8,13 @@ #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" +#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" #include "chrome/browser/web_applications/web_app_utils.h" #include "chrome/common/webui_url_constants.h" +#include "chromeos/crosapi/cpp/gurl_os_handler_utils.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "url/url_constants.h" namespace { @@ -52,47 +55,50 @@ } void UrlHandlerAsh::OpenUrl(const GURL& url) { + GURL target_url = crosapi::gurl_os_handler_utils::SanitizeAshURL(url); // Settings will be handled. - if (url.DeprecatedGetOriginAsURL() == - GURL(chrome::kChromeUIOSSettingsURL).DeprecatedGetOriginAsURL()) { + if (target_url == GURL(chrome::kChromeUIOSSettingsURL)) { chrome::SettingsWindowManager* settings_window_manager = chrome::SettingsWindowManager::GetInstance(); settings_window_manager->ShowChromePageForProfile( - ProfileManager::GetPrimaryUserProfile(), url, + ProfileManager::GetPrimaryUserProfile(), target_url, display::kInvalidDisplayId); return; } - // The following two handlers are mapping to system OS URls which have their - // own favicon and with it their own place in the shelf. + web_app::SystemAppType app_id; - // Handle the os://flags and/or chrome://flags url as an app in Ash using a - // special icon and shelf seat. - if (url.DeprecatedGetOriginAsURL() == - GURL(chrome::kChromeUIFlagsURL).DeprecatedGetOriginAsURL()) { - ShowOsAppForProfile(ProfileManager::GetPrimaryUserProfile(), url, - web_app::SystemAppType::OS_FLAGS); + // As there are different apps which need to be driven by some URLs, the + // following code does pick the proper app for a given URL. + // TODO: As Chrome_web_ui_controller_factory gets refactored, this function + // should get refactored as well to improve long term stability. + if (target_url == GURL(chrome::kChromeUIFlagsURL) || + target_url == GURL(chrome::kOsUIFlagsURL)) { + app_id = web_app::SystemAppType::OS_FLAGS; + target_url = GURL(chrome::kChromeUIFlagsURL); + } else if (target_url == GURL(chrome::kChromeUIUntrustedCroshURL) || + target_url == GURL(chrome::kOsUICroshURL) || + target_url == GURL(chrome::kChromeUIOsCroshAppURL)) { + app_id = web_app::SystemAppType::CROSH; + target_url = GURL(chrome::kChromeUIUntrustedCroshURL); + } else if (ChromeWebUIControllerFactory::GetInstance()->CanHandleUrl( + target_url)) { + app_id = web_app::SystemAppType::OS_URL_HANDLER; + // Convert a os://<url> into a chrome://<url> or chrome-untrusted://<url>. + if (target_url == GURL(chrome::kOsUITerminalURL) || + target_url == GURL(chrome::kOsUIFileManagerURL)) { + target_url = GURL("chrome-untrusted://" + target_url.host()); + } else if (crosapi::gurl_os_handler_utils::IsAshOsUrl(target_url)) { + target_url = + GURL("chrome://" + + crosapi::gurl_os_handler_utils::AshOsUrlHost(target_url)); + } + } else { + LOG(ERROR) << "Invalid URL passed to UrlHandlerAsh::OpenUrl:" << url; return; } - - // Handle the os://crosh and/or chrome-untrusted://crosh url as an app. - if (url.DeprecatedGetOriginAsURL() == - GURL(chrome::kChromeUIOsCroshAppURL).DeprecatedGetOriginAsURL()) { - ShowOsAppForProfile(ProfileManager::GetPrimaryUserProfile(), - GURL(chrome::kChromeUIUntrustedCroshURL), - web_app::SystemAppType::CROSH); - return; - } - - // Handle a list of os://<url> and/or chrome://<url> url's, combined in one - // icon and shelf seat. - // TODO(crbug/1256481): Only accept URL's from the Ash supplied allow list. - if (url.DeprecatedGetOriginAsURL() == - GURL(chrome::kChromeUIVersionURL).DeprecatedGetOriginAsURL()) { - ShowOsAppForProfile(ProfileManager::GetPrimaryUserProfile(), url, - web_app::SystemAppType::OS_URL_HANDLER); - return; - } + ShowOsAppForProfile(ProfileManager::GetPrimaryUserProfile(), target_url, + app_id); } } // namespace crosapi
diff --git a/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc b/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc index 1b303daa..49974556 100644 --- a/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc +++ b/chrome/browser/ash/dbus/encrypted_reporting_service_provider_unittest.cc
@@ -54,9 +54,9 @@ return true; } -// Helper function composes JSON represented as base::Value from Sequencing +// Helper function composes JSON represented as base::Value from Sequence // information in request. -base::Value ValueFromSucceededSequencingInfo( +base::Value ValueFromSucceededSequenceInfo( const absl::optional<base::Value> request, bool force_confirm_flag) { EXPECT_TRUE(request.has_value()); @@ -69,11 +69,7 @@ EXPECT_NE(encrypted_record_list, nullptr); EXPECT_FALSE(encrypted_record_list->GetList().empty()); - // Retrieve and process sequencing information - const base::Value* unsigned_seq_info = - encrypted_record_list->GetList().rbegin()->FindDictKey( - "sequencingInformation"); - EXPECT_NE(unsigned_seq_info, nullptr); + // Retrieve and process sequence information const base::Value* seq_info = encrypted_record_list->GetList().rbegin()->FindDictKey( "sequenceInformation"); @@ -231,8 +227,7 @@ Invoke([](base::Value request, policy::CloudPolicyClient::ResponseCallback response_cb) { std::move(response_cb) - .Run(ValueFromSucceededSequencingInfo(std::move(request), - false)); + .Run(ValueFromSucceededSequenceInfo(std::move(request), false)); }))); reporting::UploadEncryptedRecordRequest request;
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 8778788..8b1aa79e 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
@@ -263,43 +263,6 @@ apps::mojom::OptionalBool::kTrue); } - void AddChromeBookmarkApp() { - const char kGraphrId[] = "ppcpljkgngnngojbghcdiojhbneibgdg"; - extensions::ExtensionBuilder graphr; - graphr.SetManifest( - extensions::DictionaryBuilder() - .Set("name", "Graphr") - .Set("version", "1.0.0") - .Set("manifest_version", 2) - .Set("app", - extensions::DictionaryBuilder() - .Set("launch", extensions::DictionaryBuilder() - .Set("web_url", "https://graphr.tld") - .Build()) - .Build()) - .Set("file_handlers", - extensions::DictionaryBuilder() - .Set("https://graphr.tld/open-files/?name=raw", - extensions::DictionaryBuilder() - .Set("title", "Raw") - .Set("types", extensions::ListBuilder() - .Append("text/csv") - .Build()) - .Set("extensions", extensions::ListBuilder() - .Append("csv") - .Build()) - .Build()) - .Build()) - .Build()); - graphr.SetID(kGraphrId); - graphr.AddFlags(extensions::Extension::InitFromValueFlags::FROM_BOOKMARK); - auto filters = - apps_util::CreateChromeAppIntentFilters(graphr.Build().get()); - AddFakeAppWithIntentFilters(kGraphrId, std::move(filters), - apps::mojom::AppType::kExtension, - apps::mojom::OptionalBool::kTrue); - } - base::test::ScopedFeatureList feature_list_; content::BrowserTaskEnvironment task_environment_; std::unique_ptr<TestingProfile> profile_; @@ -584,14 +547,5 @@ EXPECT_EQ(Verb::VERB_OPEN_WITH, tasks[0].task_verb); } -TEST_F(AppServiceFileTasksTestEnabled, FindAppServiceChromeBookmarkApp) { - AddChromeBookmarkApp(); - std::vector<FullTaskDescriptor> tasks = - FindAppServiceTasks({{"foo.csv", "text/csv"}}); - - // No bookmark apps expected. - ASSERT_EQ(0U, tasks.size()); -} - } // namespace file_tasks } // namespace file_manager.
diff --git a/chrome/browser/ash/file_manager/path_util.cc b/chrome/browser/ash/file_manager/path_util.cc index e2449eb..0c596fe07 100644 --- a/chrome/browser/ash/file_manager/path_util.cc +++ b/chrome/browser/ash/file_manager/path_util.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/ash/drive/drive_integration_service.h" #include "chrome/browser/ash/drive/file_system_util.h" #include "chrome/browser/ash/file_manager/app_id.h" +#include "chrome/browser/ash/file_manager/fileapi_util.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/ash/smb_client/smb_service.h" #include "chrome/browser/ash/smb_client/smb_service_factory.h" @@ -217,10 +218,8 @@ FILE_PATH_LITERAL("/media/archive"); const url::Origin& GetFilesAppOrigin() { - static const base::NoDestructor<url::Origin> origin([] { - return url::Origin::Create(extensions::Extension::GetBaseURLFromExtensionId( - file_manager::kFileManagerAppId)); - }()); + static const base::NoDestructor<url::Origin> origin( + [] { return url::Origin::Create(GetFileManagerURL()); }()); return *origin; } @@ -568,10 +567,7 @@ } *file_system_url = mount_points->CreateExternalFileSystemURL( - blink::StorageKey( - url::Origin::Create(extensions::Extension::GetBaseURLFromExtensionId( - file_manager::kFileManagerAppId))), - mount_name, path); + blink::StorageKey(GetFilesAppOrigin()), mount_name, path); return file_system_url->is_valid(); }
diff --git a/chrome/browser/ash/login/ui/web_contents_forced_title.cc b/chrome/browser/ash/login/ui/web_contents_forced_title.cc index 423347cf..ee28f59 100644 --- a/chrome/browser/ash/login/ui/web_contents_forced_title.cc +++ b/chrome/browser/ash/login/ui/web_contents_forced_title.cc
@@ -26,7 +26,9 @@ WebContentsForcedTitle::WebContentsForcedTitle( content::WebContents* web_contents, const std::u16string& title) - : content::WebContentsObserver(web_contents), title_(title) {} + : content::WebContentsObserver(web_contents), + content::WebContentsUserData<WebContentsForcedTitle>(*web_contents), + title_(title) {} WebContentsForcedTitle::~WebContentsForcedTitle() {}
diff --git a/chrome/browser/ash/policy/dlp/dlp_content_manager.h b/chrome/browser/ash/policy/dlp/dlp_content_manager.h index ebf65e6..1952723a 100644 --- a/chrome/browser/ash/policy/dlp/dlp_content_manager.h +++ b/chrome/browser/ash/policy/dlp/dlp_content_manager.h
@@ -105,12 +105,14 @@ const content::DesktopMediaID& media_id); // Checks whether screen sharing of content from the |media_id| source with - // the calling application |application_title| is restricted or not advised. - // Depending on the result, calls |callback| and passes an indicator whether - // to proceed or not. - void CheckScreenShareRestriction(const content::DesktopMediaID& media_id, - const std::u16string& application_title, - OnDlpRestrictionCheckedCallback callback); + // application |application_name| is restricted or not advised. Depending on + // the result, calls |callback| and passes an indicator whether to proceed or + // not. + // Virtual to allow tests to override. + virtual void CheckScreenShareRestriction( + const content::DesktopMediaID& media_id, + const std::u16string& application_title, + OnDlpRestrictionCheckedCallback callback); // Called when video capturing for |area| is started. void OnVideoCaptureStarted(const ScreenshotArea& area);
diff --git a/chrome/browser/ash/policy/dlp/mock_dlp_content_manager.cc b/chrome/browser/ash/policy/dlp/mock_dlp_content_manager.cc index c47e12c..fddc95672 100644 --- a/chrome/browser/ash/policy/dlp/mock_dlp_content_manager.cc +++ b/chrome/browser/ash/policy/dlp/mock_dlp_content_manager.cc
@@ -15,6 +15,14 @@ void MockDlpContentManager::Init() { SetReportingManagerForTesting(new DlpReportingManager()); + + ON_CALL(*this, CheckScreenShareRestriction) + .WillByDefault([](const content::DesktopMediaID& media_id, + const std::u16string& application_title, + OnDlpRestrictionCheckedCallback callback) { + // Allow by default. + std::move(callback).Run(true); + }); } } // namespace policy
diff --git a/chrome/browser/ash/policy/dlp/mock_dlp_content_manager.h b/chrome/browser/ash/policy/dlp/mock_dlp_content_manager.h index 04315c0..f8ba398 100644 --- a/chrome/browser/ash/policy/dlp/mock_dlp_content_manager.h +++ b/chrome/browser/ash/policy/dlp/mock_dlp_content_manager.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_ASH_POLICY_DLP_MOCK_DLP_CONTENT_MANAGER_H_ #define CHROME_BROWSER_ASH_POLICY_DLP_MOCK_DLP_CONTENT_MANAGER_H_ +#include "base/callback_forward.h" #include "chrome/browser/ash/policy/dlp/dlp_content_manager.h" #include "testing/gmock/include/gmock/gmock.h" #include "url/gurl.h" @@ -16,15 +17,29 @@ MockDlpContentManager(); ~MockDlpContentManager() override; - MOCK_METHOD2(OnConfidentialityChanged, - void(content::WebContents*, const DlpContentRestrictionSet&)); - MOCK_METHOD1(OnWebContentsDestroyed, void(content::WebContents*)); - MOCK_CONST_METHOD1(GetRestrictionSetForURL, - DlpContentRestrictionSet(const GURL&)); - MOCK_METHOD1(OnVisibilityChanged, void(content::WebContents*)); - MOCK_METHOD1(IsScreenshotApiRestricted, bool(const ScreenshotArea& area)); - MOCK_METHOD1(IsScreenCaptureRestricted, - bool(const content::DesktopMediaID& media_id)); + MOCK_METHOD(void, + OnConfidentialityChanged, + (content::WebContents*, const DlpContentRestrictionSet&)); + MOCK_METHOD(void, OnWebContentsDestroyed, (content::WebContents*)); + MOCK_METHOD(DlpContentRestrictionSet, + GetRestrictionSetForURL, + (const GURL&), + (const)); + MOCK_METHOD(void, OnVisibilityChanged, (content::WebContents*)); + MOCK_METHOD(bool, + IsScreenshotApiRestricted, + (const ScreenshotArea& area), + (override)); + MOCK_METHOD(bool, + IsScreenCaptureRestricted, + (const content::DesktopMediaID& media_id), + (override)); + MOCK_METHOD(void, + CheckScreenShareRestriction, + (const content::DesktopMediaID& media_id, + const std::u16string& application_title, + OnDlpRestrictionCheckedCallback callback), + (override)); protected: void Init() override;
diff --git a/chrome/browser/ash/policy/invalidation/affiliated_invalidation_service_provider_impl.cc b/chrome/browser/ash/policy/invalidation/affiliated_invalidation_service_provider_impl.cc index 34cbb6ee..621cd70 100644 --- a/chrome/browser/ash/policy/invalidation/affiliated_invalidation_service_provider_impl.cc +++ b/chrome/browser/ash/policy/invalidation/affiliated_invalidation_service_provider_impl.cc
@@ -65,7 +65,7 @@ private: AffiliatedInvalidationServiceProviderImpl* parent_; - invalidation::InvalidationService* invalidation_service_; + invalidation::InvalidationService* const invalidation_service_; bool is_service_connected_; bool is_observer_ready_; }; @@ -78,6 +78,7 @@ invalidation_service_(invalidation_service), is_service_connected_(false), is_observer_ready_(false) { + DCHECK(invalidation_service_); invalidation_service_->RegisterInvalidationHandler(this); is_service_connected_ = invalidation_service->GetInvalidatorState() == invalidation::INVALIDATIONS_ENABLED; @@ -130,7 +131,9 @@ AffiliatedInvalidationServiceProviderImpl:: AffiliatedInvalidationServiceProviderImpl() - : invalidation_service_(nullptr), consumer_count_(0), is_shut_down_(false) { + : current_invalidation_service_(nullptr), + consumer_count_(0), + is_shut_down_(false) { // The AffiliatedInvalidationServiceProviderImpl should be created before any // user Profiles. DCHECK(g_browser_process->profile_manager()->GetLoadedProfiles().empty()); @@ -188,8 +191,8 @@ consumers_.AddObserver(consumer); ++consumer_count_; - if (invalidation_service_) - consumer->OnInvalidationServiceSet(invalidation_service_); + if (current_invalidation_service_) + consumer->OnInvalidationServiceSet(current_invalidation_service_); else if (consumer_count_ == 1) FindConnectedInvalidationService(); } @@ -202,8 +205,8 @@ consumers_.RemoveObserver(consumer); --consumer_count_; - if (invalidation_service_ && consumer_count_ == 0) { - invalidation_service_ = nullptr; + if (current_invalidation_service_ && consumer_count_ == 0) { + current_invalidation_service_ = nullptr; DestroyDeviceInvalidationService(); } } @@ -215,11 +218,11 @@ profile_invalidation_service_observers_.clear(); device_invalidation_service_observer_.reset(); - if (invalidation_service_) { - invalidation_service_ = nullptr; + if (current_invalidation_service_) { + current_invalidation_service_ = nullptr; // Explicitly notify consumers that the invalidation service they were using // is no longer available. - SetInvalidationService(nullptr); + SetCurrentInvalidationService(nullptr); } DestroyDeviceInvalidationService(); @@ -249,11 +252,11 @@ } // Make the invalidation service that just connected available to consumers. - invalidation_service_ = nullptr; - SetInvalidationService(invalidation_service); + current_invalidation_service_ = nullptr; + SetCurrentInvalidationService(invalidation_service); - if (invalidation_service_ && device_invalidation_service_ && - invalidation_service_ != device_invalidation_service_.get()) { + if (current_invalidation_service_ && device_invalidation_service_ && + current_invalidation_service_ != device_invalidation_service_.get()) { // If a different invalidation service is being made available to consumers // now, destroy the device-global one. DestroyDeviceInvalidationService(); @@ -265,7 +268,7 @@ invalidation::InvalidationService* invalidation_service) { DCHECK(!is_shut_down_); - if (invalidation_service != invalidation_service_) { + if (invalidation_service != current_invalidation_service_) { // If the invalidation service which disconnected was not being made // available to consumers, return. return; @@ -274,7 +277,7 @@ // The invalidation service which disconnected was being made available to // consumers. Stop making it available. DCHECK(consumer_count_); - invalidation_service_ = nullptr; + current_invalidation_service_ = nullptr; // Try to make another invalidation service available to consumers. FindConnectedInvalidationService(); @@ -282,13 +285,13 @@ // If no other connected invalidation service was found, explicitly notify // consumers that the invalidation service they were using is no longer // available. - if (!invalidation_service_) - SetInvalidationService(nullptr); + if (!current_invalidation_service_) + SetCurrentInvalidationService(nullptr); } void AffiliatedInvalidationServiceProviderImpl:: FindConnectedInvalidationService() { - DCHECK(!invalidation_service_); + DCHECK(!current_invalidation_service_); DCHECK(consumer_count_); DCHECK(!is_shut_down_); @@ -297,7 +300,7 @@ // If a connected invalidation service belonging to an affiliated // logged-in user is found, make it available to consumers. DestroyDeviceInvalidationService(); - SetInvalidationService(observer->GetInvalidationService()); + SetCurrentInvalidationService(observer->GetInvalidationService()); return; } } @@ -319,12 +322,12 @@ } } -void AffiliatedInvalidationServiceProviderImpl::SetInvalidationService( +void AffiliatedInvalidationServiceProviderImpl::SetCurrentInvalidationService( invalidation::InvalidationService* invalidation_service) { - DCHECK(!invalidation_service_); - invalidation_service_ = invalidation_service; + DCHECK(!current_invalidation_service_); + current_invalidation_service_ = invalidation_service; for (auto& observer : consumers_) - observer.OnInvalidationServiceSet(invalidation_service_); + observer.OnInvalidationServiceSet(current_invalidation_service_); } void AffiliatedInvalidationServiceProviderImpl::
diff --git a/chrome/browser/ash/policy/invalidation/affiliated_invalidation_service_provider_impl.h b/chrome/browser/ash/policy/invalidation/affiliated_invalidation_service_provider_impl.h index edd3126f..43224f5 100644 --- a/chrome/browser/ash/policy/invalidation/affiliated_invalidation_service_provider_impl.h +++ b/chrome/browser/ash/policy/invalidation/affiliated_invalidation_service_provider_impl.h
@@ -69,9 +69,9 @@ // one registered consumer. void FindConnectedInvalidationService(); - // Choose |invalidation_service| as the shared invalidation service and notify - // consumers. - void SetInvalidationService( + // Choose |invalidation_service| as the |current_invalidation_service_| and + // notify consumers. + void SetCurrentInvalidationService( invalidation::InvalidationService* invalidation_service); // Destroy the device-global invalidation service, if any. @@ -110,7 +110,7 @@ // The invalidation service currently used by consumers. nullptr if there are // no registered consumers or no connected invalidation service is available // for use. - invalidation::InvalidationService* invalidation_service_; + invalidation::InvalidationService* current_invalidation_service_; base::ObserverList<Consumer, true>::Unchecked consumers_; int consumer_count_;
diff --git a/chrome/browser/ash/printing/history/print_job_reporting_service.h b/chrome/browser/ash/printing/history/print_job_reporting_service.h index 9b3683c2..6043f7a 100644 --- a/chrome/browser/ash/printing/history/print_job_reporting_service.h +++ b/chrome/browser/ash/printing/history/print_job_reporting_service.h
@@ -7,8 +7,7 @@ #include <memory> -#include "base/callback.h" -#include "base/strings/string_piece_forward.h" +#include "base/task/sequenced_task_runner.h" #include "chrome/browser/ash/printing/history/print_job_history_service.h" #include "components/keyed_service/core/keyed_service.h" #include "components/reporting/client/report_queue.h" @@ -19,14 +18,16 @@ class PrintJobReportingService : public KeyedService, public PrintJobHistoryService::Observer { public: - static std::unique_ptr<PrintJobReportingService> Create( - base::StringPiece dm_token_value); + static std::unique_ptr<PrintJobReportingService> Create(); + + // Test helper for creating a PrintJobReportingService using the specified + // report queue + static std::unique_ptr<PrintJobReportingService> CreateForTest( + std::unique_ptr<::reporting::ReportQueue, base::OnTaskRunnerDeleter> + report_queue); ~PrintJobReportingService() override = default; - virtual base::OnceCallback<void(std::unique_ptr<::reporting::ReportQueue>)> - GetReportQueueSetter() = 0; - // PrintJobHistoryService::Observer: void OnPrintJobFinished(const chromeos::printing::proto::PrintJobInfo& print_job_info) override = 0;
diff --git a/chrome/browser/ash/printing/history/print_job_reporting_service_factory.cc b/chrome/browser/ash/printing/history/print_job_reporting_service_factory.cc index 12ef3aa4..d9a3f3f 100644 --- a/chrome/browser/ash/printing/history/print_job_reporting_service_factory.cc +++ b/chrome/browser/ash/printing/history/print_job_reporting_service_factory.cc
@@ -4,14 +4,8 @@ #include "chrome/browser/ash/printing/history/print_job_reporting_service_factory.h" -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/task/bind_post_task.h" +#include "base/memory/singleton.h" #include "chrome/browser/ash/printing/history/print_job_reporting_service.h" -#include "chrome/browser/policy/dm_token_utils.h" -#include "chrome/browser/profiles/profile.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" namespace ash { @@ -38,16 +32,7 @@ KeyedService* PrintJobReportingServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { - Profile* profile = Profile::FromBrowserContext(context); - - policy::DMToken dm_token = policy::GetDMToken(profile); - // TODO(1229994, marcgrimme) remove the logs as part of refactoring. - if (!dm_token.is_valid()) { - LOG(ERROR) << "DMToken must be valid"; - return nullptr; - } - - auto reporting_service = PrintJobReportingService::Create(dm_token.value()); + auto reporting_service = PrintJobReportingService::Create(); return reporting_service.release(); }
diff --git a/chrome/browser/ash/printing/history/print_job_reporting_service_impl.cc b/chrome/browser/ash/printing/history/print_job_reporting_service_impl.cc index 03b6f06f..4a8160e 100644 --- a/chrome/browser/ash/printing/history/print_job_reporting_service_impl.cc +++ b/chrome/browser/ash/printing/history/print_job_reporting_service_impl.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ash/printing/history/print_job_reporting_service.h" +#include <memory> #include <utility> #include "ash/components/settings/cros_settings_names.h" @@ -13,11 +14,13 @@ #include "base/containers/queue.h" #include "base/memory/weak_ptr.h" #include "base/strings/string_piece.h" +#include "base/task/sequenced_task_runner.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/chromeos/printing/history/print_job_info.pb.h" #include "components/policy/proto/device_management_backend.pb.h" +#include "components/reporting/client/report_queue.h" #include "components/reporting/client/report_queue_factory.h" #include "components/reporting/proto/synced/record_constants.pb.h" #include "components/reporting/util/status.h" @@ -33,18 +36,17 @@ class PrintJobReportingServiceImpl : public PrintJobReportingService { public: - explicit PrintJobReportingServiceImpl(base::StringPiece dm_token_value) - : cros_settings_(CrosSettings::Get()) { + explicit PrintJobReportingServiceImpl( + std::unique_ptr<::reporting::ReportQueue, base::OnTaskRunnerDeleter> + report_queue) + : report_queue_(std::move(report_queue)), + cros_settings_(CrosSettings::Get()) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); UpdateShouldReport(); should_report_subscription_ = cros_settings_->AddSettingsObserver( kReportDevicePrintJobs, base::BindRepeating(&PrintJobReportingServiceImpl::UpdateShouldReport, weak_factory_.GetWeakPtr())); - - ::reporting::ReportQueueFactory::Create( - dm_token_value, ::reporting::Destination::PRINT_JOBS, - GetReportQueueSetter()); } ~PrintJobReportingServiceImpl() override = default; @@ -60,24 +62,15 @@ VLOG(1) << "Not a managed printer for print job: " << print_job_info.id(); return; } + if (!report_queue_) { + VLOG(1) << "No report queue set"; + return; + } em::PrintJobEvent event = Convert(print_job_info); - if (report_queue_) { - VLOG(1) << "Enqueuing event for print job: " - << event.job_configuration().id(); - Enqueue(event); - } else { - VLOG(1) << "Reporting queue not yet set at print job: " - << event.job_configuration().id(); - pending_print_jobs_.push(std::move(event)); - } - } - - base::OnceCallback<void(std::unique_ptr<::reporting::ReportQueue>)> - GetReportQueueSetter() override { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - return base::BindOnce(&PrintJobReportingServiceImpl::SetReportQueue, - weak_factory_.GetWeakPtr()); + VLOG(1) << "Enqueuing event for print job: " + << event.job_configuration().id(); + Enqueue(event); } private: @@ -91,15 +84,6 @@ cros_settings_->GetBoolean(kReportDevicePrintJobs, &should_report_); } - void SetReportQueue(std::unique_ptr<::reporting::ReportQueue> report_queue) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - report_queue_ = std::move(report_queue); - while (!pending_print_jobs_.empty()) { - Enqueue(pending_print_jobs_.front()); - pending_print_jobs_.pop(); - } - } - void Enqueue(const em::PrintJobEvent& event) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); report_queue_->Enqueue(&event, ::reporting::Priority::SLOW_BATCH, @@ -190,24 +174,35 @@ // Whether print jobs should be reported. bool should_report_ = false; - // Print jobs that are queued before the report queue is available. - base::queue<em::PrintJobEvent> pending_print_jobs_; - // Subscription for the CrOS setting that determines whether print jobs should // be reported. base::CallbackListSubscription should_report_subscription_; - // Report queue for print jobs - std::unique_ptr<::reporting::ReportQueue> report_queue_; + // Speculative report queue for print jobs + const std::unique_ptr<::reporting::ReportQueue, base::OnTaskRunnerDeleter> + report_queue_; CrosSettings* const cros_settings_; base::WeakPtrFactory<PrintJobReportingServiceImpl> weak_factory_{this}; }; -std::unique_ptr<PrintJobReportingService> PrintJobReportingService::Create( - base::StringPiece dm_token_value) { - return std::make_unique<PrintJobReportingServiceImpl>(dm_token_value); +// static +std::unique_ptr<PrintJobReportingService> PrintJobReportingService::Create() { + auto report_queue = + ::reporting::ReportQueueFactory::CreateSpeculativeReportQueue( + ::reporting::EventType::kUser, ::reporting::Destination::PRINT_JOBS); + return std::make_unique<PrintJobReportingServiceImpl>( + std::move(report_queue)); +} + +// static +std::unique_ptr<PrintJobReportingService> +PrintJobReportingService::CreateForTest( + std::unique_ptr<::reporting::ReportQueue, base::OnTaskRunnerDeleter> + report_queue) { + return std::make_unique<PrintJobReportingServiceImpl>( + std::move(report_queue)); } } // namespace ash
diff --git a/chrome/browser/ash/printing/history/print_job_reporting_service_unittest.cc b/chrome/browser/ash/printing/history/print_job_reporting_service_unittest.cc index 48c0495..256491b 100644 --- a/chrome/browser/ash/printing/history/print_job_reporting_service_unittest.cc +++ b/chrome/browser/ash/printing/history/print_job_reporting_service_unittest.cc
@@ -6,6 +6,8 @@ #include "ash/components/settings/cros_settings_names.h" #include "base/bind.h" +#include "base/task/sequenced_task_runner.h" +#include "base/task/thread_pool.h" #include "base/time/time.h" #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/browser/ash/settings/scoped_testing_cros_settings.h" @@ -13,6 +15,7 @@ #include "components/account_id/account_id.h" #include "components/policy/proto/device_management_backend.pb.h" #include "components/reporting/client/mock_report_queue.h" +#include "components/reporting/client/report_queue.h" #include "components/user_manager/scoped_user_manager.h" #include "content/public/test/browser_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" @@ -281,8 +284,6 @@ user_manager->AddKioskAppUser(account_id); user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>( std::move(user_manager)); - print_job_reporting_service_ = - PrintJobReportingService::Create(/* dm_token_value= */ ""); } void ChangeReportingSetting(bool should_report) { @@ -290,8 +291,15 @@ should_report); } - void SetReportQueue() { - auto report_queue = std::make_unique<::reporting::MockReportQueue>(); + // Creates a new report queue that can be used by the PrintJobReportingService + // with the enqueue operation stubbed + std::unique_ptr<::reporting::ReportQueue, base::OnTaskRunnerDeleter> + CreateReportQueue() { + auto report_queue = std::unique_ptr<::reporting::MockReportQueue, + base::OnTaskRunnerDeleter>( + new ::reporting::MockReportQueue(), + base::OnTaskRunnerDeleter( + base::ThreadPool::CreateSequencedTaskRunner({}))); EXPECT_CALL(*report_queue, AddRecord) .WillRepeatedly( [this](base::StringPiece record, ::reporting::Priority priority, @@ -301,8 +309,7 @@ events_.push_back(event); priorities_.push_back(priority); }); - print_job_reporting_service_->GetReportQueueSetter().Run( - std::move(report_queue)); + return std::move(report_queue); } protected: @@ -315,9 +322,9 @@ }; TEST_F(PrintJobReportingServiceTest, ShouldReportPolicyDisabled) { + print_job_reporting_service_ = + PrintJobReportingService::CreateForTest(CreateReportQueue()); ChangeReportingSetting(false); - SetReportQueue(); - print_job_reporting_service_->OnPrintJobFinished(JobInfo1()); print_job_reporting_service_->OnPrintJobFinished(JobInfo2()); @@ -326,9 +333,9 @@ } TEST_F(PrintJobReportingServiceTest, Enqueue) { + print_job_reporting_service_ = + PrintJobReportingService::CreateForTest(CreateReportQueue()); ChangeReportingSetting(true); - SetReportQueue(); - print_job_reporting_service_->OnPrintJobFinished(JobInfo1()); print_job_reporting_service_->OnPrintJobFinished(JobInfo2()); @@ -339,36 +346,11 @@ EXPECT_EQ(priorities_[1], ::reporting::Priority::SLOW_BATCH); } -TEST_F(PrintJobReportingServiceTest, PendingPrintJobsEnqueue) { - ChangeReportingSetting(true); - - print_job_reporting_service_->OnPrintJobFinished(JobInfo1()); - print_job_reporting_service_->OnPrintJobFinished(JobInfo2()); - - EXPECT_TRUE(events_.empty()); - EXPECT_TRUE(priorities_.empty()); - - SetReportQueue(); - - ASSERT_EQ(events_.size(), 2u); - EXPECT_THAT(events_[0], IsPrintJobEvent(JobEvent1())); - EXPECT_EQ(priorities_[0], ::reporting::Priority::SLOW_BATCH); - EXPECT_THAT(events_[1], IsPrintJobEvent(JobEvent2())); - EXPECT_EQ(priorities_[1], ::reporting::Priority::SLOW_BATCH); - - print_job_reporting_service_->OnPrintJobFinished(JobInfo3()); - - ASSERT_EQ(events_.size(), 3u); - EXPECT_THAT(events_[2], IsPrintJobEvent(JobEvent3())); - EXPECT_EQ(priorities_[2], ::reporting::Priority::SLOW_BATCH); -} - TEST_F(PrintJobReportingServiceTest, ShouldReportPolicyInitiallyEnabled) { ChangeReportingSetting(true); // Create the reporting service after setting the policy to true. print_job_reporting_service_ = - PrintJobReportingService::Create(/* dm_token_value= */ ""); - SetReportQueue(); + PrintJobReportingService::CreateForTest(CreateReportQueue()); print_job_reporting_service_->OnPrintJobFinished(JobInfo1()); @@ -381,9 +363,7 @@ ChangeReportingSetting(false); // Create the reporting service after setting the policy to false. print_job_reporting_service_ = - PrintJobReportingService::Create(/* dm_token_value= */ ""); - SetReportQueue(); - + PrintJobReportingService::CreateForTest(CreateReportQueue()); print_job_reporting_service_->OnPrintJobFinished(JobInfo1()); EXPECT_TRUE(events_.empty());
diff --git a/chrome/browser/ash/web_applications/os_url_handler_system_web_app_info.cc b/chrome/browser/ash/web_applications/os_url_handler_system_web_app_info.cc index e12f201..bbbb1168 100644 --- a/chrome/browser/ash/web_applications/os_url_handler_system_web_app_info.cc +++ b/chrome/browser/ash/web_applications/os_url_handler_system_web_app_info.cc
@@ -9,8 +9,10 @@ #include "base/feature_list.h" #include "chrome/browser/ash/crosapi/browser_util.h" #include "chrome/browser/ash/web_applications/system_web_app_install_utils.h" +#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/generated_resources.h" +#include "chromeos/crosapi/cpp/gurl_os_handler_utils.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" #include "ui/chromeos/styles/cros_styles.h" @@ -38,9 +40,8 @@ std::unique_ptr<WebApplicationInfo> OsUrlHandlerSystemWebAppDelegate::GetWebAppInfo() const { auto info = std::make_unique<WebApplicationInfo>(); - info->start_url = GURL(chrome::kChromeUIFlagsURL); - info->scope = GURL(chrome::kChromeUIFlagsURL); - + info->start_url = GURL(chrome::kChromeUIOsUrlAppURL); + info->scope = GURL(chrome::kChromeUIOsUrlAppURL); info->title = l10n_util::GetStringUTF16(IDS_OS_URL_HANDLER_APP_NAME); web_app::CreateIconInfoForSystemWebApp( @@ -78,3 +79,30 @@ bool OsUrlHandlerSystemWebAppDelegate::ShouldShowInSearch() const { return false; } + +bool OsUrlHandlerSystemWebAppDelegate::ShouldReuseExistingWindow() const { + return false; +} + +bool OsUrlHandlerSystemWebAppDelegate::IsUrlInSystemAppScope( + const GURL& url) const { + if (!IsAppEnabled()) + return false; + + GURL target_url = crosapi::gurl_os_handler_utils::SanitizeAshURL(url); + if (!target_url.has_scheme() || !target_url.has_host()) + return false; + + if (ChromeWebUIControllerFactory::GetInstance()->CanHandleUrl(target_url)) + return true; + + if (target_url.scheme() != "chrome") + return false; + + // By the time the web app system gets the link, the os:// scheme will have + // been replaced by the chrome:// scheme. As the user cannot enter in ash + // chrome:// scheme urls anymore, we should be safely able to assume that they + // might have been os:// schemed URLs when being called from Lacros. + target_url = GURL("os://" + target_url.host()); + return ChromeWebUIControllerFactory::GetInstance()->CanHandleUrl(target_url); +}
diff --git a/chrome/browser/ash/web_applications/os_url_handler_system_web_app_info.h b/chrome/browser/ash/web_applications/os_url_handler_system_web_app_info.h index 8f04e19..fd76aa9 100644 --- a/chrome/browser/ash/web_applications/os_url_handler_system_web_app_info.h +++ b/chrome/browser/ash/web_applications/os_url_handler_system_web_app_info.h
@@ -31,6 +31,8 @@ bool IsAppEnabled() const override; bool ShouldShowInLauncher() const override; bool ShouldShowInSearch() const override; + bool ShouldReuseExistingWindow() const override; + bool IsUrlInSystemAppScope(const GURL& url) const override; }; #endif // CHROME_BROWSER_ASH_WEB_APPLICATIONS_OS_URL_HANDLER_SYSTEM_WEB_APP_INFO_H_
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper.cc b/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper.cc index f9efcd5..37a9b70 100644 --- a/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper.cc +++ b/chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper.cc
@@ -104,7 +104,8 @@ } DlpContentTabHelper::DlpContentTabHelper(content::WebContents* web_contents) - : content::WebContentsObserver(web_contents) {} + : content::WebContentsUserData<DlpContentTabHelper>(*web_contents), + content::WebContentsObserver(web_contents) {} DlpContentRestrictionSet DlpContentTabHelper::GetRestrictionSet() const { DlpContentRestrictionSet set;
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reaction_layout.xml b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reaction_layout.xml index 6341151..f29ec718 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reaction_layout.xml +++ b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reaction_layout.xml
@@ -3,13 +3,13 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<!-- TODO(crbug.com/1252182): Add android:contentDescription="@string/foo" attributes --> <org.chromium.chrome.browser.content_creation.reactions.scene.ReactionLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content"> + <!-- ContentDescription is added at runtime. --> <ImageView tools:ignore="ContentDescription" android:id="@+id/reaction_view" @@ -27,6 +27,7 @@ android:layout_alignParentEnd="true" android:scaleType="fitCenter" android:background="@android:color/transparent" + android:contentDescription="@string/delete" android:src="@drawable/lr_delete" /> <org.chromium.ui.widget.ChromeImageButton @@ -37,6 +38,7 @@ android:layout_alignParentBottom="true" android:background="@android:color/transparent" android:scaleType="fitCenter" + android:contentDescription="@string/lightweight_reactions_duplicate_button" android:src="@drawable/lr_copy" /> <org.chromium.ui.widget.ChromeImageButton @@ -47,6 +49,7 @@ android:background="@android:color/transparent" android:scaleType="fitCenter" android:layout_alignParentEnd="true" - android:layout_alignParentBottom="true" /> + android:layout_alignParentBottom="true" + android:contentDescription="@string/lightweight_reactions_resize_and_rotate_button"/> </org.chromium.chrome.browser.content_creation.reactions.scene.ReactionLayout> \ No newline at end of file
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reactions_dialog.xml b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reactions_dialog.xml index f399ab0..957879d 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reactions_dialog.xml +++ b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/reactions_dialog.xml
@@ -3,7 +3,6 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<!-- TODO(crbug.com/1252182): Add android:contentDescription="@string/foo" attributes --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/lightweight_reactions_dialog" @@ -19,7 +18,7 @@ <View android:id="@+id/lightweight_reactions_divider" - android:background="@color/divider_line_bg_color" + android:background="@macro/divider_line_bg_color" android:layout_above="@id/lightweight_reactions_toolbar" android:layout_height="@dimen/toolbar_separator_height" android:layout_width="match_parent"/> @@ -28,6 +27,5 @@ android:id="@+id/lightweight_reactions_toolbar" android:layout_width="match_parent" android:layout_height="@dimen/toolbar_total_height" - android:layout_alignParentBottom="true" - /> + android:layout_alignParentBottom="true" /> </RelativeLayout> \ No newline at end of file
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/scene.xml b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/scene.xml index 45d315e..6afec94d 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/scene.xml +++ b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/scene.xml
@@ -3,7 +3,6 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<!-- TODO(crbug.com/1252182): Add android:contentDescription="@string/foo" attributes --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml index 3bbade4..33b70e1b7 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml +++ b/chrome/browser/content_creation/reactions/internal/android/java/res/layout/toolbar.xml
@@ -3,10 +3,8 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<!-- TODO(crbug.com/1252182): Add android:contentDescription="@string/foo" attributes --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" @@ -17,7 +15,8 @@ android:layout_width="match_parent" android:layout_height="@dimen/toolbar_row_height" android:layout_above="@id/lightweight_reactions_toolbar_controls" - android:scrollbars="none"> + android:scrollbars="none" + android:contentDescription="@string/lightweight_reactions_toolbar_announcement" > <LinearLayout android:id="@+id/lightweight_reactions_toolbar_reaction_picker" android:gravity="center" @@ -58,10 +57,9 @@ android:text="@string/sharing_lightweight_reactions" android:textAppearance="@style/TextAppearance.TextMedium.Secondary"/> - <!-- TODO(crbug.com/1252182): Fix the android:contentDescription attribute --> <org.chromium.ui.widget.ChromeImageButton android:id="@+id/done_button" - android:contentDescription="@string/screenshot_save_title" + android:contentDescription="@string/confirm" android:src="@drawable/ic_checkmark_24dp" android:layout_height="match_parent" android:layout_width="@dimen/toolbar_button_size"
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java index b4448da..c0c8b267 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsCoordinatorImpl.java
@@ -16,6 +16,7 @@ import org.chromium.base.Callback; import org.chromium.chrome.browser.content_creation.reactions.LightweightReactionsMediator.GifGeneratorHost; +import org.chromium.chrome.browser.content_creation.reactions.internal.R; import org.chromium.chrome.browser.content_creation.reactions.scene.SceneCoordinator; import org.chromium.chrome.browser.content_creation.reactions.toolbar.ToolbarControlsDelegate; import org.chromium.chrome.browser.content_creation.reactions.toolbar.ToolbarCoordinator; @@ -147,6 +148,14 @@ } /** + * Returns the localized temporary filename with the current timestamp appended. + */ + private String getFileName() { + return mActivity.getString(R.string.lightweight_reactions_filename_prefix, + String.valueOf(System.currentTimeMillis())); + } + + /** * Creates the share sheet title based on a localized title and the current date formatted for * the user's preferred locale. */ @@ -154,8 +163,8 @@ Date now = new Date(System.currentTimeMillis()); String currentDateString = DateFormat.getDateInstance(DateFormat.SHORT, getPreferredLocale()).format(now); - // TODO(crbug.com/1213923): get final string from UX, and localize it here. - return "Generated GIF " + currentDateString; + return mActivity.getString( + R.string.lightweight_reactions_title_for_share, currentDateString); } /** @@ -228,7 +237,7 @@ progressDialog.show(mFragmentManager, /*tag=*/null); mMediator.generateGif( - gifHost, mSceneCoordinator, progressDialog, (imageUri) -> { + gifHost, getFileName(), mSceneCoordinator, progressDialog, (imageUri) -> { LightweightReactionsMetrics.recordGifGenerated(getTimeSinceOpened(), imageUri != null, System.currentTimeMillis() - mGenerationStartTime); final String sheetTitle = getShareSheetTitle();
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMediator.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMediator.java index b6a89efa..038a80a 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMediator.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/LightweightReactionsMediator.java
@@ -132,6 +132,7 @@ * with the URI to the temporary GIF file for sharing. * * @param host The {@link GifGeneratorHost} to use for generating the GIF frames. + * @param fileName The shared GIF's file name. * @param sceneCoordinator The {@link SceneCoordinator} to restart the animations when * cancelling and to get the dimensions. * @param progressDialog The {@link LightweightReactionsProgressDialog} to update the progress @@ -139,8 +140,9 @@ * @param doneCallback The callback to invoke when the final GIF is ready. The callback is * passed the Uri to the temporary GIF file that was generated. */ - public void generateGif(GifGeneratorHost host, SceneCoordinator sceneCoordinator, - LightweightReactionsProgressDialog progressDialog, Callback<Uri> doneCallback) { + public void generateGif(GifGeneratorHost host, String fileName, + SceneCoordinator sceneCoordinator, LightweightReactionsProgressDialog progressDialog, + Callback<Uri> doneCallback) { mGifGenerationCancelled = false; progressDialog.setCancelProgressListener(view -> mGifGenerationCancelled = true); FileOutputStreamWriter gifWriter = (fos, frameCallback) -> { @@ -202,16 +204,7 @@ }; ShareImageFileUtils.generateTemporaryUriFromStream( - getFileName(), gifWriter, GIF_FILE_EXT, doneCallback); - } - - /** - * Returns the localized temporary filename. Random numbers will be appended to it when the file - * creation happens. - */ - private String getFileName() { - // TODO(crbug.com/1213923): get final string from UX, and localize it here. - return "reaction"; + fileName, gifWriter, GIF_FILE_EXT, doneCallback); } /**
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/ReactionGifDrawable.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/ReactionGifDrawable.java index b112295..8c52e231 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/ReactionGifDrawable.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/ReactionGifDrawable.java
@@ -19,11 +19,17 @@ private final ReactionMetadata mMetadata; private boolean mSteppingEnabled; private org.chromium.base.Callback<Void> mStepCallback; + private boolean mIsCurrentlyDecoding; + private boolean mStepOnNextDecode; public ReactionGifDrawable( ReactionMetadata metadata, BaseGifImage gifImage, Bitmap.Config bitmapConfig) { super(gifImage, bitmapConfig); mMetadata = metadata; + mStepOnNextDecode = false; + + // The base class constructor automatically starts decoding the first frame. + mIsCurrentlyDecoding = true; } /** @@ -44,7 +50,7 @@ mSteppingEnabled = steppingEnabled; if (mSteppingEnabled) { stop(); - reset(); + requestReset(); } } @@ -59,9 +65,19 @@ return false; } mStepCallback = listener; + + boolean wasSteppingEnabled = mSteppingEnabled; setSteppingEnabled(true); - run(); - return true; + + if (mIsCurrentlyDecoding && !wasSteppingEnabled) { + // Wait for the current decoding operation to finish. The step will be performed by + // postProcessFrame() when the current decoding operation is done. + mStepOnNextDecode = true; + return false; + } else { + run(); + return true; + } } public ReactionMetadata getMetadata() { @@ -72,13 +88,23 @@ * Restarts the animation from the first frame. */ public void resetAnimation() { - reset(); + requestReset(); } @Override protected void postProcessFrame(Bitmap bitmap) { - // A frame has just been decoded. If stepping is enabled, notify the listener that a step - // has completed. + mIsCurrentlyDecoding = false; + + if (mStepOnNextDecode) { + // Ignore the frame that was just decoded because stepping mode is being enabled, which + // means the reaction is being reset to the first frame anyway. Simply perform the step + // manually from here. + mStepOnNextDecode = false; + run(); + return; + } + + // If stepping is enabled, notify the listener that a step has completed. if (mSteppingEnabled && mStepCallback != null) { org.chromium.base.Callback<Void> cb = mStepCallback; mStepCallback = null; @@ -105,4 +131,10 @@ super.invalidateSelf(); } + + @Override + public void run() { + mIsCurrentlyDecoding = true; + super.run(); + } }
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/ReactionLayout.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/ReactionLayout.java index fa2c097..3b41d52 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/ReactionLayout.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/ReactionLayout.java
@@ -41,17 +41,20 @@ * Initialize the ReactionLayout outside of the constructor since the Layout is inflated. * @param drawable {@link ReactionGifDrawable} of the reaction. * @param sceneEditorDelegate {@link SceneEditorDelegate} to call scene editing methods. + * @param localizedName The name of the reaction for accessibility. */ - void init(ReactionGifDrawable drawable, SceneEditorDelegate sceneEditorDelegate) { - setDrawable(drawable); + void init(ReactionGifDrawable drawable, SceneEditorDelegate sceneEditorDelegate, + String localizedName) { + setDrawable(drawable, localizedName); mSceneEditorDelegate = sceneEditorDelegate; mIsActive = true; setUpReactionView(); } - void setDrawable(ReactionGifDrawable drawable) { + void setDrawable(ReactionGifDrawable drawable, String localizedName) { mDrawable = drawable; mReaction.setImageDrawable(mDrawable); + mReaction.setContentDescription(localizedName); } @Override
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/SceneCoordinator.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/SceneCoordinator.java index ebcc407..3ac163c 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/SceneCoordinator.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/scene/SceneCoordinator.java
@@ -84,7 +84,7 @@ ReactionLayout reactionLayout = (ReactionLayout) LayoutInflaterUtils.inflate( mActivity, R.layout.reaction_layout, null); - reactionLayout.init(drawable, this); + reactionLayout.init(drawable, this, reaction.localizedName); int reactionSizePx = ViewUtils.dpToPx(mActivity, DEFAULT_REACTION_SIZE_DP); RelativeLayout.LayoutParams lp = @@ -236,7 +236,7 @@ mActivity, R.layout.reaction_layout, null); ReactionGifDrawable drawable = new ReactionGifDrawable(reaction, baseGifImage, Bitmap.Config.ARGB_8888); - newReactionLayout.init(drawable, this); + newReactionLayout.init(drawable, this, reaction.localizedName); RelativeLayout.LayoutParams oldLayoutParams = (RelativeLayout.LayoutParams) reactionLayout.getLayoutParams(); @@ -307,7 +307,8 @@ ++mNbTypeChange; mMediator.getGifForUrl(reaction.assetUrl, (baseGifImage) -> { mActiveReaction.setDrawable( - new ReactionGifDrawable(reaction, baseGifImage, Bitmap.Config.ARGB_8888)); + new ReactionGifDrawable(reaction, baseGifImage, Bitmap.Config.ARGB_8888), + reaction.localizedName); resetReactions(mActiveReaction); }); }
diff --git a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java index 37fe939..2210aea3 100644 --- a/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java +++ b/chrome/browser/content_creation/reactions/internal/android/java/src/org/chromium/chrome/browser/content_creation/reactions/toolbar/ToolbarCoordinator.java
@@ -26,8 +26,6 @@ private final ToolbarReactionsDelegate mReactionsDelegate; private final RelativeLayout mRootLayout; - private List<ReactionMetadata> mAvailableReactions; - public ToolbarCoordinator(View parentView, ToolbarControlsDelegate controlsDelegate, ToolbarReactionsDelegate reactionsDelegate) { mControlsDelegate = controlsDelegate; @@ -46,11 +44,11 @@ */ public void initReactions(List<ReactionMetadata> availableReactions, Bitmap[] thumbnails) { assert availableReactions.size() == thumbnails.length; - mAvailableReactions = availableReactions; LinearLayout lr = mRootLayout.findViewById(R.id.lightweight_reactions_toolbar_reaction_picker); for (int i = 0; i < thumbnails.length; ++i) { + ReactionMetadata reactionMetadata = availableReactions.get(i); ImageView iv = new ImageView(mRootLayout.getContext()); iv.setImageBitmap(thumbnails[i]); int thumbnailSizePx = ViewUtils.dpToPx(mRootLayout.getContext(), THUMBNAIL_SIZE_DP); @@ -61,8 +59,9 @@ iv.setScaleType(ImageView.ScaleType.CENTER_CROP); iv.setClickable(true); - iv.setTag(availableReactions.get(i)); + iv.setTag(reactionMetadata); iv.setOnClickListener(this::onReactionTapped); + iv.setContentDescription(reactionMetadata.localizedName); lr.addView(iv); }
diff --git a/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc b/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc index 624b3ef4..ef4f67c 100644 --- a/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/chrome/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -112,6 +112,73 @@ // Should not crash by this point. } +IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, + InputDispatchEventsToCorrectTarget) { + Attach(); + + std::string setup_logging = R"( + window.logs = []; + ['dragenter', 'keydown', 'mousedown', 'mouseenter', 'mouseleave', + 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'click', 'touchcancel', + 'touchend', 'touchmove', 'touchstart', + ].forEach((event) => + window.addEventListener(event, (e) => logs.push(e.type)));)"; + content::WebContents* target_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + ui_test_utils::NavigateToURLWithDisposition( + browser(), GURL("about:blank"), WindowOpenDisposition::NEW_FOREGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); + content::WebContents* other_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_TRUE( + content::EvalJs(target_web_contents, setup_logging).error.empty()); + EXPECT_TRUE(content::EvalJs(other_web_contents, setup_logging).error.empty()); + + base::DictionaryValue params; + params.SetStringKey("button", "left"); + params.SetIntKey("clickCount", 1); + params.SetIntKey("x", 100); + params.SetIntKey("y", 250); + params.SetIntKey("clickCount", 1); + + params.SetStringKey("type", "mousePressed"); + SendCommandSync("Input.dispatchMouseEvent", params.Clone()); + + params.SetStringKey("type", "mouseMoved"); + params.SetIntKey("y", 270); + SendCommandSync("Input.dispatchMouseEvent", params.Clone()); + + params.SetStringKey("type", "mouseReleased"); + SendCommandSync("Input.dispatchMouseEvent", std::move(params)); + + params = base::DictionaryValue(); + params.SetIntKey("x", 100); + params.SetIntKey("y", 250); + params.SetStringPath("type", "dragEnter"); + params.SetIntPath("data.dragOperationsMask", 1); + params.SetPath("data.items", base::ListValue()); + SendCommandSync("Input.dispatchDragEvent", std::move(params)); + + params = base::DictionaryValue(); + params.SetIntKey("x", 100); + params.SetIntKey("y", 250); + SendCommandSync("Input.synthesizeTapGesture", std::move(params)); + + params = base::DictionaryValue(); + params.SetStringKey("type", "keyDown"); + params.SetStringKey("key", "a"); + SendCommandSync("Input.dispatchKeyEvent", std::move(params)); + + content::EvalJsResult main_target_events = + content::EvalJs(target_web_contents, "logs.join(' ')"); + content::EvalJsResult other_target_events = + content::EvalJs(other_web_contents, "logs.join(' ')"); + EXPECT_EQ("mouseover mousedown mousemove mouseup click dragenter keydown", + main_target_events.ExtractString()); + EXPECT_EQ("", other_target_events.ExtractString()); +} + class DevToolsProtocolTest_AppId : public DevToolsProtocolTest { public: DevToolsProtocolTest_AppId() {
diff --git a/chrome/browser/enterprise/connectors/connectors_service_browsertest.cc b/chrome/browser/enterprise/connectors/connectors_service_browsertest.cc index 06a80ad5..425c29a9 100644 --- a/chrome/browser/enterprise/connectors/connectors_service_browsertest.cc +++ b/chrome/browser/enterprise/connectors/connectors_service_browsertest.cc
@@ -32,6 +32,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h" #include "chrome/browser/ash/policy/core/user_cloud_policy_manager_ash.h" +#include "chrome/browser/ash/profiles/profile_helper.h" #include "components/account_id/account_id.h" #include "components/user_manager/scoped_user_manager.h" #include "components/user_manager/user.h" @@ -79,6 +80,10 @@ constexpr char kDomain1[] = "domain1.com"; constexpr char kTestUrl[] = "https://foo.com"; +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kTestGaiaId[] = "123"; +#endif + } // namespace // Profile DM token tests @@ -137,6 +142,11 @@ void TearDownOnMainThread() override { #if BUILDFLAG(IS_CHROMEOS_ASH) + // Remove cached user from ProfileHelper so it does not interfere with other + // workflows + ash::ProfileHelper::Get()->RemoveUserFromListForTesting( + AccountId::FromUserEmailGaiaId( + browser()->profile()->GetProfileUserName(), kTestGaiaId)); user_manager_enabler_.reset(); #endif } @@ -189,7 +199,7 @@ user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>( base::WrapUnique(fake_user_manager)); AccountId account_id = AccountId::FromUserEmailGaiaId( - browser()->profile()->GetProfileUserName(), "123"); + browser()->profile()->GetProfileUserName(), kTestGaiaId); fake_user_manager->AddUserWithAffiliationAndTypeAndProfile( account_id, management_status() == ManagementStatus::AFFILIATED, user_manager::USER_TYPE_REGULAR,
diff --git a/chrome/browser/enterprise/connectors/device_trust/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/BUILD.gn index 8d21e29..ac4e57b 100644 --- a/chrome/browser/enterprise/connectors/device_trust/BUILD.gn +++ b/chrome/browser/enterprise/connectors/device_trust/BUILD.gn
@@ -12,12 +12,25 @@ source_set("test_support") { testonly = true - sources = [ "mock_device_trust_service.cc" ] + sources = [ + "fake_device_trust_connector_service.cc", + "mock_device_trust_service.cc", + ] - public = [ "mock_device_trust_service.h" ] + public = [ + "fake_device_trust_connector_service.h", + "mock_device_trust_service.h", + ] public_deps = [ + "//base", "//chrome/browser", "//testing/gmock", ] + + deps = [ + "//components/pref_registry", + "//components/prefs:test_support", + "//components/sync_preferences:test_support", + ] }
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.cc new file mode 100644 index 0000000..d88756c --- /dev/null +++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.cc
@@ -0,0 +1,98 @@ +// 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/enterprise/connectors/device_trust/device_trust_connector_service.h" + +#include "base/check.h" +#include "chrome/browser/enterprise/connectors/connectors_prefs.h" +#include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h" +#include "components/policy/core/browser/url_util.h" +#include "components/prefs/pref_service.h" +#include "components/url_matcher/url_matcher.h" +#include "url/gurl.h" + +namespace enterprise_connectors { + +namespace { + +bool IsFeatureEnabled() { + return base::FeatureList::IsEnabled(kDeviceTrustConnectorEnabled); +} + +const base::ListValue* GetPolicyUrlPatterns(PrefService* prefs) { + return prefs->GetList(kContextAwareAccessSignalsAllowlistPref); +} + +bool ConnectorPolicyHasValues(PrefService* profile_prefs) { + const auto* list = GetPolicyUrlPatterns(profile_prefs); + return list && !list->GetList().empty(); +} + +} // namespace + +// static +bool DeviceTrustConnectorService::IsConnectorEnabled( + PrefService* profile_prefs) { + if (!IsFeatureEnabled() || !profile_prefs) { + return false; + } + + return ConnectorPolicyHasValues(profile_prefs); +} + +DeviceTrustConnectorService::DeviceTrustConnectorService( + PrefService* profile_prefs) + : profile_prefs_(profile_prefs), + matcher_(std::make_unique<url_matcher::URLMatcher>()) { + DCHECK(profile_prefs_); + if (!IsFeatureEnabled()) { + return; + } + + pref_observer_.Init(profile_prefs_); + pref_observer_.Add( + kContextAwareAccessSignalsAllowlistPref, + base::BindRepeating(&DeviceTrustConnectorService::OnPolicyUpdated, + weak_factory_.GetWeakPtr())); + + // Call once to initialize the watcher with the current pref's values. + OnPolicyUpdated(); +} + +DeviceTrustConnectorService::~DeviceTrustConnectorService() = default; + +bool DeviceTrustConnectorService::IsConnectorEnabled() const { + return DeviceTrustConnectorService::IsConnectorEnabled(profile_prefs_); +} + +bool DeviceTrustConnectorService::Watches(const GURL& url) const { + return !matcher_->MatchURL(url).empty(); +} + +void DeviceTrustConnectorService::OnConnectorEnabled() { + // No-op by default. +} + +void DeviceTrustConnectorService::OnPolicyUpdated() { + DCHECK(IsFeatureEnabled()); + + const base::ListValue* url_patterns = GetPolicyUrlPatterns(profile_prefs_); + + url_matcher::URLMatcherConditionSet::ID condition_set_id(0); + if (!matcher_->IsEmpty()) { + // Clear old conditions in case they exist. + matcher_->RemoveConditionSets({condition_set_id}); + } + + if (url_patterns && !url_patterns->GetList().empty()) { + // Add the new endpoints to the conditions. + policy::url_util::AddFilters(matcher_.get(), /*allow=*/true, + &condition_set_id, url_patterns); + + // Call the hook which signals that the connector has been enabled. + OnConnectorEnabled(); + } +} + +} // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h new file mode 100644 index 0000000..8ee64c9 --- /dev/null +++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h
@@ -0,0 +1,66 @@ +// 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_ENTERPRISE_CONNECTORS_DEVICE_TRUST_DEVICE_TRUST_CONNECTOR_SERVICE_H_ +#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_DEVICE_TRUST_CONNECTOR_SERVICE_H_ + +#include <memory> + +#include "components/keyed_service/core/keyed_service.h" +#include "components/prefs/pref_change_registrar.h" + +class PrefService; +class GURL; + +namespace url_matcher { +class URLMatcher; +} // namespace url_matcher + +namespace enterprise_connectors { + +// Keyed-Service in charge of monitoring the status of the Device Trust +// connector (e.g. enabled or not). +class DeviceTrustConnectorService : public KeyedService { + public: + explicit DeviceTrustConnectorService(PrefService* profile_prefs); + + DeviceTrustConnectorService(const DeviceTrustConnectorService&) = delete; + DeviceTrustConnectorService& operator=(const DeviceTrustConnectorService&) = + delete; + + ~DeviceTrustConnectorService() override; + + // Returns whether the Device Trust connector is enabled or not, uses the + // given `profile_prefs` to check the policy value. + static bool IsConnectorEnabled(PrefService* profile_prefs); + + // Returns whether the Device Trust connector is enabled or not. + bool IsConnectorEnabled() const; + + // Returns whether the Device Trust connector watches navigations to the given + // `url` or not. + bool Watches(const GURL& url) const; + + protected: + // Hook that can is called to notify that the policy changed and the connector + // became, or is still, enabled. + virtual void OnConnectorEnabled(); + + private: + // Called when the policy value changes in Prefs. + void OnPolicyUpdated(); + + PrefChangeRegistrar pref_observer_; + + PrefService* profile_prefs_; + + // The URL matcher created from the ContextAwareAccessSignalsAllowlist policy. + std::unique_ptr<url_matcher::URLMatcher> matcher_; + + base::WeakPtrFactory<DeviceTrustConnectorService> weak_factory_{this}; +}; + +} // namespace enterprise_connectors + +#endif // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_DEVICE_TRUST_CONNECTOR_SERVICE_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_factory.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_factory.cc new file mode 100644 index 0000000..cda6d44 --- /dev/null +++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_factory.cc
@@ -0,0 +1,48 @@ +// 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/enterprise/connectors/device_trust/device_trust_connector_service_factory.h" + +#include "base/memory/singleton.h" +#include "chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h" +#include "chrome/browser/profiles/profile.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/keyed_service/core/keyed_service.h" + +namespace enterprise_connectors { + +// static +DeviceTrustConnectorServiceFactory* +DeviceTrustConnectorServiceFactory::GetInstance() { + return base::Singleton<DeviceTrustConnectorServiceFactory>::get(); +} + +// static +DeviceTrustConnectorService* DeviceTrustConnectorServiceFactory::GetForProfile( + Profile* profile) { + return static_cast<DeviceTrustConnectorService*>( + GetInstance()->GetServiceForBrowserContext(profile, true)); +} + +bool DeviceTrustConnectorServiceFactory::ServiceIsCreatedWithBrowserContext() + const { + // TODO(b/204914180): Change this when ready to initialize the DT Key Manager. + return false; +} + +DeviceTrustConnectorServiceFactory::DeviceTrustConnectorServiceFactory() + : BrowserContextKeyedServiceFactory( + "DeviceTrustConnectorService", + BrowserContextDependencyManager::GetInstance()) {} + +DeviceTrustConnectorServiceFactory::~DeviceTrustConnectorServiceFactory() = + default; + +KeyedService* DeviceTrustConnectorServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + auto* profile = Profile::FromBrowserContext(context); + return new DeviceTrustConnectorService(profile->GetPrefs()); +} + +} // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_factory.h b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_factory.h new file mode 100644 index 0000000..dd8649f9 --- /dev/null +++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_factory.h
@@ -0,0 +1,45 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_DEVICE_TRUST_CONNECTOR_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_DEVICE_TRUST_CONNECTOR_SERVICE_FACTORY_H_ + +#include "components/keyed_service/content/browser_context_keyed_service_factory.h" + +class Profile; + +namespace base { +template <typename T> +struct DefaultSingletonTraits; +} + +namespace enterprise_connectors { + +class DeviceTrustConnectorService; + +// Singleton factory for Profile-keyed DeviceTrustConnectorService instances. +class DeviceTrustConnectorServiceFactory + : public BrowserContextKeyedServiceFactory { + public: + static DeviceTrustConnectorServiceFactory* GetInstance(); + static DeviceTrustConnectorService* GetForProfile(Profile* profile); + + protected: + bool ServiceIsCreatedWithBrowserContext() const override; + + private: + friend struct base::DefaultSingletonTraits< + DeviceTrustConnectorServiceFactory>; + + DeviceTrustConnectorServiceFactory(); + ~DeviceTrustConnectorServiceFactory() override; + + // BrowserContextKeyedServiceFactory implementation: + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; +}; + +} // namespace enterprise_connectors + +#endif // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_DEVICE_TRUST_CONNECTOR_SERVICE_FACTORY_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_service.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_service.cc index 21a52bda..dffd3b60 100644 --- a/chrome/browser/enterprise/connectors/device_trust/device_trust_service.cc +++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_service.cc
@@ -9,6 +9,7 @@ #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.h" #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_utils.h" #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/signals_type.h" +#include "chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h" #include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h" #include "chrome/browser/enterprise/connectors/device_trust/signals/signals_service.h" #include "components/prefs/pref_service.h" @@ -17,56 +18,24 @@ using CollectSignalsCallback = SignalsService::CollectSignalsCallback; -namespace { - -const base::ListValue& GetTrustedUrlPatterns(PrefService* prefs) { - return *prefs->GetList(kContextAwareAccessSignalsAllowlistPref); -} - -} // namespace - -// static -bool DeviceTrustService::IsEnabled(PrefService* prefs) { - if (!base::FeatureList::IsEnabled(kDeviceTrustConnectorEnabled)) { - return false; - } - - const auto& list = GetTrustedUrlPatterns(prefs); - return !list.GetList().empty(); -} - DeviceTrustService::DeviceTrustService( - PrefService* profile_prefs, std::unique_ptr<AttestationService> attestation_service, - std::unique_ptr<SignalsService> signals_service) - : profile_prefs_(profile_prefs), - attestation_service_(std::move(attestation_service)), - signals_service_(std::move(signals_service)) { - pref_observer_.Init(profile_prefs_); - pref_observer_.Add(kContextAwareAccessSignalsAllowlistPref, - base::BindRepeating(&DeviceTrustService::OnPolicyUpdated, - weak_factory_.GetWeakPtr())); + std::unique_ptr<SignalsService> signals_service, + DeviceTrustConnectorService* connector) + : attestation_service_(std::move(attestation_service)), + signals_service_(std::move(signals_service)), + connector_(connector) { + DCHECK(attestation_service_); + DCHECK(signals_service_); + DCHECK(connector_); } -DeviceTrustService::DeviceTrustService(PrefService* profile_prefs) - : profile_prefs_(profile_prefs) {} +DeviceTrustService::DeviceTrustService() = default; -DeviceTrustService::~DeviceTrustService() { - DCHECK(callbacks_.empty()); -} - -void DeviceTrustService::Shutdown() { - pref_observer_.Remove(kContextAwareAccessSignalsAllowlistPref); -} +DeviceTrustService::~DeviceTrustService() = default; bool DeviceTrustService::IsEnabled() const { - return IsEnabled(profile_prefs_); -} - -void DeviceTrustService::OnPolicyUpdated() { - if (IsEnabled() && !callbacks_.empty()) { - callbacks_.Notify(GetTrustedUrlPatterns(profile_prefs_)); - } + return connector_ && connector_->IsConnectorEnabled(); } void DeviceTrustService::BuildChallengeResponse(const std::string& challenge, @@ -76,6 +45,10 @@ std::move(callback))); } +bool DeviceTrustService::Watches(const GURL& url) const { + return connector_ && connector_->Watches(url); +} + void DeviceTrustService::GetSignals(CollectSignalsCallback callback) { return signals_service_->CollectSignals(std::move(callback)); } @@ -88,15 +61,4 @@ challenge, std::move(signals), std::move(callback)); } -base::CallbackListSubscription -DeviceTrustService::RegisterTrustedUrlPatternsChangedCallback( - TrustedUrlPatternsChangedCallback callback) { - // Notify the callback right away so that caller can initialize itself. - if (IsEnabled()) { - callback.Run(GetTrustedUrlPatterns(profile_prefs_)); - } - - return callbacks_.Add(callback); -} - } // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_service.h b/chrome/browser/enterprise/connectors/device_trust/device_trust_service.h index 3c7bc17d..9f3961b 100644 --- a/chrome/browser/enterprise/connectors/device_trust/device_trust_service.h +++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_service.h
@@ -9,17 +9,15 @@ #include <string> #include "base/callback.h" -#include "base/callback_list.h" -#include "base/values.h" #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/signals_type.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/prefs/pref_change_registrar.h" -class PrefService; +class GURL; namespace enterprise_connectors { class AttestationService; +class DeviceTrustConnectorService; class SignalsService; // Main service used to drive device trust connector scenarios. It is currently @@ -29,17 +27,9 @@ public: using AttestationCallback = base::OnceCallback<void(const std::string&)>; - using TrustedUrlPatternsChangedCallbackList = - base::RepeatingCallbackList<void(const base::ListValue&)>; - using TrustedUrlPatternsChangedCallback = - TrustedUrlPatternsChangedCallbackList::CallbackType; - - // Check if DeviceTrustService is enabled via prefs with non-empty allowlist. - static bool IsEnabled(PrefService* prefs); - - DeviceTrustService(PrefService* profile_prefs, - std::unique_ptr<AttestationService> attestation_service, - std::unique_ptr<SignalsService> signals_service); + DeviceTrustService(std::unique_ptr<AttestationService> attestation_service, + std::unique_ptr<SignalsService> signals_service, + DeviceTrustConnectorService* connector); DeviceTrustService(const DeviceTrustService&) = delete; DeviceTrustService& operator=(const DeviceTrustService&) = delete; @@ -54,36 +44,26 @@ virtual void BuildChallengeResponse(const std::string& challenge, AttestationCallback callback); + // Returns whether the Device Trust connector watches navigations to the given + // `url` or not. + virtual bool Watches(const GURL& url) const; + // Collects device trust signals and returns them via `callback`. void GetSignals( base::OnceCallback<void(std::unique_ptr<SignalsType>)> callback); - // Register a `callback` that listens for changes in the trust URL patterns. - // The callback may be run synchronously for initialization purposes. - virtual base::CallbackListSubscription - RegisterTrustedUrlPatternsChangedCallback( - TrustedUrlPatternsChangedCallback callback); - - // KeyedService: - void Shutdown() override; - protected: // Default constructor that can be used by mocks to bypass initialization. - explicit DeviceTrustService(PrefService* profile_prefs); + DeviceTrustService(); private: - void OnPolicyUpdated(); - void OnSignalsCollected(const std::string& challenge, AttestationCallback callback, std::unique_ptr<SignalsType> signals); - PrefChangeRegistrar pref_observer_; - - PrefService* const profile_prefs_; std::unique_ptr<AttestationService> attestation_service_; std::unique_ptr<SignalsService> signals_service_; - TrustedUrlPatternsChangedCallbackList callbacks_; + DeviceTrustConnectorService* const connector_{nullptr}; base::WeakPtrFactory<DeviceTrustService> weak_factory_{this}; };
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc index 23997c3..8e1376c 100644 --- a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc +++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
@@ -8,6 +8,8 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.h" +#include "chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h" +#include "chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service_factory.h" #include "chrome/browser/enterprise/connectors/device_trust/device_trust_service.h" #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h" #include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h" @@ -44,6 +46,7 @@ : BrowserContextKeyedServiceFactory( "DeviceTrustService", BrowserContextDependencyManager::GetInstance()) { + DependsOn(DeviceTrustConnectorServiceFactory::GetInstance()); DependsOn(PolicyBlocklistFactory::GetInstance()); } @@ -64,9 +67,10 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) return new DeviceTrustService( - profile->GetPrefs(), std::move(attestation_service), + std::move(attestation_service), CreateSignalsService( - profile, PolicyBlocklistFactory::GetForBrowserContext(context))); + profile, PolicyBlocklistFactory::GetForBrowserContext(context)), + DeviceTrustConnectorServiceFactory::GetForProfile(profile)); } } // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_unittest.cc index 4b23f4fc..76292b5 100644 --- a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_unittest.cc +++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_unittest.cc
@@ -13,6 +13,7 @@ #include "base/values.h" #include "chrome/browser/enterprise/connectors/connectors_prefs.h" #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/mock_attestation_service.h" +#include "chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h" #include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h" #include "chrome/browser/enterprise/connectors/device_trust/signals/mock_signals_service.h" #include "components/enterprise/common/proto/device_trust_report_event.pb.h" @@ -62,11 +63,6 @@ std::make_unique<base::ListValue>(origins)); } - void UpdateServicePolicy() { - prefs_.SetUserPref(kContextAwareAccessSignalsAllowlistPref, - std::make_unique<base::ListValue>(more_origins)); - } - void DisableServicePolicy() { prefs_.SetUserPref(kContextAwareAccessSignalsAllowlistPref, std::make_unique<base::ListValue>()); @@ -77,6 +73,8 @@ } std::unique_ptr<DeviceTrustService> CreateService() { + connector_ = std::make_unique<DeviceTrustConnectorService>(&prefs_); + auto mock_attestation_service = std::make_unique<MockAttestationService>(); mock_attestation_service_ = mock_attestation_service.get(); @@ -84,8 +82,8 @@ mock_signals_service_ = mock_signals_service.get(); return std::make_unique<DeviceTrustService>( - &prefs_, std::move(mock_attestation_service), - std::move(mock_signals_service)); + std::move(mock_attestation_service), std::move(mock_signals_service), + connector_.get()); } bool is_attestation_flow_enabled() { @@ -98,6 +96,7 @@ base::test::SingleThreadTaskEnvironment task_environment_; base::test::ScopedFeatureList feature_list_; TestingPrefServiceSimple prefs_; + std::unique_ptr<DeviceTrustConnectorService> connector_; MockAttestationService* mock_attestation_service_; MockSignalsService* mock_signals_service_; }; @@ -109,49 +108,6 @@ EXPECT_EQ(is_attestation_flow_enabled(), device_trust_service->IsEnabled()); } -// Tests that callbacks get invoked when added and when the policy changes. -TEST_P(DeviceTrustServiceTest, PolicyValueCallbacks) { - const base::ListValue* captured_policy_urls; - int callback_invoked_counter = 0; - base::RepeatingCallback<void(const base::ListValue&)> callback = - base::BindLambdaForTesting( - [&captured_policy_urls, - &callback_invoked_counter](const base::ListValue& urls) { - ++callback_invoked_counter; - captured_policy_urls = &urls; - }); - - auto device_trust_service = CreateService(); - auto sub = - device_trust_service->RegisterTrustedUrlPatternsChangedCallback(callback); - - if (is_attestation_flow_enabled()) { - EXPECT_EQ(callback_invoked_counter, 1); - EXPECT_EQ(captured_policy_urls->GetList().size(), 2U); - } else { - // The callback was registered, but not invoked immediately. - EXPECT_EQ(callback_invoked_counter, 0); - } - - UpdateServicePolicy(); - - ASSERT_EQ(device_trust_service->IsEnabled(), is_flag_enabled()); - - if (is_flag_enabled()) { - if (is_attestation_flow_enabled()) { - // If the policy was already set at the beginning of the test, then the - // callback will have been called a total of two times. - EXPECT_EQ(callback_invoked_counter, 2); - } else { - EXPECT_EQ(callback_invoked_counter, 1); - } - EXPECT_EQ(captured_policy_urls->GetList().size(), 3U); - } else { - // If the flag is disabled, registered callbacks will still not get updated. - EXPECT_EQ(callback_invoked_counter, 0); - } -} - // Tests that the service kicks off the attestation flow properly. TEST_P(DeviceTrustServiceTest, BuildChallengeResponse) { auto device_trust_service = CreateService();
diff --git a/chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.cc b/chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.cc new file mode 100644 index 0000000..272afcb --- /dev/null +++ b/chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.cc
@@ -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. + +#include "chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.h" + +#include "chrome/browser/enterprise/connectors/connectors_prefs.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" + +namespace enterprise_connectors { + +FakeDeviceTrustConnectorService::FakeDeviceTrustConnectorService( + sync_preferences::TestingPrefServiceSyncable* profile_prefs) + : DeviceTrustConnectorService(profile_prefs), test_prefs_(profile_prefs) {} + +FakeDeviceTrustConnectorService::~FakeDeviceTrustConnectorService() = default; + +void FakeDeviceTrustConnectorService::update_policy( + std::unique_ptr<base::ListValue> new_urls) { + test_prefs_->SetUserPref(kContextAwareAccessSignalsAllowlistPref, + std::move(new_urls)); +} + +} // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.h b/chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.h new file mode 100644 index 0000000..baa1422 --- /dev/null +++ b/chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.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 CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_FAKE_DEVICE_TRUST_CONNECTOR_SERVICE_H_ +#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_FAKE_DEVICE_TRUST_CONNECTOR_SERVICE_H_ + +#include <memory> + +#include "base/values.h" +#include "chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h" + +namespace sync_preferences { +class TestingPrefServiceSyncable; +} // namespace sync_preferences + +namespace enterprise_connectors { + +class FakeDeviceTrustConnectorService : public DeviceTrustConnectorService { + public: + explicit FakeDeviceTrustConnectorService( + sync_preferences::TestingPrefServiceSyncable* profile_prefs); + ~FakeDeviceTrustConnectorService() override; + + void update_policy(std::unique_ptr<base::ListValue> new_urls); + + private: + sync_preferences::TestingPrefServiceSyncable* test_prefs_; +}; + +} // namespace enterprise_connectors + +#endif // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_FAKE_DEVICE_TRUST_CONNECTOR_SERVICE_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/mock_device_trust_service.cc b/chrome/browser/enterprise/connectors/device_trust/mock_device_trust_service.cc index cf52505..2bf65c1f 100644 --- a/chrome/browser/enterprise/connectors/device_trust/mock_device_trust_service.cc +++ b/chrome/browser/enterprise/connectors/device_trust/mock_device_trust_service.cc
@@ -7,8 +7,7 @@ namespace enterprise_connectors { namespace test { -MockDeviceTrustService::MockDeviceTrustService() - : DeviceTrustService(nullptr) {} +MockDeviceTrustService::MockDeviceTrustService() = default; MockDeviceTrustService::~MockDeviceTrustService() = default; } // namespace test
diff --git a/chrome/browser/enterprise/connectors/device_trust/mock_device_trust_service.h b/chrome/browser/enterprise/connectors/device_trust/mock_device_trust_service.h index 3eb429c..a73545d2 100644 --- a/chrome/browser/enterprise/connectors/device_trust/mock_device_trust_service.h +++ b/chrome/browser/enterprise/connectors/device_trust/mock_device_trust_service.h
@@ -21,10 +21,7 @@ BuildChallengeResponse, (const std::string&, AttestationCallback), (override)); - MOCK_METHOD(base::CallbackListSubscription, - RegisterTrustedUrlPatternsChangedCallback, - (TrustedUrlPatternsChangedCallback), - (override)); + MOCK_METHOD(bool, Watches, (const GURL&), (const, override)); }; } // namespace test
diff --git a/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.cc b/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.cc index d1e2edf..28e1ccf 100644 --- a/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.cc +++ b/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.cc
@@ -7,12 +7,11 @@ #include "base/memory/ptr_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/enterprise/connectors/connectors_prefs.h" +#include "chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h" #include "chrome/browser/enterprise/connectors/device_trust/device_trust_service.h" #include "chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.h" #include "chrome/browser/profiles/profile.h" -#include "components/policy/core/browser/url_util.h" #include "components/prefs/pref_service.h" -#include "components/url_matcher/url_matcher.h" #include "components/user_prefs/user_prefs.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_handle.h" @@ -38,10 +37,9 @@ ->GetPrefs(); // TODO(b/183690432): Check if the browser or device is being managed // to create the throttle. - if (!DeviceTrustService::IsEnabled(prefs)) + if (!DeviceTrustConnectorService::IsConnectorEnabled(prefs)) return nullptr; - DVLOG(1) << "DeviceTrustNavigationThrottle::MaybeCreateThrottleFor"; return std::make_unique<DeviceTrustNavigationThrottle>(navigation_handle); } @@ -57,37 +55,11 @@ content::NavigationHandle* navigation_handle) : content::NavigationThrottle(navigation_handle), device_trust_service_(device_trust_service) { - matcher_ = std::make_unique<url_matcher::URLMatcher>(); - - // Start listening for pref changes. - subscription_ = - device_trust_service_->RegisterTrustedUrlPatternsChangedCallback( - base::BindRepeating( - &DeviceTrustNavigationThrottle::OnTrustedUrlPatternsChanged, - base::Unretained(this))); + DCHECK(device_trust_service_); } DeviceTrustNavigationThrottle::~DeviceTrustNavigationThrottle() = default; -void DeviceTrustNavigationThrottle::OnTrustedUrlPatternsChanged( - const base::ListValue& origins) { - DVLOG(1) - << "DeviceTrustNavigationThrottle::OnTrustedUrlPatternsChanged count=" - << origins.GetList().size(); - - url_matcher::URLMatcherConditionSet::ID id(0); - if (!matcher_->IsEmpty()) { - // Clear old conditions in case they exist. - matcher_->RemoveConditionSets({id}); - } - - if (device_trust_service_ && device_trust_service_->IsEnabled()) { - // Add the new endpoints to the conditions. - policy::url_util::AddFilters(matcher_.get(), true /* allowed */, &id, - &origins); - } -} - content::NavigationThrottle::ThrottleCheckResult DeviceTrustNavigationThrottle::WillStartRequest() { return AddHeadersIfNeeded(); @@ -105,26 +77,17 @@ content::NavigationThrottle::ThrottleCheckResult DeviceTrustNavigationThrottle::AddHeadersIfNeeded() { const GURL& url = navigation_handle()->GetURL(); - DVLOG(1) << "DeviceTrustNavigationThrottle::AddHeadersIfNeeded url=" - << url.spec().c_str(); - if (!url.is_valid() || !url.SchemeIsHTTPOrHTTPS()) return PROCEED; if (!device_trust_service_ || !device_trust_service_->IsEnabled()) return PROCEED; - DCHECK(matcher_); - auto matches = matcher_->MatchURL(url); - if (matches.empty()) + if (!device_trust_service_->Watches(url)) return PROCEED; - DVLOG(1) << " DeviceTrustNavigationThrottle::AddHeadersIfNeeded matched"; - // If we are starting an attestation flow. if (navigation_handle()->GetResponseHeaders() == nullptr) { - DVLOG(1) << " DeviceTrustNavigationThrottle::AddHeadersIfNeeded adding " - "x-device-trust"; navigation_handle()->SetRequestHeader(kDeviceTrustHeader, kDeviceTrustHeaderValue); return PROCEED; @@ -133,9 +96,6 @@ // If a challenge is coming from the Idp. if (navigation_handle()->GetResponseHeaders()->HasHeader( kVerifiedAccessChallengeHeader)) { - DVLOG(1) << " DeviceTrustNavigationThrottle::HasHeader url=" - << url.spec().c_str(); - // Remove request header since is not needed for challenge response. navigation_handle()->RemoveRequestHeader(kDeviceTrustHeader); @@ -162,19 +122,13 @@ deferring_ = true; return DEFER; } - } else { - LOG(ERROR) << "No challenge in the response."; } return PROCEED; } void DeviceTrustNavigationThrottle::ReplyChallengeResponseAndResume( const std::string& challenge_response) { - DVLOG(1) << "DeviceTrustNavigationThrottle::ReplyChallengeResponseAndResume " - "challenge_response=" - << challenge_response; if (!deferring_) { - DVLOG(1) << "No navigation was deferred."; return; } deferring_ = false;
diff --git a/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.h b/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.h index d3d4164a..c6a9c28 100644 --- a/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.h +++ b/chrome/browser/enterprise/connectors/device_trust/navigation_throttle.h
@@ -9,14 +9,6 @@ #include "base/values.h" #include "content/public/browser/navigation_throttle.h" -class GURL; - -namespace url_matcher { - -class URLMatcher; - -} - namespace enterprise_connectors { class DeviceTrustService; @@ -56,8 +48,6 @@ const char* GetNameForLogging() override; private: - void OnTrustedUrlPatternsChanged(const base::ListValue& origins); - content::NavigationThrottle::ThrottleCheckResult AddHeadersIfNeeded(); // Whether this throttle is deferring the navigation. Only set to true in @@ -72,12 +62,6 @@ // IdP and resume the navigation. void ReplyChallengeResponseAndResume(const std::string& challenge_response); - // The URL matcher created from the ContextAwareAccessSignalsAllowlist policy. - std::unique_ptr<url_matcher::URLMatcher> matcher_; - - // Subscription for trusted URL pattern changes. - base::CallbackListSubscription subscription_; - base::WeakPtrFactory<DeviceTrustNavigationThrottle> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/enterprise/connectors/device_trust/navigation_throttle_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/navigation_throttle_unittest.cc index a69a51d..d5b2e06 100644 --- a/chrome/browser/enterprise/connectors/device_trust/navigation_throttle_unittest.cc +++ b/chrome/browser/enterprise/connectors/device_trust/navigation_throttle_unittest.cc
@@ -6,13 +6,18 @@ #include <memory> +#include "base/test/scoped_feature_list.h" #include "base/values.h" #include "build/build_config.h" #include "chrome/browser/enterprise/connectors/connectors_prefs.h" +#include "chrome/browser/enterprise/connectors/device_trust/device_trust_connector_service.h" +#include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h" +#include "chrome/browser/enterprise/connectors/device_trust/fake_device_trust_connector_service.h" #include "chrome/browser/enterprise/connectors/device_trust/mock_device_trust_service.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" #include "components/policy/core/common/policy_pref_names.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" #include "content/public/browser/navigation_throttle.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_task_environment.h" @@ -59,18 +64,20 @@ DeviceTrustNavigationThrottleTest() : trusted_urls_(GetTrustedUrls()) {} void SetUp() override { + scoped_feature_list_.InitAndEnableFeature(kDeviceTrustConnectorEnabled); web_contents_ = content::WebContentsTester::CreateTestWebContents(&profile_, nullptr); + fake_connector_ = std::make_unique<FakeDeviceTrustConnectorService>( + profile_.GetTestingPrefService()); + fake_connector_->update_policy( + std::make_unique<base::ListValue>(GetTrustedUrls())); + + EXPECT_CALL(mock_device_trust_service_, Watches(_)) + .WillRepeatedly(Invoke( + [this](const GURL& url) { return fake_connector_->Watches(url); })); EXPECT_CALL(mock_device_trust_service_, IsEnabled()) .WillRepeatedly(Return(true)); - EXPECT_CALL(mock_device_trust_service_, - RegisterTrustedUrlPatternsChangedCallback(_)) - .WillOnce([this](base::RepeatingCallback<void(const base::ListValue&)> - callback) { - callback.Run(trusted_urls_); - return base::CallbackListSubscription(); - }); } std::unique_ptr<DeviceTrustNavigationThrottle> CreateThrottle( @@ -87,10 +94,12 @@ protected: content::BrowserTaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; + base::test::ScopedFeatureList scoped_feature_list_; content::RenderViewHostTestEnabler rvh_test_enabler_; TestingProfile profile_; std::unique_ptr<content::WebContents> web_contents_; test::MockDeviceTrustService mock_device_trust_service_; + std::unique_ptr<FakeDeviceTrustConnectorService> fake_connector_; base::ListValue trusted_urls_; };
diff --git a/chrome/browser/extensions/api/mdns/mdns_api.cc b/chrome/browser/extensions/api/mdns/mdns_api.cc index 2e5525e..f81027c4 100644 --- a/chrome/browser/extensions/api/mdns/mdns_api.cc +++ b/chrome/browser/extensions/api/mdns/mdns_api.cc
@@ -16,6 +16,7 @@ #include "extensions/browser/extension_function.h" #include "extensions/browser/extension_host.h" #include "extensions/browser/extension_registry.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" namespace extensions { @@ -175,7 +176,7 @@ auto event = std::make_unique<Event>(events::MDNS_ON_SERVICE_LIST, mdns::OnServiceList::kEventName, std::move(results), browser_context_); - event->filter_info.service_type = service_type; + event->filter_info->service_type = service_type; // TODO(justinlin): To avoid having listeners without filters getting all // events, modify API to have this event require filters.
diff --git a/chrome/browser/extensions/api/scripting/scripting_api.cc b/chrome/browser/extensions/api/scripting/scripting_api.cc index ffa75d9..3e8e3ee 100644 --- a/chrome/browser/extensions/api/scripting/scripting_api.cc +++ b/chrome/browser/extensions/api/scripting/scripting_api.cc
@@ -551,7 +551,8 @@ mojom::HostID(mojom::HostID::HostType::kExtensions, extension()->id()), mojom::CodeInjection::NewJs( mojom::JSInjection::New(std::move(sources), execution_world, - /*wants_result=*/true, user_gesture())), + /*wants_result=*/true, user_gesture(), + /*wait_for_promise=*/true)), frame_scope, frame_ids, ScriptExecutor::MATCH_ABOUT_BLANK, mojom::RunLocation::kDocumentIdle, ScriptExecutor::DEFAULT_PROCESS, /* webview_src */ GURL(),
diff --git a/chrome/browser/extensions/api/tabs/windows_event_router.cc b/chrome/browser/extensions/api/tabs/windows_event_router.cc index a40c7a4..ff5a7c8 100644 --- a/chrome/browser/extensions/api/tabs/windows_event_router.cc +++ b/chrome/browser/extensions/api/tabs/windows_event_router.cc
@@ -25,6 +25,7 @@ #include "extensions/browser/event_router.h" #include "extensions/browser/extension_util.h" #include "extensions/common/constants.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" using content::BrowserContext; @@ -75,13 +76,14 @@ } // Cleanup previous values. - event->filter_info = EventFilteringInfo(); + event->filter_info = mojom::EventFilteringInfo::New(); // Only set the window type if the listener has set a filter. // Otherwise we set the window visibility relative to the extension. if (has_filter) { - event->filter_info.window_type = window_controller->GetWindowTypeText(); + event->filter_info->window_type = window_controller->GetWindowTypeText(); } else { - event->filter_info.window_exposed_by_default = true; + event->filter_info->has_window_exposed_by_default = true; + event->filter_info->window_exposed_by_default = true; } return true; } @@ -107,17 +109,18 @@ } // Cleanup previous values. - event->filter_info = EventFilteringInfo(); + event->filter_info = mojom::EventFilteringInfo::New(); // Only set the window type if the listener has set a filter, // otherwise set the visibility to true (if the window is not // supposed to be visible by the extension, we will clear out the // window id later). if (has_filter) { - event->filter_info.window_type = + event->filter_info->window_type = window_controller ? window_controller->GetWindowTypeText() : extensions::tabs_constants::kWindowTypeValueNormal; } else { - event->filter_info.window_exposed_by_default = true; + event->filter_info->has_window_exposed_by_default = true; + event->filter_info->window_exposed_by_default = true; } // When switching between windows in the default and incognito profiles,
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.cc b/chrome/browser/extensions/api/terminal/terminal_private_api.cc index 1a0d6567..782e18db 100644 --- a/chrome/browser/extensions/api/terminal/terminal_private_api.cc +++ b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
@@ -131,7 +131,8 @@ } private: - explicit TerminalTabHelper(content::WebContents* contents) {} + explicit TerminalTabHelper(content::WebContents* contents) + : content::WebContentsUserData<TerminalTabHelper>(*contents) {} friend class content::WebContentsUserData<TerminalTabHelper>; WEB_CONTENTS_USER_DATA_KEY_DECL();
diff --git a/chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.cc b/chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.cc index 32b584b0..6d3a9f3 100644 --- a/chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.cc +++ b/chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.cc
@@ -26,7 +26,7 @@ #include "content/public/common/url_constants.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_api_frame_id_map.h" -#include "extensions/common/event_filtering_info.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "net/base/net_errors.h" #include "ui/base/page_transition_types.h" @@ -47,14 +47,13 @@ void DispatchEvent(content::BrowserContext* browser_context, std::unique_ptr<Event> event, const GURL& url) { - EventFilteringInfo info; - info.url = url; - Profile* profile = Profile::FromBrowserContext(browser_context); EventRouter* event_router = EventRouter::Get(profile); if (profile && event_router) { + mojom::EventFilteringInfoPtr info = mojom::EventFilteringInfo::New(); + info->url = url; DCHECK_EQ(profile, event->restrict_to_browser_context); - event->filter_info = info; + event->filter_info = std::move(info); event_router->BroadcastEvent(std::move(event)); } } @@ -82,9 +81,9 @@ web_navigation::OnBeforeNavigate::Create(details), navigation_handle->GetWebContents()->GetBrowserContext()); - EventFilteringInfo info; - info.url = navigation_handle->GetURL(); - event->filter_info = info; + mojom::EventFilteringInfoPtr info = mojom::EventFilteringInfo::New(); + info->url = navigation_handle->GetURL(); + event->filter_info = std::move(info); return event; }
diff --git a/chrome/browser/extensions/component_loader.h b/chrome/browser/extensions/component_loader.h index 1d856a0..6d798cb 100644 --- a/chrome/browser/extensions/component_loader.h +++ b/chrome/browser/extensions/component_loader.h
@@ -196,7 +196,6 @@ void AddImageLoaderExtension(); void AddGuestModeTestExtension(const base::FilePath& path); void AddKeyboardApp(); - void AddChromeCameraApp(); #endif // BUILDFLAG(IS_CHROMEOS_ASH) scoped_refptr<const Extension> CreateExtension(
diff --git a/chrome/browser/extensions/extension_messages_apitest.cc b/chrome/browser/extensions/extension_messages_apitest.cc index f53ba48..e219dd3 100644 --- a/chrome/browser/extensions/extension_messages_apitest.cc +++ b/chrome/browser/extensions/extension_messages_apitest.cc
@@ -42,6 +42,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/storage_partition.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" @@ -125,21 +126,52 @@ class MessagingApiTest : public ExtensionApiTest { public: - MessagingApiTest() {} + MessagingApiTest() : MessagingApiTest(/*enable_back_forward_cache=*/true) { + // Enable back/forward cache. + } + explicit MessagingApiTest(bool enable_back_forward_cache) { + if (enable_back_forward_cache) { + feature_list_.InitWithFeaturesAndParameters( + {{features::kBackForwardCache, + // The tests does same-site navigation. So same site BFCache needs + // to be enabled. + {{"enable_same_site", "true"}}}, + // Allow BackForwardCache for all devices regardless of their memory. + {features::kBackForwardCacheMemoryControls, {}}}, + {}); + } else { + feature_list_.InitWithFeaturesAndParameters( + {}, {features::kBackForwardCache}); + } + } MessagingApiTest(const MessagingApiTest&) = delete; MessagingApiTest& operator=(const MessagingApiTest&) = delete; - ~MessagingApiTest() override {} + ~MessagingApiTest() override = default; void SetUpOnMainThread() override { ExtensionApiTest::SetUpOnMainThread(); host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(StartEmbeddedTestServer()); } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +class MessagingApiWithoutBackForwardCacheTest : public MessagingApiTest { + public: + MessagingApiWithoutBackForwardCacheTest() + : MessagingApiTest(/*enable_back_forward_cache=*/false) {} }; IN_PROC_BROWSER_TEST_F(MessagingApiTest, Messaging) { + ASSERT_TRUE(RunExtensionTest("messaging/connect", {.custom_arg = "bfcache"})) + << message_; +} + +IN_PROC_BROWSER_TEST_F(MessagingApiWithoutBackForwardCacheTest, Messaging) { ASSERT_TRUE(RunExtensionTest("messaging/connect")) << message_; }
diff --git a/chrome/browser/extensions/extension_service_sync_unittest.cc b/chrome/browser/extensions/extension_service_sync_unittest.cc index e3c8a0e..63d13d1 100644 --- a/chrome/browser/extensions/extension_service_sync_unittest.cc +++ b/chrome/browser/extensions/extension_service_sync_unittest.cc
@@ -235,25 +235,6 @@ } }; -TEST_F(ExtensionServiceSyncTest, DeleteAllInstalledBookMarkAppsDuringSync) { - InitializeEmptyExtensionService(); - - // Install the bookmark app. - InstallCRX(data_dir().AppendASCII("good.crx"), - ManifestLocation::kExternalPref, INSTALL_NEW, - Extension::FROM_BOOKMARK); - const Extension* extension = registry()->GetInstalledExtension(good_crx); - ASSERT_TRUE(extension); - ASSERT_TRUE(extension->from_bookmark()); - ASSERT_FALSE(extensions::util::ShouldSync(extension, profile())); - - StartSyncing(syncer::EXTENSIONS); - - // Should uninstall the bookmark app. - EXPECT_FALSE( - registry()->GetExtensionById(good_crx, ExtensionRegistry::EVERYTHING)); -} - TEST_F(ExtensionServiceSyncTest, DeferredSyncStartupPreInstalledComponent) { InitializeEmptyExtensionService();
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc index 1a61f9f8..40660eb 100644 --- a/chrome/browser/extensions/extension_service_unittest.cc +++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -1247,36 +1247,6 @@ registry->RemoveObserver(&observer); } -// Tests that flags passed to OnExternalExtensionFileFound() make it to the -// extension object. -TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) { - InitializeEmptyExtensionService(); - - base::FilePath path = data_dir().AppendASCII("good.crx"); - - // Register and install an external extension. - std::string version_str = "1.0.0.0"; - std::unique_ptr<ExternalInstallInfoFile> info = CreateExternalExtension( - good_crx, version_str, path, ManifestLocation::kExternalPref, - Extension::FROM_BOOKMARK); - MockExternalProvider* provider = - AddMockExternalProvider(ManifestLocation::kExternalPolicyDownload); - provider->UpdateOrAddExtension(std::move(info)); - WaitForExternalExtensionInstalled(); - - const Extension* extension = - registry()->enabled_extensions().GetByID(good_crx); - ASSERT_TRUE(extension); - ASSERT_TRUE(extension->from_bookmark()); - - // Upgrade to version 2.0, the flag should be preserved. - path = data_dir().AppendASCII("good2.crx"); - UpdateExtension(good_crx, path, ENABLED); - extension = registry()->enabled_extensions().GetByID(good_crx); - ASSERT_TRUE(extension); - ASSERT_TRUE(extension->from_bookmark()); -} - // Test the handling of uninstalling external extensions. TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) { InitializeEmptyExtensionService(); @@ -4658,42 +4628,6 @@ } #endif -// Crashes on Linux/CrOS. https://crbug.com/703712 -#if defined(OS_LINUX) || defined(OS_CHROMEOS) -#define MAYBE_UpdatingPendingExternalExtensionWithFlags \ - DISABLED_UpdatingPendingExternalExtensionWithFlags -#else -#define MAYBE_UpdatingPendingExternalExtensionWithFlags \ - UpdatingPendingExternalExtensionWithFlags -#endif - -TEST_F(ExtensionServiceTest, MAYBE_UpdatingPendingExternalExtensionWithFlags) { - // Regression test for crbug.com/627522 - InitializeEmptyExtensionService(); - - base::FilePath path = data_dir().AppendASCII("good.crx"); - - // Register and install an external extension. - base::Version version("1.0.0.0"); - content::WindowedNotificationObserver observer( - NOTIFICATION_CRX_INSTALLER_DONE, - content::NotificationService::AllSources()); - ExternalInstallInfoFile info( - good_crx, version, path, ManifestLocation::kExternalPref, - Extension::FROM_BOOKMARK, false /* mark_acknowledged */, - false /* install_immediately */); - ASSERT_TRUE(service()->OnExternalExtensionFileFound(info)); - EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx)); - - // Upgrade to version 2.0, the flag should be preserved. - path = data_dir().AppendASCII("good2.crx"); - UpdateExtension(good_crx, path, ENABLED); - const Extension* extension = - registry()->enabled_extensions().GetByID(good_crx); - ASSERT_TRUE(extension); - ASSERT_TRUE(extension->from_bookmark()); -} - // Tests disabling extensions TEST_F(ExtensionServiceTest, DisableExtension) { InitializeEmptyExtensionService();
diff --git a/chrome/browser/extensions/lazy_background_page_apitest.cc b/chrome/browser/extensions/lazy_background_page_apitest.cc index 55c7308..b51480c9 100644 --- a/chrome/browser/extensions/lazy_background_page_apitest.cc +++ b/chrome/browser/extensions/lazy_background_page_apitest.cc
@@ -38,6 +38,7 @@ #include "components/javascript_dialogs/app_modal_dialog_controller.h" #include "components/nacl/common/buildflags.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_utils.h" @@ -611,6 +612,32 @@ } } +class LazyBackgroundPageApiWithBFCacheParamTest + : public LazyBackgroundPageApiTest, + public testing::WithParamInterface<bool> { + public: + LazyBackgroundPageApiWithBFCacheParamTest() { + if (IsBackForwardCacheEnabled()) { + feature_list_.InitWithFeaturesAndParameters( + {{features::kBackForwardCache, {{"enable_same_site", "true"}}}, + // Allow BackForwardCache for all devices regardless of their memory. + {features::kBackForwardCacheMemoryControls, {}}}, + {}); + } else { + feature_list_.InitWithFeaturesAndParameters( + {}, {features::kBackForwardCache}); + } + } + bool IsBackForwardCacheEnabled() { return GetParam(); } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +INSTANTIATE_TEST_SUITE_P(All, + LazyBackgroundPageApiWithBFCacheParamTest, + testing::Bool()); + // Tests that messages from the content script activate the lazy background // page, and keep it alive until all channels are closed. // http://crbug.com/1179524; test fails occasionally on OS X 10.15 @@ -619,7 +646,8 @@ #else #define MAYBE_Messaging Messaging #endif -IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, MAYBE_Messaging) { +IN_PROC_BROWSER_TEST_P(LazyBackgroundPageApiWithBFCacheParamTest, + MAYBE_Messaging) { ASSERT_TRUE(StartEmbeddedTestServer()); ASSERT_TRUE(LoadExtensionAndWait("messaging")); @@ -640,12 +668,20 @@ EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id())); - // Navigate away, closing the message channel and therefore the background - // page. + // Navigate away ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("about:blank"))); - host_helper.WaitForHostDestroyed(); - EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id())); + if (IsBackForwardCacheEnabled()) { + // When the page is stored back/forward cache, the message channel should be + // kept. + WaitForLoadStop(browser()->tab_strip_model()->GetActiveWebContents()); + EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id())); + } else { + // Without back/forward cache, navigating away triggers closing the message + // channel and therefore the background page. + host_helper.WaitForHostDestroyed(); + EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id())); + } } // Tests that the lazy background page receives the unload event when we
diff --git a/chrome/browser/extensions/menu_manager.cc b/chrome/browser/extensions/menu_manager.cc index 3b1657d..8de380f 100644 --- a/chrome/browser/extensions/menu_manager.cc +++ b/chrome/browser/extensions/menu_manager.cc
@@ -33,6 +33,7 @@ #include "extensions/browser/state_store.h" #include "extensions/common/extension.h" #include "extensions/common/manifest_handlers/background_info.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "third_party/blink/public/mojom/context_menu/context_menu.mojom.h" #include "ui/gfx/favicon_size.h" #include "ui/gfx/text_elider.h" @@ -761,8 +762,10 @@ : api::context_menus::OnClicked::kEventName, std::move(args), context); event->user_gesture = EventRouter::USER_GESTURE_ENABLED; - if (webview_guest) - event->filter_info.instance_id = webview_guest->view_instance_id(); + if (webview_guest) { + event->filter_info->has_instance_id = true; + event->filter_info->instance_id = webview_guest->view_instance_id(); + } event_router->DispatchEventToExtension(item->extension_id(), std::move(event)); }
diff --git a/chrome/browser/extensions/script_executor_browsertest.cc b/chrome/browser/extensions/script_executor_browsertest.cc index da230c70..9d2d008 100644 --- a/chrome/browser/extensions/script_executor_browsertest.cc +++ b/chrome/browser/extensions/script_executor_browsertest.cc
@@ -133,7 +133,8 @@ mojom::HostID(mojom::HostID::HostType::kExtensions, extension->id()), mojom::CodeInjection::NewJs(mojom::JSInjection::New( std::move(sources), mojom::ExecutionWorld::kMain, - true /* wants_result */, false /* user_gesture */)), + true /* wants_result */, false /* user_gesture */, + true /* wait_for_promise */)), ScriptExecutor::SPECIFIED_FRAMES, {ExtensionApiFrameIdMap::kTopFrameId}, ScriptExecutor::DONT_MATCH_ABOUT_BLANK, mojom::RunLocation::kDocumentIdle, ScriptExecutor::DEFAULT_PROCESS, GURL() /* webview_src */, @@ -180,7 +181,8 @@ mojom::HostID(mojom::HostID::HostType::kExtensions, extension->id()), mojom::CodeInjection::NewJs(mojom::JSInjection::New( std::move(sources), mojom::ExecutionWorld::kIsolated, - true /* wants_result */, false /* user_gesture */)), + true /* wants_result */, false /* user_gesture */, + true /* wait_for_promise */)), ScriptExecutor::SPECIFIED_FRAMES, {ExtensionApiFrameIdMap::kTopFrameId}, ScriptExecutor::DONT_MATCH_ABOUT_BLANK, mojom::RunLocation::kDocumentIdle, ScriptExecutor::DEFAULT_PROCESS, GURL() /* webview_src */, @@ -234,7 +236,8 @@ mojom::HostID(mojom::HostID::HostType::kExtensions, extension->id()), mojom::CodeInjection::NewJs(mojom::JSInjection::New( std::move(sources), mojom::ExecutionWorld::kIsolated, - true /* wants_result */, false /* user_gesture */)), + true /* wants_result */, false /* user_gesture */, + true /* wait_for_promise */)), ScriptExecutor::SPECIFIED_FRAMES, {ExtensionApiFrameIdMap::kTopFrameId}, ScriptExecutor::DONT_MATCH_ABOUT_BLANK, mojom::RunLocation::kDocumentIdle, ScriptExecutor::DEFAULT_PROCESS, GURL() /* webview_src */, @@ -249,6 +252,101 @@ EXPECT_EQ("", helper.results()[0].error); } +// Tests that scripts that evaluate to promises can be properly waited upon. +IN_PROC_BROWSER_TEST_F(ScriptExecutorBrowserTest, PromisesResolve) { + const Extension* extension = + LoadExtensionWithHostPermission("http://example.com/*"); + + GURL example_com = + embedded_test_server()->GetURL("example.com", "/simple.html"); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(web_contents); + + { + content::TestNavigationObserver nav_observer(web_contents); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), example_com)); + nav_observer.Wait(); + EXPECT_TRUE(nav_observer.last_navigation_succeeded()); + } + + EXPECT_EQ("OK", base::UTF16ToUTF8(web_contents->GetTitle())); + + ScriptExecutor script_executor(web_contents); + + { + // Inject two pieces of code. They each evaluate to a promise. The second, + // `kCode2`, evaluates to a promise that resolves immediately, and then + // asynchronously resovles the promise from the first, `kCode1`, which + // changes the title of the page. + // This guarantees that the renderer code properly waits for *all* results + // to resolve, and not simply the last one. + constexpr char kCode1[] = + R"((new Promise((resolve) => { + window.resolveFirstPromise = resolve; + }).then(() => { + document.title = 'New Title'; + }));)"; + constexpr char kCode2[] = + R"((new Promise((resolve) => { + resolve('Second Promise'); + setTimeout(window.resolveFirstPromise, 0); + }));)"; + + ScriptExecutorHelper helper; + std::vector<mojom::JSSourcePtr> sources; + sources.push_back(mojom::JSSource::New(kCode1, GURL())); + sources.push_back(mojom::JSSource::New(kCode2, GURL())); + script_executor.ExecuteScript( + mojom::HostID(mojom::HostID::HostType::kExtensions, extension->id()), + mojom::CodeInjection::NewJs(mojom::JSInjection::New( + std::move(sources), mojom::ExecutionWorld::kIsolated, + true /* wants_result */, false /* user_gesture */, + true /* wait_for_promise */)), + ScriptExecutor::SPECIFIED_FRAMES, {ExtensionApiFrameIdMap::kTopFrameId}, + ScriptExecutor::DONT_MATCH_ABOUT_BLANK, + mojom::RunLocation::kDocumentIdle, ScriptExecutor::DEFAULT_PROCESS, + GURL() /* webview_src */, helper.GetCallback()); + helper.Wait(); + + EXPECT_EQ("New Title", base::UTF16ToUTF8(web_contents->GetTitle())); + ASSERT_EQ(1u, helper.results().size()); + EXPECT_EQ(web_contents->GetLastCommittedURL(), helper.results()[0].url); + EXPECT_EQ(base::Value("Second Promise"), helper.results()[0].value); + EXPECT_EQ(0, helper.results()[0].frame_id); + EXPECT_EQ("", helper.results()[0].error); + } + + { + // Next, inject code that evaluates to a promise, but don't include the + // "wait_for_promise" flag. The returned result should be the promise + // itself, which then serializes to an empty object (`{}`). + constexpr char kCode[] = R"((new Promise((r) => { r('hello'); }));)"; + + ScriptExecutorHelper helper; + std::vector<mojom::JSSourcePtr> sources; + sources.push_back(mojom::JSSource::New(kCode, GURL())); + script_executor.ExecuteScript( + mojom::HostID(mojom::HostID::HostType::kExtensions, extension->id()), + mojom::CodeInjection::NewJs(mojom::JSInjection::New( + std::move(sources), mojom::ExecutionWorld::kIsolated, + true /* wants_result */, false /* user_gesture */, + false /* wait_for_promise */)), + ScriptExecutor::SPECIFIED_FRAMES, {ExtensionApiFrameIdMap::kTopFrameId}, + ScriptExecutor::DONT_MATCH_ABOUT_BLANK, + mojom::RunLocation::kDocumentIdle, ScriptExecutor::DEFAULT_PROCESS, + GURL() /* webview_src */, helper.GetCallback()); + helper.Wait(); + + ASSERT_EQ(1u, helper.results().size()); + EXPECT_EQ(web_contents->GetLastCommittedURL(), helper.results()[0].url); + EXPECT_EQ(base::Value(base::Value::Type::DICTIONARY), + helper.results()[0].value); + EXPECT_EQ(0, helper.results()[0].frame_id); + EXPECT_EQ("", helper.results()[0].error); + } +} + // Tests script execution into a specified set of frames. IN_PROC_BROWSER_TEST_F(ScriptExecutorBrowserTest, SpecifiedFrames) { const Extension* extension = @@ -318,7 +416,8 @@ mojom::HostID(mojom::HostID::HostType::kExtensions, extension->id()), mojom::CodeInjection::NewJs(mojom::JSInjection::New( std::move(sources), mojom::ExecutionWorld::kIsolated, - true /* wants_result */, false /* user_gesture */)), + true /* wants_result */, false /* user_gesture */, + true /* wait_for_promise */)), ScriptExecutor::SPECIFIED_FRAMES, {frame1_id, frame2_id}, ScriptExecutor::DONT_MATCH_ABOUT_BLANK, mojom::RunLocation::kDocumentIdle, ScriptExecutor::DEFAULT_PROCESS, @@ -341,7 +440,8 @@ mojom::HostID(mojom::HostID::HostType::kExtensions, extension->id()), mojom::CodeInjection::NewJs(mojom::JSInjection::New( std::move(sources), mojom::ExecutionWorld::kIsolated, - true /* wants_result */, false /* user_gesture */)), + true /* wants_result */, false /* user_gesture */, + true /* wait_for_promise */)), ScriptExecutor::INCLUDE_SUB_FRAMES, {frame1_id, frame2_id}, ScriptExecutor::DONT_MATCH_ABOUT_BLANK, mojom::RunLocation::kDocumentIdle, ScriptExecutor::DEFAULT_PROCESS, @@ -373,7 +473,8 @@ mojom::HostID(mojom::HostID::HostType::kExtensions, extension->id()), mojom::CodeInjection::NewJs(mojom::JSInjection::New( std::move(sources), mojom::ExecutionWorld::kIsolated, - true /* wants_result */, false /* user_gesture */)), + true /* wants_result */, false /* user_gesture */, + true /* wait_for_promise */)), ScriptExecutor::SPECIFIED_FRAMES, {frame1_id, frame2_id, kNonExistentFrameId}, ScriptExecutor::DONT_MATCH_ABOUT_BLANK, @@ -398,7 +499,8 @@ mojom::HostID(mojom::HostID::HostType::kExtensions, extension->id()), mojom::CodeInjection::NewJs(mojom::JSInjection::New( std::move(sources), mojom::ExecutionWorld::kIsolated, - true /* wants_result */, false /* user_gesture */)), + true /* wants_result */, false /* user_gesture */, + true /* wait_for_promise */)), ScriptExecutor::SPECIFIED_FRAMES, {kNonExistentFrameId}, ScriptExecutor::DONT_MATCH_ABOUT_BLANK, mojom::RunLocation::kDocumentIdle, ScriptExecutor::DEFAULT_PROCESS,
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index 4f1a7d0..4dedea76 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -4,6 +4,8 @@ #include <stdint.h> +#include <utility> + #include "base/bind.h" #include "base/callback_helpers.h" #include "base/json/json_reader.h" @@ -71,6 +73,7 @@ #include "extensions/common/extensions_client.h" #include "extensions/common/features/feature_channel.h" #include "extensions/common/manifest_handlers/background_info.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/common/permissions/permissions_data.h" #include "extensions/common/value_builder.h" #include "extensions/common/verifier_formats.h" @@ -913,9 +916,9 @@ events::WEB_NAVIGATION_ON_COMMITTED, "webNavigation.onCommitted", api::web_navigation::OnCommitted::Create(details), profile()); // The filter will match the listener filter registered from the extension. - EventFilteringInfo info; - info.url = GURL("http://foo.com/a.html"); - on_committed_event->filter_info = info; + mojom::EventFilteringInfoPtr info = mojom::EventFilteringInfo::New(); + info->url = GURL("http://foo.com/a.html"); + on_committed_event->filter_info = std::move(info); EarlyWorkerMessageSender sender(profile(), kId, std::move(on_committed_event));
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc index 41099b4..bc8ef85 100644 --- a/chrome/browser/extensions/tab_helper.cc +++ b/chrome/browser/extensions/tab_helper.cc
@@ -88,7 +88,7 @@ return true; static base::FeatureParam<bool> all_extensions_allowed( - &features::kBackForwardCache, "all_extensions_allowed", false); + &features::kBackForwardCache, "all_extensions_allowed", true); return all_extensions_allowed.Get(); }
diff --git a/chrome/browser/feed/android/java/res/layout/web_feed_main_menu_item.xml b/chrome/browser/feed/android/java/res/layout/web_feed_main_menu_item.xml index ba19faeb..11f6857f 100644 --- a/chrome/browser/feed/android/java/res/layout/web_feed_main_menu_item.xml +++ b/chrome/browser/feed/android/java/res/layout/web_feed_main_menu_item.xml
@@ -63,6 +63,6 @@ android:id="@+id/web_feed_menu_divider" style="@style/HorizontalDivider" android:layout_width="match_parent" - android:background="@color/divider_line_bg_color" /> + android:background="@macro/divider_line_bg_color" /> </org.chromium.chrome.browser.feed.webfeed.WebFeedMainMenuItem>
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index ca9ceb65..ace4d8d 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1671,7 +1671,7 @@ { "name": "enable-cros-language-settings-update-2", "owners": [ "cros-borders@google.com" ], - "expiry_milestone": 96 + "expiry_milestone": 100 }, { "name": "enable-cros-multilingual-typing", @@ -2410,6 +2410,11 @@ "expiry_milestone": -1 }, { + "name": "enable-password-manager-branding-update", + "owners": [ "alionadangla", "bwwilliams"], + "expiry_milestone": 105 + }, + { "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
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 37094d3..bfccc20f 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -4515,11 +4515,6 @@ "Enable normalization of scores from different providers to the " "launcher."; -const char kNewDragSpecInLauncherName[] = "Enable Launcher App Paging"; -const char kNewDragSpecInLauncherDescription[] = - "Show visual affordance of launcher app pages and enable page previews " - "when dragging apps."; - const char kEnableNeuralStylusPalmRejectionName[] = "Enable Neural Palm Detection"; const char kEnableNeuralStylusPalmRejectionDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 2129e9d..bfe2eff 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2590,9 +2590,6 @@ extern const char kEnableLibinputToHandleTouchpadName[]; extern const char kEnableLibinputToHandleTouchpadDescription[]; -extern const char kNewDragSpecInLauncherName[]; -extern const char kNewDragSpecInLauncherDescription[]; - extern const char kEnableNeuralStylusPalmRejectionName[]; extern const char kEnableNeuralStylusPalmRejectionDescription[];
diff --git a/chrome/browser/headless/headless_mode_browsertest.cc b/chrome/browser/headless/headless_mode_browsertest.cc index 292d233..b9b5aec 100644 --- a/chrome/browser/headless/headless_mode_browsertest.cc +++ b/chrome/browser/headless/headless_mode_browsertest.cc
@@ -17,6 +17,10 @@ #include "testing/gmock/include/gmock/gmock.h" #include "ui/gfx/switches.h" +#if defined(OS_LINUX) +#include "ui/ozone/public/ozone_platform.h" +#endif // defined(OS_LINUX) + namespace { const char kChrome[] = "chrome"; } // namespace @@ -46,6 +50,14 @@ private: }; +#if defined(OS_LINUX) +IN_PROC_BROWSER_TEST_F(HeadlessModeBrowserTest, OzonePlatformHeadless) { + // On Linux, the Native Headless Chrome uses Ozone/Headless. + ASSERT_NE(ui::OzonePlatform::GetInstance(), nullptr); + EXPECT_EQ(ui::OzonePlatform::GetPlatformNameForTest(), "headless"); +} +#endif // defined(OS_LINUX) + #if defined(OS_WIN) IN_PROC_BROWSER_TEST_F(HeadlessModeBrowserTest, BrowserDesktopWindowHidden) { // On Windows, the Native Headless Chrome browser window exists but is hidden.
diff --git a/chrome/browser/image_editor/screenshot_flow.cc b/chrome/browser/image_editor/screenshot_flow.cc index 270f363..3de8731 100644 --- a/chrome/browser/image_editor/screenshot_flow.cc +++ b/chrome/browser/image_editor/screenshot_flow.cc
@@ -259,6 +259,9 @@ ScreenshotCaptureResultCode result_code, gfx::Rect bounds, gfx::Image image) { + if (flow_callback_.is_null()) + return; + ScreenshotCaptureResult result; result.result_code = result_code; result.image = image;
diff --git a/chrome/browser/lacros/lacros_url_handling.cc b/chrome/browser/lacros/lacros_url_handling.cc index e3f88a5..1f02a6f 100644 --- a/chrome/browser/lacros/lacros_url_handling.cc +++ b/chrome/browser/lacros/lacros_url_handling.cc
@@ -4,7 +4,9 @@ #include "chrome/browser/lacros/lacros_url_handling.h" +#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" #include "chrome/common/webui_url_constants.h" +#include "chromeos/crosapi/cpp/gurl_os_handler_utils.h" #include "chromeos/crosapi/mojom/url_handler.mojom.h" #include "chromeos/lacros/lacros_service.h" #include "url/gurl.h" @@ -12,23 +14,49 @@ namespace lacros_url_handling { bool MaybeInterceptNavigation(const GURL& url) { - // For now, just intercept the os-settings URL. - if (url.DeprecatedGetOriginAsURL() != - GURL(chrome::kChromeUIOSSettingsURL).DeprecatedGetOriginAsURL()) + const GURL& target_url = url.DeprecatedGetOriginAsURL(); + const GURL& ash_url = crosapi::gurl_os_handler_utils::SanitizeAshURL(url); + // Every URL which is supported by Ash but not by Lacros will automatically + // forwarded to Ash. Note: We are using the original url to check for + // Ash compatibility + if (IsUrlHandledByLacros(target_url) || !IsUrlAcceptedByAsh(ash_url)) return false; - // We may expand this in the future to support a dynamic set of URLs provided - // by Ash via LacrosInitParams. That way we avoid having to synchronize the - // set of known chrome:// URLs across the two sides. - return NavigateInAsh(url); + return NavigateInAsh(ash_url); +} + +bool IsUrlHandledByLacros(const GURL& url) { + return ChromeWebUIControllerFactory::GetInstance()->CanHandleUrl(url); +} + +bool IsUrlAcceptedByAsh(const GURL& requested_url) { + auto* init_params = chromeos::LacrosService::Get()->init_params(); + if (!init_params->accepted_internal_ash_urls.has_value()) { + // For Ash backwards compatibility allow URLs to be used which were + // allowed before crosapi passed allowed URLs. + return requested_url == GURL(chrome::kChromeUIOSSettingsURL) + .DeprecatedGetOriginAsURL() || + requested_url == + GURL(chrome::kChromeUIFlagsURL).DeprecatedGetOriginAsURL(); + } + + return crosapi::gurl_os_handler_utils::IsUrlInList( + requested_url, *init_params->accepted_internal_ash_urls); } bool NavigateInAsh(const GURL& url) { + // As requested by security, all additional queries will get removed. + // Note that this will also be done on the Ash side for the same reason. + const GURL& ash_url = crosapi::gurl_os_handler_utils::SanitizeAshURL(url); + + if (!IsUrlAcceptedByAsh(ash_url)) + return false; + chromeos::LacrosService* service = chromeos::LacrosService::Get(); if (!service->IsAvailable<crosapi::mojom::UrlHandler>()) return false; - service->GetRemote<crosapi::mojom::UrlHandler>()->OpenUrl(url); + service->GetRemote<crosapi::mojom::UrlHandler>()->OpenUrl(ash_url); return true; }
diff --git a/chrome/browser/lacros/lacros_url_handling.h b/chrome/browser/lacros/lacros_url_handling.h index 6eb6992..ee4f7ec 100644 --- a/chrome/browser/lacros/lacros_url_handling.h +++ b/chrome/browser/lacros/lacros_url_handling.h
@@ -14,6 +14,14 @@ // how to load. Returns |true| if the navigation was intercepted. bool MaybeInterceptNavigation(const GURL& url); +// Checks if Ash is allowed and able to handle the requested URL or not. +// Note that the passed |url| must be sanitized before passing in. +bool IsUrlAcceptedByAsh(const GURL& url); + +// Checks if Lacros is able to handle the requested URL or not. +// Note that the passed |url| must be sanitized before passing in. +bool IsUrlHandledByLacros(const GURL& requested_url); + // This is an explicit url redirect executed in Ash. It returns |true| when // a navigation has been forwarded to Ash. This call is used for chrome:// and // os:// URLs which are handled either by Ash or Ash and Lacros.
diff --git a/chrome/browser/lacros/lacros_url_handling_unittest.cc b/chrome/browser/lacros/lacros_url_handling_unittest.cc new file mode 100644 index 0000000..eb953b6d --- /dev/null +++ b/chrome/browser/lacros/lacros_url_handling_unittest.cc
@@ -0,0 +1,50 @@ +// 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/lacros_url_handling.h" + +#include "base/test/task_environment.h" +#include "chrome/common/url_constants.h" +#include "chromeos/crosapi/mojom/crosapi.mojom.h" +#include "chromeos/lacros/lacros_service.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +TEST(LacrosUrlHandlingTest, IsURLAcceptedByAshOldVersion) { + base::test::TaskEnvironment task_environment; + chromeos::LacrosService lacros_service; + + auto params = crosapi::mojom::BrowserInitParams::New(); + lacros_service.SetInitParamsForTests(std::move(params)); + EXPECT_TRUE(lacros_url_handling::IsUrlAcceptedByAsh( + GURL(chrome::kChromeUIOSSettingsURL))); + EXPECT_TRUE( + lacros_url_handling::IsUrlAcceptedByAsh(GURL(chrome::kChromeUIFlagsURL))); + EXPECT_FALSE(lacros_url_handling::IsUrlAcceptedByAsh(GURL(""))); + EXPECT_FALSE( + lacros_url_handling::IsUrlAcceptedByAsh(GURL("chrome://flags2"))); +} + +TEST(LacrosUrlHandlingTest, IsURLAcceptedByAsh) { + base::test::TaskEnvironment task_environment; + chromeos::LacrosService lacros_service; + + auto params = crosapi::mojom::BrowserInitParams::New(); + params->accepted_internal_ash_urls = std::vector<GURL>{ + GURL(chrome::kChromeUIFlagsURL), GURL(chrome::kChromeUIOSSettingsURL), + GURL("chrome://version")}; + lacros_service.SetInitParamsForTests(std::move(params)); + EXPECT_TRUE(lacros_url_handling::IsUrlAcceptedByAsh( + GURL(chrome::kChromeUIOSSettingsURL))); + EXPECT_TRUE( + lacros_url_handling::IsUrlAcceptedByAsh(GURL(chrome::kChromeUIFlagsURL))); + EXPECT_TRUE( + lacros_url_handling::IsUrlAcceptedByAsh(GURL("chrome://version"))); + EXPECT_FALSE( + lacros_url_handling::IsUrlAcceptedByAsh(GURL("chrome://versions"))); + EXPECT_FALSE(lacros_url_handling::IsUrlAcceptedByAsh(GURL("http://version"))); + EXPECT_FALSE(lacros_url_handling::IsUrlAcceptedByAsh(GURL(""))); + EXPECT_FALSE( + lacros_url_handling::IsUrlAcceptedByAsh(GURL("chrome://flags2"))); +}
diff --git a/chrome/browser/media/webrtc/display_media_access_handler.cc b/chrome/browser/media/webrtc/display_media_access_handler.cc index c6cb1afb..92e9792 100644 --- a/chrome/browser/media/webrtc/display_media_access_handler.cc +++ b/chrome/browser/media/webrtc/display_media_access_handler.cc
@@ -28,6 +28,7 @@ #include "components/url_formatter/elide_url.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/desktop_capture.h" +#include "content/public/browser/desktop_media_id.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/render_frame_host.h" @@ -44,6 +45,17 @@ #include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h" #endif +namespace { + +// Helper function to get the title of the calling application. +std::u16string GetApplicationTitle(content::WebContents* web_contents) { + return url_formatter::FormatOriginForSecurityDisplay( + web_contents->GetMainFrame()->GetLastCommittedOrigin(), + url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC); +} + +} // namespace + // Holds pending request information so that we display one picker UI at a time // for each content::WebContents. struct DisplayMediaAccessHandler::PendingAccessRequest { @@ -285,9 +297,7 @@ gfx::NativeWindow parent_window = web_contents->GetTopLevelNativeWindow(); picker_params.context = parent_window; picker_params.parent = parent_window; - picker_params.app_name = url_formatter::FormatOriginForSecurityDisplay( - web_contents->GetMainFrame()->GetLastCommittedOrigin(), - url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC); + picker_params.app_name = GetApplicationTitle(web_contents); picker_params.target_name = picker_params.app_name; picker_params.request_audio = pending_request.request.audio_type == @@ -298,9 +308,10 @@ std::move(done_callback)); } -void DisplayMediaAccessHandler::OnPickerDialogResults( +void DisplayMediaAccessHandler::FinalizeResult( content::WebContents* web_contents, - content::DesktopMediaID media_id) { + const content::DesktopMediaID& media_id, + blink::mojom::MediaStreamRequestResult request_result) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(web_contents); @@ -313,62 +324,24 @@ // need to do anything. return; } - PendingAccessRequest& pending_request = *queue.front(); blink::MediaStreamDevices devices; - blink::mojom::MediaStreamRequestResult request_result = - blink::mojom::MediaStreamRequestResult::PERMISSION_DENIED; std::unique_ptr<content::MediaStreamUI> ui; - if (media_id.is_null()) { - request_result = blink::mojom::MediaStreamRequestResult::PERMISSION_DENIED; - } else { - request_result = blink::mojom::MediaStreamRequestResult::OK; -#if defined(OS_MAC) - // Check screen capture permissions on Mac if necessary. - if ((media_id.type == content::DesktopMediaID::TYPE_SCREEN || - media_id.type == content::DesktopMediaID::TYPE_WINDOW) && - system_media_permissions::CheckSystemScreenCapturePermission() != - system_media_permissions::SystemPermission::kAllowed) { - request_result = - blink::mojom::MediaStreamRequestResult::SYSTEM_PERMISSION_DENIED; - } -#endif - if (media_id.type == content::DesktopMediaID::TYPE_WEB_CONTENTS && - !content::WebContents::FromRenderFrameHost( - content::RenderFrameHost::FromID( - media_id.web_contents_id.render_process_id, - media_id.web_contents_id.main_render_frame_id))) { - request_result = - blink::mojom::MediaStreamRequestResult::TAB_CAPTURE_FAILURE; - } -#if BUILDFLAG(IS_CHROMEOS_ASH) - if (request_result == blink::mojom::MediaStreamRequestResult::OK) { - if (policy::DlpContentManager::Get()->IsScreenCaptureRestricted( - media_id)) { - request_result = - blink::mojom::MediaStreamRequestResult::PERMISSION_DENIED; - } - } -#endif - if (request_result == blink::mojom::MediaStreamRequestResult::OK) { - const auto& visible_url = url_formatter::FormatOriginForSecurityDisplay( - web_contents->GetMainFrame()->GetLastCommittedOrigin(), - url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC); - const bool disable_local_echo = - (media_id.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) && - media_id.web_contents_id.disable_local_echo; - ui = GetDevicesForDesktopCapture( - web_contents, - url::Origin::Create(pending_request.request.security_origin), - &devices, media_id, pending_request.request.video_type, - blink::mojom::MediaStreamType::DISPLAY_AUDIO_CAPTURE, - media_id.audio_share, disable_local_echo, display_notification_, - visible_url, visible_url); - } - } - if (request_result == blink::mojom::MediaStreamRequestResult::OK) + if (request_result == blink::mojom::MediaStreamRequestResult::OK) { + const std::u16string application_title = GetApplicationTitle(web_contents); + const bool disable_local_echo = + (media_id.type == content::DesktopMediaID::TYPE_WEB_CONTENTS) && + media_id.web_contents_id.disable_local_echo; + ui = GetDevicesForDesktopCapture( + web_contents, + url::Origin::Create(pending_request.request.security_origin), &devices, + media_id, pending_request.request.video_type, + blink::mojom::MediaStreamType::DISPLAY_AUDIO_CAPTURE, + media_id.audio_share, disable_local_echo, display_notification_, + application_title, application_title); UpdateTarget(pending_request.request, media_id); + } std::move(pending_request.callback) .Run(devices, request_result, std::move(ui)); @@ -378,6 +351,54 @@ ProcessQueuedAccessRequest(queue, web_contents); } +void DisplayMediaAccessHandler::OnPickerDialogResults( + content::WebContents* web_contents, + content::DesktopMediaID media_id) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(web_contents); + + if (media_id.is_null()) { + FinalizeResult(web_contents, media_id, + blink::mojom::MediaStreamRequestResult::PERMISSION_DENIED); + return; + } + + // If the media id is tied to a tab, check that it hasn't been destroyed. + if (media_id.type == content::DesktopMediaID::TYPE_WEB_CONTENTS && + !content::WebContents::FromRenderFrameHost( + content::RenderFrameHost::FromID( + media_id.web_contents_id.render_process_id, + media_id.web_contents_id.main_render_frame_id))) { + FinalizeResult(web_contents, media_id, + blink::mojom::MediaStreamRequestResult::TAB_CAPTURE_FAILURE); + return; + } + +#if defined(OS_MAC) + // Check screen capture permissions on Mac if necessary. + if ((media_id.type == content::DesktopMediaID::TYPE_SCREEN || + media_id.type == content::DesktopMediaID::TYPE_WINDOW) && + system_media_permissions::CheckSystemScreenCapturePermission() != + system_media_permissions::SystemPermission::kAllowed) { + FinalizeResult( + web_contents, media_id, + blink::mojom::MediaStreamRequestResult::SYSTEM_PERMISSION_DENIED); + return; + } +#endif // defined(OS_MAC) + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Check Data Leak Prevention restrictions on Chrome. + policy::DlpContentManager::Get()->CheckScreenShareRestriction( + media_id, GetApplicationTitle(web_contents), + base::BindOnce(&DisplayMediaAccessHandler::OnDlpRestrictionChecked, + base::Unretained(this), web_contents, media_id)); +#else // BUILDFLAG(IS_CHROMEOS_ASH) + FinalizeResult(web_contents, media_id, + blink::mojom::MediaStreamRequestResult::OK); +#endif // !BUILDFLAG(IS_CHROMEOS_ASH) +} + void DisplayMediaAccessHandler::WebContentsDestroyed( content::WebContents* web_contents) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -385,6 +406,19 @@ pending_requests_.erase(web_contents); } +#if BUILDFLAG(IS_CHROMEOS_ASH) +void DisplayMediaAccessHandler::OnDlpRestrictionChecked( + content::WebContents* web_contents, + const content::DesktopMediaID& media_id, + bool is_dlp_allowed) { + blink::mojom::MediaStreamRequestResult result = + is_dlp_allowed + ? blink::mojom::MediaStreamRequestResult::OK + : blink::mojom::MediaStreamRequestResult::PERMISSION_DENIED; + FinalizeResult(web_contents, media_id, result); +} +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + void DisplayMediaAccessHandler::DeletePendingAccessRequest( int render_process_id, int render_frame_id,
diff --git a/chrome/browser/media/webrtc/display_media_access_handler.h b/chrome/browser/media/webrtc/display_media_access_handler.h index 68472da..9c93c6d7 100644 --- a/chrome/browser/media/webrtc/display_media_access_handler.h +++ b/chrome/browser/media/webrtc/display_media_access_handler.h
@@ -15,6 +15,7 @@ #include "chrome/browser/media/webrtc/desktop_media_picker_factory.h" #include "chrome/browser/tab_contents/web_contents_collection.h" #include "content/public/browser/desktop_media_id.h" +#include "content/public/browser/web_contents.h" namespace extensions { class Extension; @@ -63,11 +64,30 @@ base::circular_deque<std::unique_ptr<PendingAccessRequest>>; using RequestsQueues = base::flat_map<content::WebContents*, RequestsQueue>; + // Processes one pending request. Requests are queued so that we display one + // picker UI at a time for each content::WebContents. void ProcessQueuedAccessRequest(const RequestsQueue& queue, content::WebContents* web_contents); + // Processes the first queued access request for |web_contents| + // according to |request_result|. Calls ProcessQueuedAccessRequest if there + // are more requests left in the queue. + void FinalizeResult(content::WebContents* web_contents, + const content::DesktopMediaID& media_id, + blink::mojom::MediaStreamRequestResult request_result); + + // Called back after the user chooses one of the possible desktop media + // sources for the request that's currently being processed. If no |media_id| + // is given, the request was rejected, either by the browser or by the user. void OnPickerDialogResults(content::WebContents* web_contents, - content::DesktopMediaID source); + content::DesktopMediaID media_id); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Called back after checking Data Leak Prevention (DLP) restrictions. + void OnDlpRestrictionChecked(content::WebContents* web_contents, + const content::DesktopMediaID& media_id, + bool is_dlp_allowed); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) void DeletePendingAccessRequest(int render_process_id, int render_frame_id,
diff --git a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc index 0496705..1533060 100644 --- a/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc +++ b/chrome/browser/media/webrtc/display_media_access_handler_unittest.cc
@@ -171,9 +171,13 @@ policy::MockDlpContentManager mock_dlp_content_manager; policy::ScopedDlpContentManagerForTesting scoped_dlp_content_manager_( &mock_dlp_content_manager); - EXPECT_CALL(mock_dlp_content_manager, IsScreenCaptureRestricted(media_id)) - .Times(1) - .WillOnce(testing::Return(true)); + EXPECT_CALL(mock_dlp_content_manager, CheckScreenShareRestriction) + .WillOnce([](const content::DesktopMediaID& media_id, + const std::u16string& application_title, + base::OnceCallback<void(bool)> callback) { + // Disallow + std::move(callback).Run(false); + }); blink::mojom::MediaStreamRequestResult result; blink::MediaStreamDevices devices;
diff --git a/chrome/browser/metrics/metrics_memory_details.cc b/chrome/browser/metrics/metrics_memory_details.cc index 0fc53cd..02637894 100644 --- a/chrome/browser/metrics/metrics_memory_details.cc +++ b/chrome/browser/metrics/metrics_memory_details.cc
@@ -168,21 +168,23 @@ } #endif - UpdateSiteIsolationMetrics(); + size_t initialized_and_not_dead_rphs; + size_t all_rphs; + CountRenderProcessHosts(&initialized_and_not_dead_rphs, &all_rphs); + UpdateSiteIsolationMetrics(initialized_and_not_dead_rphs); UMA_HISTOGRAM_COUNTS_100("Memory.ProcessCount", static_cast<int>(browser.processes.size())); UMA_HISTOGRAM_COUNTS_100("Memory.RendererProcessCount", renderer_count); - size_t initialized_and_not_dead_rphs, all_rphs; - CountRenderProcessHosts(&initialized_and_not_dead_rphs, &all_rphs); UMA_HISTOGRAM_COUNTS_100("Memory.RenderProcessHost.Count.All", all_rphs); UMA_HISTOGRAM_COUNTS_100( "Memory.RenderProcessHost.Count.InitializedAndNotDead", initialized_and_not_dead_rphs); } -void MetricsMemoryDetails::UpdateSiteIsolationMetrics() { +void MetricsMemoryDetails::UpdateSiteIsolationMetrics( + size_t live_process_count) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); // Track site data for predicting process counts with out-of-process iframes. @@ -219,5 +221,5 @@ SiteData& site_data = site_data_map[contents->GetBrowserContext()]; SiteDetails::CollectSiteInfo(contents->GetPrimaryPage(), &site_data); } - SiteDetails::UpdateHistograms(site_data_map); + SiteDetails::UpdateHistograms(site_data_map, live_process_count); }
diff --git a/chrome/browser/metrics/metrics_memory_details.h b/chrome/browser/metrics/metrics_memory_details.h index 18d043f..566c822 100644 --- a/chrome/browser/metrics/metrics_memory_details.h +++ b/chrome/browser/metrics/metrics_memory_details.h
@@ -29,7 +29,7 @@ // Updates the global histograms for tracking memory usage. void UpdateHistograms(); - void UpdateSiteIsolationMetrics(); + void UpdateSiteIsolationMetrics(size_t live_process_count); base::OnceClosure callback_; };
diff --git a/chrome/browser/notifications/arc_application_notifier_controller.cc b/chrome/browser/notifications/arc_application_notifier_controller.cc index be13ee9..7a6940a 100644 --- a/chrome/browser/notifications/arc_application_notifier_controller.cc +++ b/chrome/browser/notifications/arc_application_notifier_controller.cc
@@ -12,6 +12,8 @@ #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/notifications/notifier_dataset.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/chrome_features.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/app_update.h" #include "components/services/app_service/public/cpp/permission_utils.h" #include "components/services/app_service/public/mojom/types.mojom.h" @@ -107,21 +109,29 @@ DCHECK(apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile( last_used_profile_)); - auto icon_type = apps::mojom::IconType::kStandard; - - apps::AppServiceProxyFactory::GetForProfile(last_used_profile_) - ->LoadIcon(apps::mojom::AppType::kArc, app_id, icon_type, - message_center::kQuickSettingIconSizeInDp, - allow_placeholder_icon, - base::BindOnce(&ArcApplicationNotifierController::OnLoadIcon, - weak_ptr_factory_.GetWeakPtr(), app_id)); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + apps::AppServiceProxyFactory::GetForProfile(last_used_profile_) + ->LoadIcon(apps::AppType::kArc, app_id, apps::IconType::kStandard, + message_center::kQuickSettingIconSizeInDp, + allow_placeholder_icon, + base::BindOnce(&ArcApplicationNotifierController::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr(), app_id)); + } else { + apps::AppServiceProxyFactory::GetForProfile(last_used_profile_) + ->LoadIcon(apps::mojom::AppType::kArc, app_id, + apps::mojom::IconType::kStandard, + message_center::kQuickSettingIconSizeInDp, + allow_placeholder_icon, + apps::MojomIconValueToIconValueCallback(base::BindOnce( + &ArcApplicationNotifierController::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr(), app_id))); + } } void ArcApplicationNotifierController::OnLoadIcon( const std::string& app_id, - apps::mojom::IconValuePtr icon_value) { - auto expected_icon_type = apps::mojom::IconType::kStandard; - if (icon_value->icon_type != expected_icon_type) + apps::IconValuePtr icon_value) { + if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) return; SetIcon(app_id, icon_value->uncompressed);
diff --git a/chrome/browser/notifications/arc_application_notifier_controller.h b/chrome/browser/notifications/arc_application_notifier_controller.h index 5273a53..3a193f33 100644 --- a/chrome/browser/notifications/arc_application_notifier_controller.h +++ b/chrome/browser/notifications/arc_application_notifier_controller.h
@@ -12,6 +12,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/notifications/notifier_controller.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" +#include "components/services/app_service/public/cpp/icon_types.h" class AppUpdate; class Profile; @@ -39,8 +40,8 @@ private: void CallLoadIcon(const std::string& app_id, bool allow_placeholder_icon); - void OnLoadIcon(const std::string& app_id, - apps::mojom::IconValuePtr icon_value); + void OnLoadIcon(const std::string& app_id, apps::IconValuePtr icon_value); + void SetIcon(const std::string& app_id, gfx::ImageSkia image); // apps::AppRegistryCache::Observer:
diff --git a/chrome/browser/notifications/pwa_notifier_controller.cc b/chrome/browser/notifications/pwa_notifier_controller.cc index 7ce4f52..0cc5ee7 100644 --- a/chrome/browser/notifications/pwa_notifier_controller.cc +++ b/chrome/browser/notifications/pwa_notifier_controller.cc
@@ -10,6 +10,8 @@ #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/notifications/notifier_dataset.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/chrome_features.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/app_update.h" #include "components/services/app_service/public/cpp/permission_utils.h" #include "components/services/app_service/public/mojom/types.mojom.h" @@ -100,20 +102,28 @@ DCHECK(apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile( observed_profile_)); - auto icon_type = apps::mojom::IconType::kStandard; - - apps::AppServiceProxyFactory::GetForProfile(observed_profile_) - ->LoadIcon(apps::mojom::AppType::kWeb, app_id, icon_type, - message_center::kQuickSettingIconSizeInDp, - allow_placeholder_icon, - base::BindOnce(&PwaNotifierController::OnLoadIcon, - weak_ptr_factory_.GetWeakPtr(), app_id)); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + apps::AppServiceProxyFactory::GetForProfile(observed_profile_) + ->LoadIcon(apps::AppType::kWeb, app_id, apps::IconType::kStandard, + message_center::kQuickSettingIconSizeInDp, + allow_placeholder_icon, + base::BindOnce(&PwaNotifierController::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr(), app_id)); + } else { + apps::AppServiceProxyFactory::GetForProfile(observed_profile_) + ->LoadIcon(apps::mojom::AppType::kWeb, app_id, + apps::mojom::IconType::kStandard, + message_center::kQuickSettingIconSizeInDp, + allow_placeholder_icon, + apps::MojomIconValueToIconValueCallback( + base::BindOnce(&PwaNotifierController::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr(), app_id))); + } } void PwaNotifierController::OnLoadIcon(const std::string& app_id, - apps::mojom::IconValuePtr icon_value) { - auto expected_icon_type = apps::mojom::IconType::kStandard; - if (icon_value->icon_type != expected_icon_type) + apps::IconValuePtr icon_value) { + if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) return; SetIcon(app_id, icon_value->uncompressed);
diff --git a/chrome/browser/notifications/pwa_notifier_controller.h b/chrome/browser/notifications/pwa_notifier_controller.h index e76390f..7c1e9e26 100644 --- a/chrome/browser/notifications/pwa_notifier_controller.h +++ b/chrome/browser/notifications/pwa_notifier_controller.h
@@ -12,6 +12,7 @@ #include "base/memory/weak_ptr.h" #include "chrome/browser/notifications/notifier_controller.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" +#include "components/services/app_service/public/cpp/icon_types.h" class AppUpdate; class Profile; @@ -32,8 +33,8 @@ private: void CallLoadIcon(const std::string& app_id, bool allow_placeholder_icon); - void OnLoadIcon(const std::string& app_id, - apps::mojom::IconValuePtr icon_value); + void OnLoadIcon(const std::string& app_id, apps::IconValuePtr icon_value); + void SetIcon(const std::string& app_id, gfx::ImageSkia image); // apps::AppRegistryCache::Observer:
diff --git a/chrome/browser/password_manager/android/BUILD.gn b/chrome/browser/password_manager/android/BUILD.gn index 2ea549b..08da528 100644 --- a/chrome/browser/password_manager/android/BUILD.gn +++ b/chrome/browser/password_manager/android/BUILD.gn
@@ -188,7 +188,7 @@ "password_generation_controller_impl_unittest.cc", "password_store_android_backend_unittest.cc", "save_password_infobar_delegate_android_unittest.cc", - "save_password_message_delegate_unittest.cc", + "save_update_password_message_delegate_unittest.cc", "update_password_infobar_delegate_android_unittest.cc", ]
diff --git a/chrome/browser/password_manager/android/save_password_message_delegate.cc b/chrome/browser/password_manager/android/save_update_password_message_delegate.cc similarity index 73% rename from chrome/browser/password_manager/android/save_password_message_delegate.cc rename to chrome/browser/password_manager/android/save_update_password_message_delegate.cc index bfafe54..79a86a0 100644 --- a/chrome/browser/password_manager/android/save_password_message_delegate.cc +++ b/chrome/browser/password_manager/android/save_update_password_message_delegate.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/password_manager/android/save_password_message_delegate.h" +#include "chrome/browser/password_manager/android/save_update_password_message_delegate.h" #include "base/callback.h" #include "base/strings/utf_string_conversions.h" @@ -23,19 +23,19 @@ #include "ui/base/l10n/l10n_util.h" #include "url/origin.h" -SavePasswordMessageDelegate::SavePasswordMessageDelegate() - : SavePasswordMessageDelegate( +SaveUpdatePasswordMessageDelegate::SaveUpdatePasswordMessageDelegate() + : SaveUpdatePasswordMessageDelegate( base::BindRepeating(PasswordEditDialogBridge::Create)) {} -SavePasswordMessageDelegate::SavePasswordMessageDelegate( +SaveUpdatePasswordMessageDelegate::SaveUpdatePasswordMessageDelegate( PasswordEditDialogFactory password_edit_dialog_factory) : password_edit_dialog_factory_(std::move(password_edit_dialog_factory)) {} -SavePasswordMessageDelegate::~SavePasswordMessageDelegate() { +SaveUpdatePasswordMessageDelegate::~SaveUpdatePasswordMessageDelegate() { DCHECK(web_contents_ == nullptr); } -void SavePasswordMessageDelegate::DisplaySavePasswordPrompt( +void SaveUpdatePasswordMessageDelegate::DisplaySaveUpdatePasswordPrompt( content::WebContents* web_contents, std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_save, bool update_password) { @@ -47,18 +47,19 @@ absl::optional<AccountInfo> account_info = password_manager::GetAccountInfoForPasswordMessages(profile); - DisplaySavePasswordPromptInternal(web_contents, std::move(form_to_save), - std::move(account_info), update_password); + DisplaySaveUpdatePasswordPromptInternal(web_contents, std::move(form_to_save), + std::move(account_info), + update_password); } -void SavePasswordMessageDelegate::DismissSavePasswordPrompt() { +void SaveUpdatePasswordMessageDelegate::DismissSaveUpdatePasswordPrompt() { if (password_edit_dialog_ != nullptr) { password_edit_dialog_->Dismiss(); } - DismissSavePasswordMessage(messages::DismissReason::UNKNOWN); + DismissSaveUpdatePasswordMessage(messages::DismissReason::UNKNOWN); } -void SavePasswordMessageDelegate::DismissSavePasswordMessage( +void SaveUpdatePasswordMessageDelegate::DismissSaveUpdatePasswordMessage( messages::DismissReason dismiss_reason) { if (message_ != nullptr) { messages::MessageDispatcherBridge::Get()->DismissMessage(message_.get(), @@ -66,13 +67,13 @@ } } -void SavePasswordMessageDelegate::DisplaySavePasswordPromptInternal( +void SaveUpdatePasswordMessageDelegate::DisplaySaveUpdatePasswordPromptInternal( content::WebContents* web_contents, std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_save, absl::optional<AccountInfo> account_info, bool update_password) { // Dismiss previous message if it is displayed. - DismissSavePasswordPrompt(); + DismissSaveUpdatePasswordPrompt(); DCHECK(message_ == nullptr); DCHECK(password_edit_dialog_ == nullptr); @@ -94,35 +95,33 @@ messages::MessagePriority::kNormal); } -void SavePasswordMessageDelegate::CreateMessage(bool update_password) { +void SaveUpdatePasswordMessageDelegate::CreateMessage(bool update_password) { // Binding with base::Unretained(this) is safe here because - // SavePasswordMessageDelegate owns message_. Callbacks won't be called after - // the current object is destroyed. + // SaveUpdatePasswordMessageDelegate owns message_. Callbacks won't be called + // after the current object is destroyed. messages::MessageIdentifier message_id = update_password ? messages::MessageIdentifier::UPDATE_PASSWORD : messages::MessageIdentifier::SAVE_PASSWORD; base::OnceClosure callback = update_password ? base::BindOnce( - &SavePasswordMessageDelegate::HandleUpdateButtonClicked, + &SaveUpdatePasswordMessageDelegate::HandleUpdateButtonClicked, base::Unretained(this)) : base::BindOnce( - &SavePasswordMessageDelegate::HandleSaveButtonClicked, + &SaveUpdatePasswordMessageDelegate::HandleSaveButtonClicked, base::Unretained(this)); message_ = std::make_unique<messages::MessageWrapper>( message_id, std::move(callback), - base::BindOnce(&SavePasswordMessageDelegate::HandleMessageDismissed, + base::BindOnce(&SaveUpdatePasswordMessageDelegate::HandleMessageDismissed, base::Unretained(this))); - if (!update_password) { - // The message duration experiment is controlled by a parameter, associated - // with MessagesForAndroidPasswords feature and thus should only be adjusted - // for save password prompt. - int message_dismiss_duration_ms = - messages::GetSavePasswordMessageDismissDurationMs(); - if (message_dismiss_duration_ms != 0) - message_->SetDuration(message_dismiss_duration_ms); - } + // The message duration experiment is controlled by a parameter, associated + // with MessagesForAndroidPasswords feature and thus should be adjusted for + // both save and update password prompt. + int message_dismiss_duration_ms = + messages::GetSavePasswordMessageDismissDurationMs(); + if (message_dismiss_duration_ms != 0) + message_->SetDuration(message_dismiss_duration_ms); const password_manager::PasswordForm& pending_credentials = passwords_state_.form_manager()->GetPendingCredentials(); @@ -160,6 +159,8 @@ } message_->SetDescription(description); + update_password_ = update_password; + bool use_followup_button_text = false; if (update_password) { std::vector<std::u16string> usernames; @@ -177,13 +178,13 @@ ResourceMapper::MapToJavaDrawableId(IDR_ANDROID_MESSAGE_SETTINGS)); message_->SetSecondaryButtonMenuText( l10n_util::GetStringUTF16(IDS_PASSWORD_MANAGER_BLOCKLIST_BUTTON)); - message_->SetSecondaryActionCallback( - base::BindOnce(&SavePasswordMessageDelegate::HandleNeverSaveClicked, - base::Unretained(this))); + message_->SetSecondaryActionCallback(base::BindOnce( + &SaveUpdatePasswordMessageDelegate::HandleNeverSaveClicked, + base::Unretained(this))); } } -int SavePasswordMessageDelegate::GetPrimaryButtonTextId( +int SaveUpdatePasswordMessageDelegate::GetPrimaryButtonTextId( bool update_password, bool use_followup_button_text) { if (!update_password) @@ -195,7 +196,7 @@ return IDS_PASSWORD_MANAGER_CONTINUE_BUTTON; } -void SavePasswordMessageDelegate::HandleMessageDismissed( +void SaveUpdatePasswordMessageDelegate::HandleMessageDismissed( messages::DismissReason dismiss_reason) { message_.reset(); if (password_edit_dialog_) { @@ -209,16 +210,16 @@ ClearState(); } -void SavePasswordMessageDelegate::HandleSaveButtonClicked() { +void SaveUpdatePasswordMessageDelegate::HandleSaveButtonClicked() { passwords_state_.form_manager()->Save(); } -void SavePasswordMessageDelegate::HandleNeverSaveClicked() { +void SaveUpdatePasswordMessageDelegate::HandleNeverSaveClicked() { passwords_state_.form_manager()->Blocklist(); - DismissSavePasswordMessage(messages::DismissReason::SECONDARY_ACTION); + DismissSaveUpdatePasswordMessage(messages::DismissReason::SECONDARY_ACTION); } -void SavePasswordMessageDelegate::HandleUpdateButtonClicked() { +void SaveUpdatePasswordMessageDelegate::HandleUpdateButtonClicked() { std::vector<std::u16string> usernames; int selected_username_index = GetDisplayUsernames(&usernames); if (usernames.size() > 1) { @@ -228,17 +229,19 @@ } } -void SavePasswordMessageDelegate::DisplayUsernameConfirmDialog( +void SaveUpdatePasswordMessageDelegate::DisplayUsernameConfirmDialog( std::vector<std::u16string> usernames, int selected_username_index) { // Binding with base::Unretained(this) is safe here because - // SavePasswordMessageDelegate owns password_edit_dialog_. Callbacks won't be - // called after the SavePasswordMessageDelegate object is destroyed. + // SaveUpdatePasswordMessageDelegate owns password_edit_dialog_. Callbacks + // won't be called after the SaveUpdatePasswordMessageDelegate object is + // destroyed. password_edit_dialog_ = password_edit_dialog_factory_.Run( web_contents_, - base::BindOnce(&SavePasswordMessageDelegate::HandleSavePasswordFromDialog, - base::Unretained(this)), - base::BindOnce(&SavePasswordMessageDelegate::HandleDialogDismissed, + base::BindOnce( + &SaveUpdatePasswordMessageDelegate::HandleSavePasswordFromDialog, + base::Unretained(this)), + base::BindOnce(&SaveUpdatePasswordMessageDelegate::HandleDialogDismissed, base::Unretained(this))); // Password edit dialog factory method can return nullptr when web_contents @@ -255,7 +258,7 @@ origin, std::string()); } -unsigned int SavePasswordMessageDelegate::GetDisplayUsernames( +unsigned int SaveUpdatePasswordMessageDelegate::GetDisplayUsernames( std::vector<std::u16string>* usernames) { unsigned int selected_username_index = 0; // TODO(crbug.com/1054410): Fix the update logic to use all best matches, @@ -281,7 +284,8 @@ return selected_username_index; } -void SavePasswordMessageDelegate::HandleDialogDismissed(bool dialogAccepted) { +void SaveUpdatePasswordMessageDelegate::HandleDialogDismissed( + bool dialogAccepted) { password_edit_dialog_.reset(); RecordDismissalReasonMetrics( dialogAccepted ? password_manager::metrics_util::CLICKED_ACCEPT @@ -289,7 +293,7 @@ ClearState(); } -void SavePasswordMessageDelegate::HandleSavePasswordFromDialog( +void SaveUpdatePasswordMessageDelegate::HandleSavePasswordFromDialog( int selected_username_index) { if (passwords_state_.GetCurrentForms().size() > 1) { UpdatePasswordFormUsernameAndPassword( @@ -301,17 +305,17 @@ passwords_state_.form_manager()->Save(); } -void SavePasswordMessageDelegate::ClearState() { +void SaveUpdatePasswordMessageDelegate::ClearState() { DCHECK(message_ == nullptr); DCHECK(password_edit_dialog_ == nullptr); passwords_state_.OnInactive(); - // web_contents_ is set in DisplaySavePasswordPromptInternal(). Resetting it - // here to keep the state clean when no message is enqueued. + // web_contents_ is set in DisplaySaveUpdatePasswordPromptInternal(). + // Resetting it here to keep the state clean when no message is enqueued. web_contents_ = nullptr; } -void SavePasswordMessageDelegate::RecordMessageShownMetrics() { +void SaveUpdatePasswordMessageDelegate::RecordMessageShownMetrics() { if (auto* recorder = passwords_state_.form_manager()->GetMetricsRecorder()) { recorder->RecordPasswordBubbleShown( passwords_state_.form_manager()->GetCredentialSource(), @@ -319,16 +323,21 @@ } } -void SavePasswordMessageDelegate::RecordDismissalReasonMetrics( +void SaveUpdatePasswordMessageDelegate::RecordDismissalReasonMetrics( password_manager::metrics_util::UIDismissalReason ui_dismissal_reason) { auto submission_event = passwords_state_.form_manager()->GetPendingCredentials().submission_event; - password_manager::metrics_util::LogSaveUIDismissalReason( - ui_dismissal_reason, submission_event, - /*user_state=*/absl::nullopt); - if (passwords_state_.form_manager()->WasUnblocklisted()) { - password_manager::metrics_util::LogSaveUIDismissalReasonAfterUnblocklisting( - ui_dismissal_reason); + if (update_password_) { + password_manager::metrics_util::LogUpdateUIDismissalReason( + ui_dismissal_reason, submission_event); + } else { + password_manager::metrics_util::LogSaveUIDismissalReason( + ui_dismissal_reason, submission_event, + /*user_state=*/absl::nullopt); + if (passwords_state_.form_manager()->WasUnblocklisted()) { + password_manager::metrics_util:: + LogSaveUIDismissalReasonAfterUnblocklisting(ui_dismissal_reason); + } } if (auto* recorder = passwords_state_.form_manager()->GetMetricsRecorder()) { recorder->RecordUIDismissalReason(ui_dismissal_reason); @@ -336,7 +345,8 @@ } // static -password_manager::metrics_util::UIDismissalReason SavePasswordMessageDelegate:: +password_manager::metrics_util::UIDismissalReason +SaveUpdatePasswordMessageDelegate:: MessageDismissReasonToPasswordManagerUIDismissalReason( messages::DismissReason dismiss_reason) { password_manager::metrics_util::UIDismissalReason ui_dismissal_reason;
diff --git a/chrome/browser/password_manager/android/save_password_message_delegate.h b/chrome/browser/password_manager/android/save_update_password_message_delegate.h similarity index 79% rename from chrome/browser/password_manager/android/save_password_message_delegate.h rename to chrome/browser/password_manager/android/save_update_password_message_delegate.h index 5bc9e1e7..a02c023f 100644 --- a/chrome/browser/password_manager/android/save_password_message_delegate.h +++ b/chrome/browser/password_manager/android/save_update_password_message_delegate.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_SAVE_PASSWORD_MESSAGE_DELEGATE_H_ -#define CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_SAVE_PASSWORD_MESSAGE_DELEGATE_H_ +#ifndef CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_SAVE_UPDATE_PASSWORD_MESSAGE_DELEGATE_H_ +#define CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_SAVE_UPDATE_PASSWORD_MESSAGE_DELEGATE_H_ #include <memory> @@ -22,10 +22,11 @@ } // namespace content // This class provides simplified interface for ChromePasswordManagerClient to -// display a prompt to save password through Messages API. The class is -// responsible for populating message properties, managing message's lifetime, -// saving password form in response to user interactions and recording metrics. -class SavePasswordMessageDelegate { +// display a prompt to save and update password through Messages API. The class +// is responsible for populating message properties, managing message's +// lifetime, saving password form in response to user interactions and recording +// metrics. +class SaveUpdatePasswordMessageDelegate { public: using PasswordEditDialogFactory = base::RepeatingCallback<std::unique_ptr<PasswordEditDialog>( @@ -33,12 +34,12 @@ PasswordEditDialog::DialogAcceptedCallback, PasswordEditDialog::DialogDismissedCallback)>; - SavePasswordMessageDelegate(); - ~SavePasswordMessageDelegate(); + SaveUpdatePasswordMessageDelegate(); + ~SaveUpdatePasswordMessageDelegate(); // Displays a "Save password" message for current |web_contents| and // |form_to_save|. - void DisplaySavePasswordPrompt( + void DisplaySaveUpdatePasswordPrompt( content::WebContents* web_contents, std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_save, bool update_password); @@ -46,17 +47,17 @@ // Dismisses currently displayed message or dialog. Because the implementation // uses some of the dependencies (e.g. log manager) this method needs to be // called before the object is destroyed. - void DismissSavePasswordPrompt(); + void DismissSaveUpdatePasswordPrompt(); private: - friend class SavePasswordMessageDelegateTest; + friend class SaveUpdatePasswordMessageDelegateTest; - SavePasswordMessageDelegate( + SaveUpdatePasswordMessageDelegate( PasswordEditDialogFactory password_edit_dialog_factory); - void DismissSavePasswordMessage(messages::DismissReason dismiss_reason); + void DismissSaveUpdatePasswordMessage(messages::DismissReason dismiss_reason); - void DisplaySavePasswordPromptInternal( + void DisplaySaveUpdatePasswordPromptInternal( content::WebContents* web_contents, std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_save, absl::optional<AccountInfo> account_info, @@ -98,6 +99,7 @@ content::WebContents* web_contents_ = nullptr; std::string account_email_; + bool update_password_ = false; // ManagePasswordsState maintains the password form that is being // saved/updated. It provides helper functions for populating username list. @@ -107,4 +109,4 @@ std::unique_ptr<PasswordEditDialog> password_edit_dialog_; }; -#endif // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_SAVE_PASSWORD_MESSAGE_DELEGATE_H_ +#endif // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_SAVE_UPDATE_PASSWORD_MESSAGE_DELEGATE_H_
diff --git a/chrome/browser/password_manager/android/save_password_message_delegate_unittest.cc b/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc similarity index 86% rename from chrome/browser/password_manager/android/save_password_message_delegate_unittest.cc rename to chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc index 18313e3..db9ac33 100644 --- a/chrome/browser/password_manager/android/save_password_message_delegate_unittest.cc +++ b/chrome/browser/password_manager/android/save_update_password_message_delegate_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/password_manager/android/save_password_message_delegate.h" +#include "chrome/browser/password_manager/android/save_update_password_message_delegate.h" #include "base/android/jni_android.h" #include "base/memory/ptr_util.h" @@ -42,8 +42,10 @@ constexpr char16_t kPassword[] = u"password"; constexpr char kAccountEmail[] = "account@example.com"; constexpr char16_t kAccountEmail16[] = u"account@example.com"; -constexpr char kDismissalReasonHistogramName[] = +constexpr char kSaveUIDismissalReasonHistogramName[] = "PasswordManager.SaveUIDismissalReason"; +constexpr char kUpdateUIDismissalReasonHistogramName[] = + "PasswordManager.UpdateUIDismissalReason"; } // namespace class MockPasswordEditDialog : public PasswordEditDialog { @@ -59,9 +61,10 @@ MOCK_METHOD(void, Dismiss, (), (override)); }; -class SavePasswordMessageDelegateTest : public ChromeRenderViewHostTestHarness { +class SaveUpdatePasswordMessageDelegateTest + : public ChromeRenderViewHostTestHarness { public: - SavePasswordMessageDelegateTest(); + SaveUpdatePasswordMessageDelegateTest(); protected: void SetUp() override; @@ -87,7 +90,7 @@ messages::MessageWrapper* GetMessageWrapper(); // Password edit dialog factory function that is passed to - // SavePasswordMessageDelegate. Passes the dialog prepared by + // SaveUpdatePasswordMessageDelegate. Passes the dialog prepared by // PreparePasswordEditDialog. Captures accept and dismiss callbacks. std::unique_ptr<PasswordEditDialog> CreatePasswordEditDialog( content::WebContents* web_contents, @@ -95,7 +98,7 @@ PasswordEditDialog::DialogDismissedCallback dialog_dismissed_callback); // Creates a mock of PasswordEditDialog that will be passed to - // SavePasswordMessageDelegate through CreatePasswordEditDialog factory. + // SaveUpdatePasswordMessageDelegate through CreatePasswordEditDialog factory. // Returns non-owning pointer to the mock for test to configure mock // expectations. MockPasswordEditDialog* PreparePasswordEditDialog(); @@ -128,7 +131,7 @@ &kPasswordForm1, &kPasswordForm2}; PasswordForm pending_credentials_; - std::unique_ptr<SavePasswordMessageDelegate> delegate_; + std::unique_ptr<SaveUpdatePasswordMessageDelegate> delegate_; GURL password_form_url_; scoped_refptr<PasswordFormMetricsRecorder> metrics_recorder_; ukm::SourceId ukm_source_id_; @@ -138,13 +141,13 @@ PasswordEditDialog::DialogDismissedCallback dialog_dismissed_callback_; }; -SavePasswordMessageDelegateTest::SavePasswordMessageDelegateTest() - : delegate_( - base::WrapUnique(new SavePasswordMessageDelegate(base::BindRepeating( - &SavePasswordMessageDelegateTest::CreatePasswordEditDialog, +SaveUpdatePasswordMessageDelegateTest::SaveUpdatePasswordMessageDelegateTest() + : delegate_(base::WrapUnique( + new SaveUpdatePasswordMessageDelegate(base::BindRepeating( + &SaveUpdatePasswordMessageDelegateTest::CreatePasswordEditDialog, base::Unretained(this))))) {} -void SavePasswordMessageDelegateTest::SetUp() { +void SaveUpdatePasswordMessageDelegateTest::SetUp() { ChromeRenderViewHostTestHarness::SetUp(); ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient( web_contents(), nullptr); @@ -157,13 +160,13 @@ &message_dispatcher_bridge_); } -void SavePasswordMessageDelegateTest::TearDown() { +void SaveUpdatePasswordMessageDelegateTest::TearDown() { messages::MessageDispatcherBridge::SetInstanceForTesting(nullptr); ChromeRenderViewHostTestHarness::TearDown(); } std::unique_ptr<MockPasswordFormManagerForUI> -SavePasswordMessageDelegateTest::CreateFormManager( +SaveUpdatePasswordMessageDelegateTest::CreateFormManager( const GURL& password_form_url, const std::vector<const PasswordForm*>* best_matches) { password_form_url_ = password_form_url; @@ -185,7 +188,7 @@ return form_manager; } -void SavePasswordMessageDelegateTest::SetPendingCredentials( +void SaveUpdatePasswordMessageDelegateTest::SetPendingCredentials( std::u16string username, std::u16string password) { pending_credentials_.username_value = std::move(username); @@ -193,7 +196,7 @@ } // static -PasswordForm SavePasswordMessageDelegateTest::CreatePasswordForm( +PasswordForm SaveUpdatePasswordMessageDelegateTest::CreatePasswordForm( std::u16string username, std::u16string password) { PasswordForm password_form; @@ -202,7 +205,7 @@ return password_form; } -void SavePasswordMessageDelegateTest::EnqueueMessage( +void SaveUpdatePasswordMessageDelegateTest::EnqueueMessage( std::unique_ptr<PasswordFormManagerForUI> form_to_save, bool user_signed_in, bool update_password) { @@ -212,22 +215,22 @@ account_info.value().email = kAccountEmail; } EXPECT_CALL(message_dispatcher_bridge_, EnqueueMessage); - delegate_->DisplaySavePasswordPromptInternal( + delegate_->DisplaySaveUpdatePasswordPromptInternal( web_contents(), std::move(form_to_save), account_info, update_password); } -void SavePasswordMessageDelegateTest::TriggerActionClick() { +void SaveUpdatePasswordMessageDelegateTest::TriggerActionClick() { GetMessageWrapper()->HandleActionClick(base::android::AttachCurrentThread()); // Simulate call from Java to dismiss message on primary button click. DismissMessage(messages::DismissReason::PRIMARY_ACTION); } -void SavePasswordMessageDelegateTest::TriggerPasswordEditDialog() { +void SaveUpdatePasswordMessageDelegateTest::TriggerPasswordEditDialog() { GetMessageWrapper()->HandleSecondaryActionClick( base::android::AttachCurrentThread()); } -void SavePasswordMessageDelegateTest::ExpectDismissMessageCall() { +void SaveUpdatePasswordMessageDelegateTest::ExpectDismissMessageCall() { EXPECT_CALL(message_dispatcher_bridge_, DismissMessage) .WillOnce([](messages::MessageWrapper* message, messages::DismissReason dismiss_reason) { @@ -236,23 +239,24 @@ }); } -void SavePasswordMessageDelegateTest::DismissMessage( +void SaveUpdatePasswordMessageDelegateTest::DismissMessage( messages::DismissReason dismiss_reason) { ExpectDismissMessageCall(); - delegate_->DismissSavePasswordMessage(dismiss_reason); + delegate_->DismissSaveUpdatePasswordMessage(dismiss_reason); EXPECT_EQ(nullptr, GetMessageWrapper()); } -void SavePasswordMessageDelegateTest::DestroyDelegate() { +void SaveUpdatePasswordMessageDelegateTest::DestroyDelegate() { delegate_.reset(); } -messages::MessageWrapper* SavePasswordMessageDelegateTest::GetMessageWrapper() { +messages::MessageWrapper* +SaveUpdatePasswordMessageDelegateTest::GetMessageWrapper() { return delegate_->message_.get(); } std::unique_ptr<PasswordEditDialog> -SavePasswordMessageDelegateTest::CreatePasswordEditDialog( +SaveUpdatePasswordMessageDelegateTest::CreatePasswordEditDialog( content::WebContents* web_contents, PasswordEditDialog::DialogAcceptedCallback dialog_accepted_callback, PasswordEditDialog::DialogDismissedCallback dialog_dismissed_callback) { @@ -262,26 +266,26 @@ } MockPasswordEditDialog* -SavePasswordMessageDelegateTest::PreparePasswordEditDialog() { +SaveUpdatePasswordMessageDelegateTest::PreparePasswordEditDialog() { mock_password_edit_dialog_ = std::make_unique<MockPasswordEditDialog>(); return mock_password_edit_dialog_.get(); } -void SavePasswordMessageDelegateTest::TriggerDialogAcceptedCallback( +void SaveUpdatePasswordMessageDelegateTest::TriggerDialogAcceptedCallback( int selected_username_index) { std::move(dialog_accepted_callback_).Run(selected_username_index); } -void SavePasswordMessageDelegateTest::TriggerDialogDismissedCallback( +void SaveUpdatePasswordMessageDelegateTest::TriggerDialogDismissedCallback( bool dialog_accepted) { std::move(dialog_dismissed_callback_).Run(dialog_accepted); } -void SavePasswordMessageDelegateTest::CommitPasswordFormMetrics() { +void SaveUpdatePasswordMessageDelegateTest::CommitPasswordFormMetrics() { // PasswordFormMetricsRecorder::dtor commits accumulated metrics. metrics_recorder_.reset(); } -void SavePasswordMessageDelegateTest::VerifyUkmMetrics( +void SaveUpdatePasswordMessageDelegateTest::VerifyUkmMetrics( const ukm::TestUkmRecorder& ukm_recorder, PasswordFormMetricsRecorder::BubbleDismissalReason expected_dismissal_reason) { @@ -304,7 +308,8 @@ // Tests that message properties (title, description, icon, button text) are // set correctly for save password message. -TEST_F(SavePasswordMessageDelegateTest, MessagePropertyValues_SavePassword) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, + MessagePropertyValues_SavePassword) { SetPendingCredentials(kUsername, kPassword); auto form_manager = CreateFormManager(GURL(kDefaultUrl), empty_best_matches()); @@ -335,7 +340,8 @@ // Tests that message properties (title, description, icon, button text) are // set correctly for update password message. -TEST_F(SavePasswordMessageDelegateTest, MessagePropertyValues_UpdatePassword) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, + MessagePropertyValues_UpdatePassword) { SetPendingCredentials(kUsername, kPassword); auto form_manager = CreateFormManager(GURL(kDefaultUrl), empty_best_matches()); @@ -355,7 +361,8 @@ // Tests that the description is set correctly when signed-in user saves a // password. -TEST_F(SavePasswordMessageDelegateTest, SignedInDescription_SavePassword) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, + SignedInDescription_SavePassword) { SetPendingCredentials(kUsername, kPassword); auto form_manager = CreateFormManager(GURL(kDefaultUrl), empty_best_matches()); @@ -374,7 +381,8 @@ // Tests that the description is set correctly when signed-in user updates a // password. -TEST_F(SavePasswordMessageDelegateTest, SignedInDescription_UpdatePassword) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, + SignedInDescription_UpdatePassword) { SetPendingCredentials(kUsername, kPassword); auto form_manager = CreateFormManager(GURL(kDefaultUrl), empty_best_matches()); @@ -392,7 +400,7 @@ } // Tests that the previous prompt gets dismissed when the new one is enqueued. -TEST_F(SavePasswordMessageDelegateTest, OnlyOnePromptAtATime) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, OnlyOnePromptAtATime) { SetPendingCredentials(kUsername, kPassword); auto form_manager = CreateFormManager(GURL(kDefaultUrl), empty_best_matches()); @@ -409,7 +417,7 @@ // Tests that password form is saved and metrics recorded correctly when the // user clicks "Save" button. -TEST_F(SavePasswordMessageDelegateTest, SaveOnActionClick) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, SaveOnActionClick) { base::HistogramTester histogram_tester; ukm::TestAutoSetUkmRecorder test_ukm_recorder; @@ -427,13 +435,13 @@ test_ukm_recorder, PasswordFormMetricsRecorder::BubbleDismissalReason::kAccepted); histogram_tester.ExpectUniqueSample( - kDismissalReasonHistogramName, + kSaveUIDismissalReasonHistogramName, password_manager::metrics_util::CLICKED_ACCEPT, 1); } // Tests that password form is not saved and metrics recorded correctly when the // user dismisses the message. -TEST_F(SavePasswordMessageDelegateTest, DontSaveOnDismiss) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, DontSaveOnDismiss) { base::HistogramTester histogram_tester; ukm::TestAutoSetUkmRecorder test_ukm_recorder; @@ -451,13 +459,13 @@ test_ukm_recorder, PasswordFormMetricsRecorder::BubbleDismissalReason::kDeclined); histogram_tester.ExpectUniqueSample( - kDismissalReasonHistogramName, + kSaveUIDismissalReasonHistogramName, password_manager::metrics_util::CLICKED_CANCEL, 1); } // Tests that password form is not saved and metrics recorded correctly when the // message is autodismissed. -TEST_F(SavePasswordMessageDelegateTest, MetricOnAutodismissTimer) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, MetricOnAutodismissTimer) { base::HistogramTester histogram_tester; ukm::TestAutoSetUkmRecorder test_ukm_recorder; @@ -475,13 +483,13 @@ test_ukm_recorder, PasswordFormMetricsRecorder::BubbleDismissalReason::kIgnored); histogram_tester.ExpectUniqueSample( - kDismissalReasonHistogramName, + kSaveUIDismissalReasonHistogramName, password_manager::metrics_util::NO_DIRECT_INTERACTION, 1); } // Tests that update password message with a single PasswordForm immediately // saves the form on Update button tap and doesn't display confirmation dialog. -TEST_F(SavePasswordMessageDelegateTest, UpdatePasswordWithSingleForm) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, UpdatePasswordWithSingleForm) { base::HistogramTester histogram_tester; ukm::TestAutoSetUkmRecorder test_ukm_recorder; @@ -502,11 +510,11 @@ test_ukm_recorder, PasswordFormMetricsRecorder::BubbleDismissalReason::kAccepted); histogram_tester.ExpectUniqueSample( - kDismissalReasonHistogramName, + kUpdateUIDismissalReasonHistogramName, password_manager::metrics_util::CLICKED_ACCEPT, 1); } -TEST_F(SavePasswordMessageDelegateTest, DialogProperties) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, DialogProperties) { SetPendingCredentials(kUsername, kPassword); auto form_manager = CreateFormManager(GURL(kDefaultUrl), two_forms_best_matches()); @@ -524,7 +532,7 @@ // Tests triggering password edit dialog and saving credentials after the // user accepts the dialog. -TEST_F(SavePasswordMessageDelegateTest, TriggerEditDialog_Accept) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, TriggerEditDialog_Accept) { base::HistogramTester histogram_tester; ukm::TestAutoSetUkmRecorder test_ukm_recorder; @@ -546,13 +554,13 @@ test_ukm_recorder, PasswordFormMetricsRecorder::BubbleDismissalReason::kAccepted); histogram_tester.ExpectUniqueSample( - kDismissalReasonHistogramName, + kUpdateUIDismissalReasonHistogramName, password_manager::metrics_util::CLICKED_ACCEPT, 1); } // Tests that credentials are not saved if the user cancels password edit // dialog. -TEST_F(SavePasswordMessageDelegateTest, TriggerEditDialog_Cancel) { +TEST_F(SaveUpdatePasswordMessageDelegateTest, TriggerEditDialog_Cancel) { base::HistogramTester histogram_tester; ukm::TestAutoSetUkmRecorder test_ukm_recorder; @@ -573,6 +581,6 @@ test_ukm_recorder, PasswordFormMetricsRecorder::BubbleDismissalReason::kDeclined); histogram_tester.ExpectUniqueSample( - kDismissalReasonHistogramName, + kUpdateUIDismissalReasonHistogramName, password_manager::metrics_util::CLICKED_CANCEL, 1); }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index e3dcdcc..63e4f91 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -327,7 +327,7 @@ if (update_password) { if (messages::IsUpdatePasswordMessagesUiEnabled()) { - save_password_message_delegate_.DisplaySavePasswordPrompt( + save_update_password_message_delegate_.DisplaySaveUpdatePasswordPrompt( web_contents(), std::move(form_to_save), /*update_password=*/true); } else { UpdatePasswordInfoBarDelegate::Create(web_contents(), @@ -335,7 +335,7 @@ } } else { if (messages::IsPasswordMessagesUiEnabled()) { - save_password_message_delegate_.DisplaySavePasswordPrompt( + save_update_password_message_delegate_.DisplaySaveUpdatePasswordPrompt( web_contents(), std::move(form_to_save), /*update_password=*/false); } else { SavePasswordInfoBarDelegate::Create(web_contents(), @@ -604,7 +604,7 @@ } if (messages::IsPasswordMessagesUiEnabled()) { - save_password_message_delegate_.DismissSavePasswordPrompt(); + save_update_password_message_delegate_.DismissSaveUpdatePasswordPrompt(); } else { HideSavePasswordInfobar(web_contents()); } @@ -1327,7 +1327,7 @@ } #if defined(OS_ANDROID) - save_password_message_delegate_.DismissSavePasswordPrompt(); + save_update_password_message_delegate_.DismissSaveUpdatePasswordPrompt(); #endif }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h index 3544f89..8db480e 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.h +++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -46,7 +46,7 @@ #if defined(OS_ANDROID) #include "chrome/browser/password_manager/android/generated_password_saved_message_delegate.h" -#include "chrome/browser/password_manager/android/save_password_message_delegate.h" +#include "chrome/browser/password_manager/android/save_update_password_message_delegate.h" #include "components/password_manager/core/browser/credential_cache.h" class PasswordAccessoryController; @@ -381,7 +381,7 @@ // reset when ime finish composing text event is triggered. std::u16string last_composing_text_; - SavePasswordMessageDelegate save_password_message_delegate_; + SaveUpdatePasswordMessageDelegate save_update_password_message_delegate_; GeneratedPasswordSavedMessageDelegate generated_password_saved_message_delegate_; #endif // defined(OS_ANDROID)
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index ca33bc3..25f0935 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -2249,6 +2249,7 @@ EXPECT_EQ(pdf_frames[0]->GetLastCommittedOrigin(), iframe->GetLastCommittedOrigin()); EXPECT_NE(pdf_frames[0]->GetProcess(), iframe->GetProcess()); + EXPECT_FALSE(content::HasOriginKeyedProcess(pdf_frames[0])); } IN_PROC_BROWSER_TEST_P(PDFExtensionIsolatedContentTest, DataNavigation) {
diff --git a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h index 8df4607..00f24eb 100644 --- a/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h +++ b/chrome/browser/policy/messaging_layer/upload/dm_server_upload_service.h
@@ -28,7 +28,7 @@ namespace reporting { // DmServerUploadService uploads events to the DMServer. It does not manage -// sequencing information, instead reporting the highest sequencing id for each +// sequence information, instead reporting the highest sequencing id for each // generation id and priority. // // DmServerUploadService relies on DmServerUploader for uploading. A @@ -39,7 +39,7 @@ class DmServerUploadService { public: // ReportSuccessfulUploadCallback is used to pass server responses back to - // the owner of |this| (the respone consists of sequencing information and + // the owner of |this| (the respone consists of sequence information and // force_confirm flag). using ReportSuccessfulUploadCallback = base::RepeatingCallback<void(SequenceInformation, @@ -50,7 +50,7 @@ using EncryptionKeyAttachedCallback = base::RepeatingCallback<void(SignedEncryptionInfo)>; - // Successful response consists of Sequencing information that may be + // Successful response consists of Sequence information that may be // accompanied with force_confirm flag. struct SuccessfulUploadResponse { SequenceInformation sequence_information;
diff --git a/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc b/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc index e282ff7..8783924 100644 --- a/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc +++ b/chrome/browser/policy/messaging_layer/upload/record_handler_impl_unittest.cc
@@ -68,10 +68,10 @@ // Helper function for retrieving and processing the SequenceInformation from // a request. void RetrieveFinalSequenceInformation(const base::Value& request, - base::Value& sequencing_info) { + base::Value& sequence_info) { ASSERT_TRUE(request.is_dict()); - // Retrieve and process sequencing information + // Retrieve and process sequence information const base::Value* const encrypted_record_list = request.FindListKey("encryptedRecord"); ASSERT_TRUE(encrypted_record_list != nullptr); @@ -83,26 +83,18 @@ ASSERT_TRUE(!seq_info->FindStringKey("sequencingId")->empty()); ASSERT_TRUE(!seq_info->FindStringKey("generationId")->empty()); ASSERT_TRUE(seq_info->FindIntKey("priority")); - // For backwards compatibility, we must also have unsigned sequencing info. - const auto* const unsigned_seq_info = - encrypted_record_list->GetList().rbegin()->FindDictKey( - "sequencingInformation"); - ASSERT_TRUE(unsigned_seq_info != nullptr); - ASSERT_TRUE(!unsigned_seq_info->FindStringKey("sequencingId")->empty()); - ASSERT_TRUE(!unsigned_seq_info->FindStringKey("generationId")->empty()); - ASSERT_TRUE(unsigned_seq_info->FindIntKey("priority")); + sequence_info.MergeDictionary(seq_info); - sequencing_info.MergeDictionary(seq_info); - // Set half of sequencing information to return a string instead of an int for + // Set half of sequence information to return a string instead of an int for // priority. int64_t sequencing_id; - ASSERT_TRUE(base::StringToInt64( - *sequencing_info.FindStringKey("sequencingId"), &sequencing_id)); + ASSERT_TRUE(base::StringToInt64(*sequence_info.FindStringKey("sequencingId"), + &sequencing_id)); if (sequencing_id % 2) { - const auto int_result = sequencing_info.FindIntKey("priority"); + const auto int_result = sequence_info.FindIntKey("priority"); ASSERT_TRUE(int_result.has_value()); - sequencing_info.RemoveKey("priority"); - sequencing_info.SetStringKey("priority", Priority_Name(int_result.value())); + sequence_info.RemoveKey("priority"); + sequence_info.SetStringKey("priority", Priority_Name(int_result.value())); } } @@ -133,8 +125,8 @@ void SucceedResponseFromRequestHelper(const base::Value& request, bool force_confirm_by_server, base::Value& response, - base::Value& sequencing_info) { - RetrieveFinalSequenceInformation(request, sequencing_info); + base::Value& sequence_info) { + RetrieveFinalSequenceInformation(request, sequence_info); // If force_confirm is true, process that. if (force_confirm_by_server) { @@ -152,33 +144,33 @@ void SucceedResponseFromRequest(const base::Value& request, bool force_confirm_by_server, base::Value& response) { - base::Value sequencing_info{base::Value::Type::DICTIONARY}; + base::Value sequence_info{base::Value::Type::DICTIONARY}; SucceedResponseFromRequestHelper(request, force_confirm_by_server, response, - sequencing_info); - response.SetPath("lastSucceedUploadedRecord", std::move(sequencing_info)); + sequence_info); + response.SetPath("lastSucceedUploadedRecord", std::move(sequence_info)); } void SucceedResponseFromRequestMissingPriority(const base::Value& request, bool force_confirm_by_server, base::Value& response) { - base::Value sequencing_info{base::Value::Type::DICTIONARY}; + base::Value sequence_info{base::Value::Type::DICTIONARY}; SucceedResponseFromRequestHelper(request, force_confirm_by_server, response, - sequencing_info); + sequence_info); // Remove priority field. - sequencing_info.RemoveKey("priority"); - response.SetPath("lastSucceedUploadedRecord", std::move(sequencing_info)); + sequence_info.RemoveKey("priority"); + response.SetPath("lastSucceedUploadedRecord", std::move(sequence_info)); } void SucceedResponseFromRequestInvalidPriority(const base::Value& request, bool force_confirm_by_server, base::Value& response) { - base::Value sequencing_info{base::Value::Type::DICTIONARY}; + base::Value sequence_info{base::Value::Type::DICTIONARY}; SucceedResponseFromRequestHelper(request, force_confirm_by_server, response, - sequencing_info); - sequencing_info.RemoveKey("priority"); + sequence_info); + sequence_info.RemoveKey("priority"); // Set priority field to an invalid value. - sequencing_info.SetStringKey("priority", "abc"); - response.SetPath("lastSucceedUploadedRecord", std::move(sequencing_info)); + sequence_info.SetStringKey("priority", "abc"); + response.SetPath("lastSucceedUploadedRecord", std::move(sequence_info)); } // Immitates the server response for failed record upload. Since additional @@ -191,8 +183,8 @@ response.SetPath("lastSucceedUploadedRecord", seq_info.Clone()); // The lastSucceedUploadedRecord should be the record before the one indicated - // in seq_info. |seq_info| has been built by - // RetrieveFinalSequencingInforamation and is guaranteed to have this key. + // in seq_info. |seq_info| has been built by RetrieveFinalSequenceInforamation + // and is guaranteed to have this key. int64_t sequencing_id; ASSERT_TRUE(base::StringToInt64(*seq_info.FindStringKey("sequencingId"), &sequencing_id));
diff --git a/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.cc b/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.cc index 81a289592..a4592a8 100644 --- a/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.cc +++ b/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.cc
@@ -46,7 +46,6 @@ // EncrypedRecordDictionaryBuilder strings constexpr char kEncryptedWrappedRecord[] = "encryptedWrappedRecord"; -constexpr char kUnsignedSequenceInformationKey[] = "sequencingInformation"; constexpr char kSequenceInformationKey[] = "sequenceInformation"; constexpr char kEncryptionInfoKey[] = "encryptionInfo"; constexpr char kCompressionInformationKey[] = "compressionInformation"; @@ -125,7 +124,7 @@ EncryptedRecord record) { base::Value record_dictionary{base::Value::Type::DICTIONARY}; - // A record without sequencing information cannot be uploaded - deny it. + // A record without sequence information cannot be uploaded - deny it. if (!record.has_sequence_information()) { return; } @@ -139,19 +138,6 @@ } record_dictionary.SetKey(GetSequenceInformationKeyPath(), std::move(sequence_information_result.value())); - // For backwards compatibility, store unsigned sequencing information too. - // The values are non-negative anyway, so the same builder can be used. - auto unsigned_sequence_information_result = - SequenceInformationDictionaryBuilder(record.sequence_information()) - .Build(); - if (!unsigned_sequence_information_result.has_value()) { - // Sequencing information was improperly configured. Record cannot be - // uploaded. Deny it. - return; - } - record_dictionary.SetKey( - GetUnsignedSequenceInformationKeyPath(), - std::move(unsigned_sequence_information_result.value())); // Encryption information can be missing until we set up encryption as // mandatory. @@ -207,12 +193,6 @@ // static base::StringPiece -EncryptedRecordDictionaryBuilder::GetUnsignedSequenceInformationKeyPath() { - return kUnsignedSequenceInformationKey; -} - -// static -base::StringPiece EncryptedRecordDictionaryBuilder::GetSequenceInformationKeyPath() { return kSequenceInformationKey; } @@ -237,16 +217,16 @@ return; } - base::Value sequencing_dictionary{base::Value::Type::DICTIONARY}; - sequencing_dictionary.SetStringKey( + base::Value sequence_dictionary{base::Value::Type::DICTIONARY}; + sequence_dictionary.SetStringKey( GetSequencingIdPath(), base::NumberToString(sequence_information.sequencing_id())); - sequencing_dictionary.SetStringKey( + sequence_dictionary.SetStringKey( GetGenerationIdPath(), base::NumberToString(sequence_information.generation_id())); - sequencing_dictionary.SetIntKey(GetPriorityPath(), - sequence_information.priority()); - result_ = std::move(sequencing_dictionary); + sequence_dictionary.SetIntKey(GetPriorityPath(), + sequence_information.priority()); + result_ = std::move(sequence_dictionary); } SequenceInformationDictionaryBuilder::~SequenceInformationDictionaryBuilder() =
diff --git a/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.h b/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.h index bd4ee07..93f3df7 100644 --- a/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.h +++ b/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder.h
@@ -23,11 +23,6 @@ // "encryptionKey": "EncryptedMessage", // "publicKeyId": 1 // }, -// "sequencingInformation": { -// "sequencingId": 1, -// "generationId": 123456789, -// "priority": 1 -// } // "sequenceInformation": { // "sequencingId": 1, // "generationId": 123456789, @@ -40,11 +35,6 @@ // "encryptionKey": "EncryptedMessage", // "publicKeyId": 2 // }, -// "sequencingInformation": { -// "sequencingId": 2, -// "generationId": 123456789, -// "priority": 1 -// } // "sequenceInformation": { // "sequencingId": 2, // "generationId": 123456789, @@ -56,12 +46,6 @@ // } // TODO(b/159361496): Periodically add memory and disk space usage. // -// Note that there are two identical sub-records - sequencingInformation and -// sequenceInformation (sequencingId and generationId in the former are -// Unsigned, in the later - Signed). This is done temporarily for backwards -// compatibility with the server. -// TODO(b/177677467): Remove this duplication once server is fully transitioned. -// // This payload is added to the common payload of all reporting jobs, which // includes "device" and "browser" sub-fields: // @@ -102,7 +86,6 @@ absl::optional<base::Value> Build(); static base::StringPiece GetEncryptedWrappedRecordPath(); - static base::StringPiece GetUnsignedSequenceInformationKeyPath(); static base::StringPiece GetSequenceInformationKeyPath(); static base::StringPiece GetEncryptionInfoPath(); static base::StringPiece GetCompressionInformationPath();
diff --git a/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc b/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc index 1dfcf6b..022c6438 100644 --- a/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc +++ b/chrome/browser/policy/messaging_layer/upload/record_upload_request_builder_unittest.cc
@@ -131,19 +131,18 @@ EXPECT_FALSE(EncryptedRecordDictionaryBuilder(record).Build().has_value()); - // Reject encrypted_wrapped_record without sequencing information. + // Reject encrypted_wrapped_record without sequence information. record.set_encrypted_wrapped_record("Enterprise"); EXPECT_FALSE(EncryptedRecordDictionaryBuilder(record).Build().has_value()); - // Reject incorrectly set sequencing information by only setting sequencing - // id. + // Reject incorrectly set sequence information by only setting sequencing id. auto* sequence_information = record.mutable_sequence_information(); sequence_information->set_sequencing_id(1701); EXPECT_FALSE(EncryptedRecordDictionaryBuilder(record).Build().has_value()); - // Finish correctly setting sequencing information but incorrectly set + // Finish correctly setting sequence information but incorrectly set // encryption info. sequence_information->set_generation_id(12345678); sequence_information->set_priority(IMMEDIATE);
diff --git a/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc b/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc index 71a98c7..9d9eb8db8 100644 --- a/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc +++ b/chrome/browser/policy/messaging_layer/upload/upload_client_unittest.cc
@@ -59,9 +59,9 @@ return expected_serialized == actual_serialized; } -// Helper function composes JSON represented as base::Value from Sequencing +// Helper function composes JSON represented as base::Value from Sequence // information in request. -base::Value ValueFromSucceededSequencingInfo( +base::Value ValueFromSucceededSequenceInfo( const absl::optional<base::Value> request, bool force_confirm_flag) { EXPECT_TRUE(request.has_value()); @@ -74,11 +74,7 @@ EXPECT_TRUE(encrypted_record_list != nullptr); EXPECT_FALSE(encrypted_record_list->GetList().empty()); - // Retrieve and process sequencing information - const base::Value* unsigned_seq_info = - encrypted_record_list->GetList().rbegin()->FindDictKey( - "sequencingInformation"); - EXPECT_TRUE(unsigned_seq_info != nullptr); + // Retrieve and process sequence information const base::Value* seq_info = encrypted_record_list->GetList().rbegin()->FindDictKey( "sequenceInformation"); @@ -210,8 +206,8 @@ base::Value request, policy::CloudPolicyClient::ResponseCallback response_cb) { std::move(response_cb) - .Run(ValueFromSucceededSequencingInfo(std::move(request), - force_confirm_flag)); + .Run(ValueFromSucceededSequenceInfo(std::move(request), + force_confirm_flag)); }))); test::TestMultiEvent<SequenceInformation, bool> upload_success;
diff --git a/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc b/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc index 3a44242b..670fd8c0 100644 --- a/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc +++ b/chrome/browser/policy/messaging_layer/upload/upload_provider_unittest.cc
@@ -42,9 +42,9 @@ return true; } -// Helper function composes JSON represented as base::Value from Sequencing +// Helper function composes JSON represented as base::Value from Sequence // information in request. -base::Value ValueFromSucceededSequencingInfo( +base::Value ValueFromSucceededSequenceInfo( const absl::optional<base::Value> request, bool force_confirm_flag) { EXPECT_TRUE(request.has_value()); @@ -57,11 +57,7 @@ EXPECT_NE(encrypted_record_list, nullptr); EXPECT_FALSE(encrypted_record_list->GetList().empty()); - // Retrieve and process sequencing information - const base::Value* unsigned_seq_info = - encrypted_record_list->GetList().rbegin()->FindDictKey( - "sequencingInformation"); - EXPECT_NE(unsigned_seq_info, nullptr); + // Retrieve and process sequence information const base::Value* seq_info = encrypted_record_list->GetList().rbegin()->FindDictKey( "sequenceInformation"); @@ -185,8 +181,8 @@ Invoke([](base::Value request, policy::CloudPolicyClient::ResponseCallback response_cb) { std::move(response_cb) - .Run(ValueFromSucceededSequencingInfo(std::move(request), - false)); + .Run(ValueFromSucceededSequenceInfo( + std::move(request), /*force_confirm_flag=*/false)); }))); auto records = std::make_unique<std::vector<EncryptedRecord>>();
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java index c7bc54e..e9c3ae23 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -781,6 +781,9 @@ public static final String SHOW_START_SEGMENTATION_RESULT = "Chrome.StartSurface.ShowSegmentationResult"; + public static final String REGULAR_TAB_COUNT = "Chrome.StartSurface.RegularTabCount"; + public static final String INCOGNITO_TAB_COUNT = "Chrome.StartSurface.IncognitoTabCount"; + /** * Contains a trial group that was used to determine whether the reached code profiler should be * enabled. @@ -1072,9 +1075,10 @@ FLAGS_LAST_CACHED_MINIMAL_BROWSER_FLAGS_TIME_MILLIS, HOMEPAGE_LOCATION_POLICY, HOMEPAGE_USE_CHROME_NTP, - HOMEPAGE_PARTNER_CUSTOMIZED_DEFAULT_URI, + HOMEPAGE_PARTNER_CUSTOMIZED_DEFAULT_URI, IMAGE_DESCRIPTIONS_JUST_ONCE_COUNT, IMAGE_DESCRIPTIONS_DONT_ASK_AGAIN, + INCOGNITO_TAB_COUNT, ISOLATED_SPLITS_DEX_COMPILE_VERSION, LAST_SESSION_BROWSER_PID, LAST_SESSION_APPLICATION_STATE, @@ -1117,6 +1121,7 @@ QUERY_TILES_NUM_RECENT_MV_TILE_CLICKS, QUERY_TILES_NUM_RECENT_QUERY_TILE_CLICKS, QUERY_TILES_SHOW_ON_NTP, + REGULAR_TAB_COUNT, SETTINGS_SAFETY_CHECK_LAST_RUN_TIMESTAMP, SETTINGS_SAFETY_CHECK_RUN_COUNTER, SHARING_LAST_SHARED_COMPONENT_NAME,
diff --git a/chrome/browser/prefetch/android/BUILD.gn b/chrome/browser/prefetch/android/BUILD.gn new file mode 100644 index 0000000..d7e98a5a --- /dev/null +++ b/chrome/browser/prefetch/android/BUILD.gn
@@ -0,0 +1,93 @@ +# 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. + +import("//build/config/android/rules.gni") + +java_cpp_enum("preload_pages_state_generated_enum") { + sources = [ "//chrome/browser/prefetch/prefetch_prefs.h" ] +} + +android_library("java") { + sources = [ + "java/src/org/chromium/chrome/browser/prefetch/settings/ExtendedPreloadingSettingsFragment.java", + "java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsBridge.java", + "java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragment.java", + "java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragmentBase.java", + "java/src/org/chromium/chrome/browser/prefetch/settings/RadioButtonGroupPreloadPagesSettings.java", + "java/src/org/chromium/chrome/browser/prefetch/settings/StandardPreloadingSettingsFragment.java", + ] + deps = [ + ":java_resources", + ":jni_headers", + "//base:base_java", + "//chrome/browser/android/lifecycle:java", + "//chrome/browser/feedback/android:java", + "//chrome/browser/flags:java", + "//chrome/browser/preferences:java", + "//chrome/browser/profiles/android:java", + "//chrome/browser/settings:java", + "//components/browser_ui/settings/android:java", + "//components/browser_ui/widget/android:java", + "//components/minidump_uploader:minidump_uploader_java", + "//third_party/android_deps:material_design_java", + "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_fragment_fragment_java", + "//third_party/androidx:androidx_preference_preference_java", + "//third_party/androidx:androidx_vectordrawable_vectordrawable_java", + ] + srcjar_deps = [ ":preload_pages_state_generated_enum" ] + annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] + resources_package = "org.chromium.chrome.browser.prefetch.settings" +} + +android_library("javatests") { + testonly = true + sources = [ "java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragmentTest.java" ] + deps = [ + ":java", + "//base:base_java_test_support", + "//chrome/android:chrome_java", + "//chrome/browser/feedback/android:java", + "//chrome/browser/flags:java", + "//chrome/browser/preferences:java", + "//chrome/browser/profiles/android:java", + "//chrome/browser/settings:java", + "//chrome/browser/settings:test_support_java", + "//chrome/test/android:chrome_java_test_support", + "//components/browser_ui/settings/android:java", + "//components/browser_ui/widget/android:java", + "//components/policy/android:policy_java_test_support", + "//components/prefs/android:java", + "//components/user_prefs/android:java", + "//content/public/test/android:content_java_test_support", + "//third_party/android_deps:espresso_java", + "//third_party/android_support_test_runner:runner_java", + "//third_party/androidx:androidx_test_runner_java", + "//third_party/junit", + "//third_party/mockito:mockito_java", + ] +} + +android_resources("java_resources") { + sources = [ + "java/res/layout/radio_button_group_preload_pages_preference.xml", + "java/res/xml/extended_preloading_preferences.xml", + "java/res/xml/preload_pages_preferences.xml", + "java/res/xml/standard_preloading_preferences.xml", + ] + deps = [ + "//chrome/browser/feedback/android:java_resources", + "//chrome/browser/ui/android/strings:ui_strings_grd", + "//components/browser_ui/settings/android:java_resources", + ] +} + +generate_jni("jni_headers") { + visibility = [ + ":*", + "//chrome/android:jni_headers", + "//chrome/browser", + ] + sources = [ "java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsBridge.java" ] +}
diff --git a/chrome/browser/prefetch/android/java/res/layout/radio_button_group_preload_pages_preference.xml b/chrome/browser/prefetch/android/java/res/layout/radio_button_group_preload_pages_preference.xml new file mode 100644 index 0000000..f9a8f5c --- /dev/null +++ b/chrome/browser/prefetch/android/java/res/layout/radio_button_group_preload_pages_preference.xml
@@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:focusable="false"> + + <org.chromium.components.browser_ui.widget.RadioButtonWithDescription + android:id="@+id/no_preloading" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:primaryText="@string/preload_pages_no_preloading_title" + app:descriptionText="@string/preload_pages_no_preloading_summary" /> + + <org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionAndAuxButton + android:id="@+id/standard_preloading" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:primaryText="@string/preload_pages_standard_preloading_title" + app:descriptionText="@string/preload_pages_standard_preloading_summary" /> + + <org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionAndAuxButton + android:id="@+id/extended_preloading" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:primaryText="@string/preload_pages_extended_preloading_title" + app:descriptionText="@string/preload_pages_extended_preloading_summary" /> + +</org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout>
diff --git a/chrome/browser/prefetch/android/java/res/xml/extended_preloading_preferences.xml b/chrome/browser/prefetch/android/java/res/xml/extended_preloading_preferences.xml new file mode 100644 index 0000000..87542f2 --- /dev/null +++ b/chrome/browser/prefetch/android/java/res/xml/extended_preloading_preferences.xml
@@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="subtitle" + android:title="@string/preload_pages_extended_preloading_subtitle" + app:allowDividerBelow="false" /> + + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="bullet_one" + android:summary="@string/preload_pages_extended_preloading_bullet_one" + app:allowDividerBelow="false" /> + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="bullet_two" + android:summary="@string/preload_pages_extended_preloading_bullet_two" + app:allowDividerBelow="false" /> + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="bullet_three" + android:summary="@string/preload_pages_extended_preloading_bullet_three" + app:allowDividerBelow="false" /> + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="bullet_four" + android:summary="@string/preload_pages_extended_preloading_bullet_four" + app:allowDividerBelow="false" /> +</PreferenceScreen>
diff --git a/chrome/browser/prefetch/android/java/res/xml/preload_pages_preferences.xml b/chrome/browser/prefetch/android/java/res/xml/preload_pages_preferences.xml new file mode 100644 index 0000000..fe83c088 --- /dev/null +++ b/chrome/browser/prefetch/android/java/res/xml/preload_pages_preferences.xml
@@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="text_managed" /> + + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="summary" + android:summary="@string/preload_pages_summary" + app:allowDividerBelow="false" /> + <org.chromium.chrome.browser.prefetch.settings.RadioButtonGroupPreloadPagesSettings + android:key="preload_pages_radio_button_group" + android:selectable="false" + app:allowDividerAbove="false" + app:allowDividerBelow="false" /> +</PreferenceScreen>
diff --git a/chrome/browser/prefetch/android/java/res/xml/standard_preloading_preferences.xml b/chrome/browser/prefetch/android/java/res/xml/standard_preloading_preferences.xml new file mode 100644 index 0000000..93b7158d --- /dev/null +++ b/chrome/browser/prefetch/android/java/res/xml/standard_preloading_preferences.xml
@@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. --> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="subtitle" + android:title="@string/preload_pages_standard_preloading_subtitle" + app:allowDividerBelow="false" /> + + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="bullet_one" + android:summary="@string/preload_pages_standard_preloading_bullet_one" + app:allowDividerBelow="false" /> + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="bullet_two" + android:summary="@string/preload_pages_standard_preloading_bullet_two" + app:allowDividerBelow="false" /> + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="bullet_three" + android:summary="@string/preload_pages_standard_preloading_bullet_three" + app:allowDividerBelow="false" /> + <org.chromium.components.browser_ui.settings.TextMessagePreference + android:key="bullet_four" + android:summary="@string/preload_pages_standard_preloading_bullet_four" + app:allowDividerBelow="false" /> +</PreferenceScreen>
diff --git a/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/ExtendedPreloadingSettingsFragment.java b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/ExtendedPreloadingSettingsFragment.java new file mode 100644 index 0000000..7286eb40 --- /dev/null +++ b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/ExtendedPreloadingSettingsFragment.java
@@ -0,0 +1,15 @@ +// 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. + +package org.chromium.chrome.browser.prefetch.settings; + +/** + * Fragment containing extended preloading settings. + */ +public class ExtendedPreloadingSettingsFragment extends PreloadPagesSettingsFragmentBase { + @Override + protected int getPreferenceResource() { + return R.xml.extended_preloading_preferences; + } +}
diff --git a/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsBridge.java b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsBridge.java new file mode 100644 index 0000000..3845d58 --- /dev/null +++ b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsBridge.java
@@ -0,0 +1,48 @@ +// 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. + +package org.chromium.chrome.browser.prefetch.settings; + +import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.annotations.NativeMethods; + +/** + * Reads and writes preferences related to preloading. + */ +@JNINamespace("prefetch") +public class PreloadPagesSettingsBridge { + /** + * @return The current Preload Pages state (off, standard or extended). + */ + public static @PreloadPagesState int getState() { + return PreloadPagesSettingsBridgeJni.get().getState(); + } + + /** + * Sets the current Preload Pages state. + * + * @param mode The desired new Preload Pages state. + */ + public static void setState(@PreloadPagesState int state) { + PreloadPagesSettingsBridgeJni.get().setState(state); + } + + /** + * Determines whether the Preload Pages state is controlled by an enterprise + * policy. + * + * @return True if the Preload Pages state is managed. + */ + public static boolean isNetworkPredictionManaged() { + return PreloadPagesSettingsBridgeJni.get().isNetworkPredictionManaged(); + } + + @NativeMethods + interface Natives { + @PreloadPagesState + int getState(); + void setState(@PreloadPagesState int mode); + boolean isNetworkPredictionManaged(); + } +}
diff --git a/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragment.java b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragment.java new file mode 100644 index 0000000..bb6de017 --- /dev/null +++ b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragment.java
@@ -0,0 +1,117 @@ +// 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. + +package org.chromium.chrome.browser.prefetch.settings; + +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; + +import org.chromium.chrome.browser.settings.ChromeManagedPreferenceDelegate; +import org.chromium.components.browser_ui.settings.FragmentSettingsLauncher; +import org.chromium.components.browser_ui.settings.ManagedPreferenceDelegate; +import org.chromium.components.browser_ui.settings.SettingsLauncher; +import org.chromium.components.browser_ui.settings.TextMessagePreference; + +/** + * Fragment containing Preload Pages settings. + */ +public class PreloadPagesSettingsFragment extends PreloadPagesSettingsFragmentBase + implements FragmentSettingsLauncher, + RadioButtonGroupPreloadPagesSettings.OnPreloadPagesStateDetailsRequested, + Preference.OnPreferenceChangeListener { + @VisibleForTesting + static final String PREF_TEXT_MANAGED = "text_managed"; + @VisibleForTesting + static final String PREF_PRELOAD_PAGES = "preload_pages_radio_button_group"; + + // An instance of SettingsLauncher that is used to launch Preload Pages subsections. + private SettingsLauncher mSettingsLauncher; + private RadioButtonGroupPreloadPagesSettings mPreloadPagesPreference; + + /** + * @return A summary that describes the current Preload Pages state. + */ + public static String getPreloadPagesSummaryString(Context context) { + @PreloadPagesState + int preloadPagesState = PreloadPagesSettingsBridge.getState(); + String preloadPagesStateString = ""; + if (preloadPagesState == PreloadPagesState.EXTENDED_PRELOADING) { + return context.getString(R.string.preload_pages_extended_preloading_title); + } + if (preloadPagesState == PreloadPagesState.STANDARD_PRELOADING) { + return context.getString(R.string.preload_pages_standard_preloading_title); + } + if (preloadPagesState == PreloadPagesState.NO_PRELOADING) { + return context.getString(R.string.preload_pages_no_preloading_title); + } + assert false : "Should not be reached"; + return ""; + } + + @Override + protected void onCreatePreferencesInternal(Bundle bundle, String s) { + ManagedPreferenceDelegate managedPreferenceDelegate = createManagedPreferenceDelegate(); + + mPreloadPagesPreference = findPreference(PREF_PRELOAD_PAGES); + mPreloadPagesPreference.init(PreloadPagesSettingsBridge.getState()); + mPreloadPagesPreference.setPreloadPagesStateDetailsRequestedListener(this); + mPreloadPagesPreference.setManagedPreferenceDelegate(managedPreferenceDelegate); + mPreloadPagesPreference.setOnPreferenceChangeListener(this); + + TextMessagePreference textManaged = findPreference(PREF_TEXT_MANAGED); + textManaged.setManagedPreferenceDelegate(managedPreferenceDelegate); + textManaged.setVisible(managedPreferenceDelegate.isPreferenceClickDisabledByPolicy( + mPreloadPagesPreference)); + } + + @Override + protected int getPreferenceResource() { + return R.xml.preload_pages_preferences; + } + + @Override + public void onPreloadPagesStateDetailsRequested(@PreloadPagesState int preloadPagesState) { + if (preloadPagesState == PreloadPagesState.EXTENDED_PRELOADING) { + mSettingsLauncher.launchSettingsActivity( + getActivity(), ExtendedPreloadingSettingsFragment.class); + } else if (preloadPagesState == PreloadPagesState.STANDARD_PRELOADING) { + mSettingsLauncher.launchSettingsActivity( + getActivity(), StandardPreloadingSettingsFragment.class); + } else { + assert false : "Should not be reached"; + } + } + + @Override + public void setSettingsLauncher(SettingsLauncher settingsLauncher) { + mSettingsLauncher = settingsLauncher; + } + + private ChromeManagedPreferenceDelegate createManagedPreferenceDelegate() { + return preference -> { + String key = preference.getKey(); + assert PREF_TEXT_MANAGED.equals(key) + || PREF_PRELOAD_PAGES.equals(key) : "Wrong preference key: " + key; + return PreloadPagesSettingsBridge.isNetworkPredictionManaged(); + }; + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + String key = preference.getKey(); + assert PREF_PRELOAD_PAGES.equals(key) : "Unexpected preference key."; + @PreloadPagesState + int newState = (int) newValue; + @PreloadPagesState + int currentState = PreloadPagesSettingsBridge.getState(); + if (newState == currentState) { + return true; + } + PreloadPagesSettingsBridge.setState(newState); + return true; + } +}
diff --git a/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragmentBase.java b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragmentBase.java new file mode 100644 index 0000000..d4ca8882 --- /dev/null +++ b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragmentBase.java
@@ -0,0 +1,76 @@ +// 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. + +package org.chromium.chrome.browser.prefetch.settings; + +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; + +import androidx.preference.PreferenceFragmentCompat; +import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; + +import org.chromium.chrome.browser.feedback.FragmentHelpAndFeedbackLauncher; +import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncher; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.components.browser_ui.settings.SettingsUtils; + +/** + * The base fragment class for Preload Pages settings fragments. + */ +public abstract class PreloadPagesSettingsFragmentBase + extends PreferenceFragmentCompat implements FragmentHelpAndFeedbackLauncher { + private HelpAndFeedbackLauncher mHelpAndFeedbackLauncher; + + @Override + public void onCreatePreferences(Bundle bundle, String s) { + SettingsUtils.addPreferencesFromResource(this, getPreferenceResource()); + getActivity().setTitle(R.string.prefs_section_preload_pages_title); + + onCreatePreferencesInternal(bundle, s); + + setHasOptionsMenu(true); + } + + @Override + public void setHelpAndFeedbackLauncher(HelpAndFeedbackLauncher helpAndFeedbackLauncher) { + mHelpAndFeedbackLauncher = helpAndFeedbackLauncher; + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + menu.clear(); + MenuItem help = + menu.add(Menu.NONE, R.id.menu_id_targeted_help, Menu.NONE, R.string.menu_help); + help.setIcon(VectorDrawableCompat.create( + getResources(), R.drawable.ic_help_and_feedback, getActivity().getTheme())); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() != R.id.menu_id_targeted_help) { + return false; + } + mHelpAndFeedbackLauncher.show(getActivity(), getString(R.string.help_context_privacy), + Profile.getLastUsedRegularProfile(), null); + return true; + } + + /** + * Called within {@link PreloadPagesSettingsFragmentBase#onCreatePreferences(Bundle, String)}. + * If the child class needs to handle specific logic during preference creation, it can override + * this method. + * + * @param bundle If the fragment is being re-created from a previous saved state, this is the + * state. + * @param s If non-null, this preference should be rooted at the PreferenceScreen with this key. + */ + protected void onCreatePreferencesInternal(Bundle bundle, String s) {} + + /** + * @return The resource id of the preference. + */ + protected abstract int getPreferenceResource(); +}
diff --git a/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragmentTest.java b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragmentTest.java new file mode 100644 index 0000000..3044e19 --- /dev/null +++ b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/PreloadPagesSettingsFragmentTest.java
@@ -0,0 +1,232 @@ +// 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. + +package org.chromium.chrome.browser.prefetch.settings; + +import static androidx.test.espresso.Espresso.onView; +import static androidx.test.espresso.action.ViewActions.click; +import static androidx.test.espresso.matcher.ViewMatchers.withId; + +import androidx.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncher; +import org.chromium.chrome.browser.init.ChromeBrowserInitializer; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.settings.SettingsActivityTestRule; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.components.browser_ui.settings.SettingsLauncher; +import org.chromium.components.browser_ui.settings.TextMessagePreference; +import org.chromium.components.browser_ui.widget.RadioButtonWithDescription; +import org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionAndAuxButton; +import org.chromium.components.policy.test.annotations.Policies; +import org.chromium.content_public.browser.test.util.TestThreadUtils; + +/** + * Tests for {@link PreloadPagesSettingsFragment}. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +public class PreloadPagesSettingsFragmentTest { + private static final String ASSERT_PRELOAD_PAGES_STATE_RADIO_BUTTON_GROUP = + "Incorrect Preload Pages state in the radio button group."; + private static final String ASSERT_RADIO_BUTTON_CHECKED = + "Incorrect radio button checked state."; + private static final String ASSERT_PRELOAD_PAGES_STATE_NATIVE = + "Incorrect Preload Pages state from native."; + + @Rule + public SettingsActivityTestRule<PreloadPagesSettingsFragment> mTestRule = + new SettingsActivityTestRule<>(PreloadPagesSettingsFragment.class); + + @Mock + private SettingsLauncher mSettingsLauncher; + + @Mock + private HelpAndFeedbackLauncher mHelpAndFeedbackLauncher; + + private PreloadPagesSettingsFragment mPreloadPagesSettingsFragment; + private RadioButtonGroupPreloadPagesSettings mPreloadPagesPreference; + private TextMessagePreference mManagedTextPreference; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + private void launchSettingsActivity() { + mTestRule.startSettingsActivity(); + mPreloadPagesSettingsFragment = mTestRule.getFragment(); + mPreloadPagesPreference = mPreloadPagesSettingsFragment.findPreference( + PreloadPagesSettingsFragment.PREF_PRELOAD_PAGES); + mManagedTextPreference = mPreloadPagesSettingsFragment.findPreference( + PreloadPagesSettingsFragment.PREF_TEXT_MANAGED); + Assert.assertNotNull( + "Preload Pages preference should not be null.", mPreloadPagesPreference); + Assert.assertNotNull("Text managed preference should not be null.", mManagedTextPreference); + } + + @Test + @SmallTest + @Feature({"PreloadPages"}) + public void testOnStartup() { + launchSettingsActivity(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + @PreloadPagesState + int currentState = PreloadPagesSettingsBridge.getState(); + boolean extended_preloading_checked = + currentState == PreloadPagesState.EXTENDED_PRELOADING; + boolean standard_preloading_checked = + currentState == PreloadPagesState.STANDARD_PRELOADING; + boolean no_preloading_checked = currentState == PreloadPagesState.NO_PRELOADING; + Assert.assertEquals(ASSERT_RADIO_BUTTON_CHECKED, extended_preloading_checked, + getExtendedPreloadingButton().isChecked()); + Assert.assertEquals(ASSERT_RADIO_BUTTON_CHECKED, standard_preloading_checked, + getStandardPreloadingButton().isChecked()); + Assert.assertEquals(ASSERT_RADIO_BUTTON_CHECKED, no_preloading_checked, + getNoPreloadingButton().isChecked()); + Assert.assertFalse(mManagedTextPreference.isVisible()); + }); + } + + @Test + @SmallTest + @Feature({"PreloadPages"}) + public void testCheckRadioButtons() { + launchSettingsActivity(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertFalse(mManagedTextPreference.isVisible()); + // Click the Extended Preloading button. + getExtendedPreloadingButton().onClick(null); + Assert.assertEquals(ASSERT_PRELOAD_PAGES_STATE_RADIO_BUTTON_GROUP, + PreloadPagesState.EXTENDED_PRELOADING, getPreloadPagesState()); + Assert.assertTrue( + ASSERT_RADIO_BUTTON_CHECKED, getExtendedPreloadingButton().isChecked()); + Assert.assertFalse( + ASSERT_RADIO_BUTTON_CHECKED, getStandardPreloadingButton().isChecked()); + Assert.assertFalse(ASSERT_RADIO_BUTTON_CHECKED, getNoPreloadingButton().isChecked()); + // TODO(crbug.com/1263586): Enable this once prefs are implemented. + // Assert.assertEquals(ASSERT_PRELOAD_PAGES_STATE_NATIVE, + // PreloadPagesState.EXTENDED_PRELOADING, + // PreloadPagesSettingsBridge.getState()); + + // Click the Standard Preloading button. + getStandardPreloadingButton().onClick(null); + Assert.assertEquals(ASSERT_PRELOAD_PAGES_STATE_RADIO_BUTTON_GROUP, + PreloadPagesState.STANDARD_PRELOADING, getPreloadPagesState()); + Assert.assertFalse( + ASSERT_RADIO_BUTTON_CHECKED, getExtendedPreloadingButton().isChecked()); + Assert.assertTrue( + ASSERT_RADIO_BUTTON_CHECKED, getStandardPreloadingButton().isChecked()); + Assert.assertFalse(ASSERT_RADIO_BUTTON_CHECKED, getNoPreloadingButton().isChecked()); + // TODO(crbug.com/1263586): Enable this once prefs are implemented. + // Assert.assertEquals(ASSERT_PRELOAD_PAGES_STATE_NATIVE, + // PreloadPagesState.STANDARD_PRELOADING, + // PreloadPagesSettingsBridge.getState()); + + // Click the No Preloading button. + getNoPreloadingButton().onClick(null); + Assert.assertEquals(ASSERT_PRELOAD_PAGES_STATE_RADIO_BUTTON_GROUP, + PreloadPagesState.NO_PRELOADING, getPreloadPagesState()); + Assert.assertFalse( + ASSERT_RADIO_BUTTON_CHECKED, getExtendedPreloadingButton().isChecked()); + Assert.assertFalse( + ASSERT_RADIO_BUTTON_CHECKED, getStandardPreloadingButton().isChecked()); + Assert.assertTrue(ASSERT_RADIO_BUTTON_CHECKED, getNoPreloadingButton().isChecked()); + // TODO(crbug.com/1263586): Enable this once prefs are implemented. + // Assert.assertEquals(ASSERT_PRELOAD_PAGES_STATE_NATIVE, + // PreloadPagesState.NO_PRELOADING, + // PreloadPagesSettingsBridge.getState()); + }); + } + + @Test + @SmallTest + @Feature({"PreloadPages"}) + public void testExtendedPreloadingAuxButtonClicked() { + launchSettingsActivity(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mPreloadPagesSettingsFragment.setSettingsLauncher(mSettingsLauncher); + getExtendedPreloadingButton().getAuxButtonForTests().performClick(); + Mockito.verify(mSettingsLauncher) + .launchSettingsActivity(mPreloadPagesSettingsFragment.getContext(), + ExtendedPreloadingSettingsFragment.class); + }); + } + + @Test + @SmallTest + @Feature({"PreloadPages"}) + public void testStandardPreloadingAuxButtonClicked() { + launchSettingsActivity(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mPreloadPagesSettingsFragment.setSettingsLauncher(mSettingsLauncher); + getStandardPreloadingButton().getAuxButtonForTests().performClick(); + Mockito.verify(mSettingsLauncher) + .launchSettingsActivity(mPreloadPagesSettingsFragment.getContext(), + StandardPreloadingSettingsFragment.class); + }); + } + + @Test + @SmallTest + @Feature({"PreloadPages"}) + @Policies.Add({ @Policies.Item(key = "NetworkPredictionOptions", string = "0") }) + public void testPreloadingManaged() { + TestThreadUtils.runOnUiThreadBlocking( + () -> { ChromeBrowserInitializer.getInstance().handleSynchronousStartup(); }); + launchSettingsActivity(); + TestThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertTrue(PreloadPagesSettingsBridge.isNetworkPredictionManaged()); + Assert.assertTrue(mManagedTextPreference.isVisible()); + Assert.assertFalse(getExtendedPreloadingButton().isEnabled()); + Assert.assertFalse(getStandardPreloadingButton().isEnabled()); + Assert.assertFalse(getNoPreloadingButton().isEnabled()); + // TODO(crbug.com/1263586): This should be NO_PRELOADING once prefs are implemented. + Assert.assertEquals(PreloadPagesState.STANDARD_PRELOADING, getPreloadPagesState()); + // To disclose information, aux buttons should be enabled under managed mode. + Assert.assertTrue(getExtendedPreloadingButton().getAuxButtonForTests().isEnabled()); + Assert.assertTrue(getStandardPreloadingButton().getAuxButtonForTests().isEnabled()); + }); + } + + @Test + @SmallTest + @Feature({"PreloadPages"}) + public void testHelpButtonClicked() { + launchSettingsActivity(); + mPreloadPagesSettingsFragment.setHelpAndFeedbackLauncher(mHelpAndFeedbackLauncher); + onView(withId(R.id.menu_id_targeted_help)).perform(click()); + TestThreadUtils.runOnUiThreadBlocking(() -> { + Mockito.verify(mHelpAndFeedbackLauncher) + .show(mPreloadPagesSettingsFragment.getActivity(), + mPreloadPagesSettingsFragment.getString(R.string.help_context_privacy), + Profile.getLastUsedRegularProfile(), null); + }); + } + + private @PreloadPagesState int getPreloadPagesState() { + return mPreloadPagesPreference.getPreloadPagesStateForTesting(); + } + + private RadioButtonWithDescriptionAndAuxButton getExtendedPreloadingButton() { + return mPreloadPagesPreference.getExtendedPreloadingButtonForTesting(); + } + + private RadioButtonWithDescriptionAndAuxButton getStandardPreloadingButton() { + return mPreloadPagesPreference.getStandardPreloadingButtonForTesting(); + } + + private RadioButtonWithDescription getNoPreloadingButton() { + return mPreloadPagesPreference.getNoPreloadingButtonForTesting(); + } +}
diff --git a/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/RadioButtonGroupPreloadPagesSettings.java b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/RadioButtonGroupPreloadPagesSettings.java new file mode 100644 index 0000000..8580cf4 --- /dev/null +++ b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/RadioButtonGroupPreloadPagesSettings.java
@@ -0,0 +1,159 @@ +// 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. + +package org.chromium.chrome.browser.prefetch.settings; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.RadioGroup; + +import androidx.annotation.VisibleForTesting; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import org.chromium.components.browser_ui.settings.ManagedPreferenceDelegate; +import org.chromium.components.browser_ui.settings.ManagedPreferencesUtils; +import org.chromium.components.browser_ui.widget.RadioButtonWithDescription; +import org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionAndAuxButton; +import org.chromium.components.browser_ui.widget.RadioButtonWithDescriptionLayout; + +/** + * A radio button group used for Preload Pages. Currently, it has 3 options: + * Extended Preloading, Standard Preloading and No Preloading. + */ +public class RadioButtonGroupPreloadPagesSettings extends Preference + implements RadioGroup.OnCheckedChangeListener, + RadioButtonWithDescriptionAndAuxButton.OnAuxButtonClickedListener { + /** + * Interface that will subscribe to Preload Pages state details requested events. + */ + public interface OnPreloadPagesStateDetailsRequested { + /** + * Notify that details of a Preload Pages state are requested. + * @param preloadPagesState The Preload Pages state that is requested for more details. + */ + void onPreloadPagesStateDetailsRequested(@PreloadPagesState int preloadPagesState); + } + private RadioButtonWithDescriptionAndAuxButton mExtendedPreloading; + private RadioButtonWithDescriptionAndAuxButton mStandardPreloading; + private RadioButtonWithDescription mNoPreloading; + private @PreloadPagesState int mPreloadPagesState; + private OnPreloadPagesStateDetailsRequested mPreloadPagesStateDetailsRequestedListener; + private ManagedPreferenceDelegate mManagedPrefDelegate; + + public RadioButtonGroupPreloadPagesSettings(Context context, AttributeSet attrs) { + super(context, attrs); + setLayoutResource(R.layout.radio_button_group_preload_pages_preference); + } + + /** + * Set Preload Pages state. Called before onBindViewHolder. + * @param preloadPagesState The current Preload Pages state. + */ + public void init(@PreloadPagesState int preloadPagesState) { + mPreloadPagesState = preloadPagesState; + } + + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + if (checkedId == mExtendedPreloading.getId()) { + mPreloadPagesState = PreloadPagesState.EXTENDED_PRELOADING; + } else if (checkedId == mStandardPreloading.getId()) { + mPreloadPagesState = PreloadPagesState.STANDARD_PRELOADING; + } else if (checkedId == mNoPreloading.getId()) { + mPreloadPagesState = PreloadPagesState.NO_PRELOADING; + } else { + assert false : "Should not be reached."; + } + callChangeListener(mPreloadPagesState); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + mExtendedPreloading = (RadioButtonWithDescriptionAndAuxButton) holder.findViewById( + R.id.extended_preloading); + mExtendedPreloading.setAuxButtonClickedListener(this); + mStandardPreloading = (RadioButtonWithDescriptionAndAuxButton) holder.findViewById( + R.id.standard_preloading); + mStandardPreloading.setAuxButtonClickedListener(this); + mNoPreloading = (RadioButtonWithDescription) holder.findViewById(R.id.no_preloading); + RadioButtonWithDescriptionLayout groupLayout = + (RadioButtonWithDescriptionLayout) mNoPreloading.getRootView(); + groupLayout.setOnCheckedChangeListener(this); + + setCheckedState(mPreloadPagesState); + + // If Preload Pages is managed, disable the radio button group, but keep the aux buttons + // enabled to disclose information. + if (mManagedPrefDelegate.isPreferenceClickDisabledByPolicy(this)) { + groupLayout.setEnabled(false); + mExtendedPreloading.setAuxButtonEnabled(true); + mStandardPreloading.setAuxButtonEnabled(true); + } + } + + @Override + public void onAuxButtonClicked(int clickedButtonId) { + if (clickedButtonId == mExtendedPreloading.getId()) { + mPreloadPagesStateDetailsRequestedListener.onPreloadPagesStateDetailsRequested( + PreloadPagesState.EXTENDED_PRELOADING); + } else if (clickedButtonId == mStandardPreloading.getId()) { + mPreloadPagesStateDetailsRequestedListener.onPreloadPagesStateDetailsRequested( + PreloadPagesState.STANDARD_PRELOADING); + } else { + assert false : "Should not be reached."; + } + } + + /** + * Sets a listener that will be notified when details of a Preload Pages state are requested. + * @param listener New listener that will be notified when details of a Preload Pages state are + * requested. + */ + public void setPreloadPagesStateDetailsRequestedListener( + OnPreloadPagesStateDetailsRequested listener) { + mPreloadPagesStateDetailsRequestedListener = listener; + } + + /** + * Sets the ManagedPreferenceDelegate which will determine whether this preference is managed. + */ + public void setManagedPreferenceDelegate(ManagedPreferenceDelegate delegate) { + mManagedPrefDelegate = delegate; + ManagedPreferencesUtils.initPreference(mManagedPrefDelegate, this); + } + + /** + * Sets the checked state of the Preload Pages radio button group. + * @param checkedState Set the radio button of checkedState to checked, and set the radio + * buttons of other states to unchecked. + */ + public void setCheckedState(@PreloadPagesState int checkedState) { + mPreloadPagesState = checkedState; + mExtendedPreloading.setChecked(checkedState == PreloadPagesState.EXTENDED_PRELOADING); + mStandardPreloading.setChecked(checkedState == PreloadPagesState.STANDARD_PRELOADING); + mNoPreloading.setChecked(checkedState == PreloadPagesState.NO_PRELOADING); + } + + @VisibleForTesting + public @PreloadPagesState int getPreloadPagesStateForTesting() { + return mPreloadPagesState; + } + + @VisibleForTesting + public RadioButtonWithDescriptionAndAuxButton getExtendedPreloadingButtonForTesting() { + return mExtendedPreloading; + } + + @VisibleForTesting + public RadioButtonWithDescriptionAndAuxButton getStandardPreloadingButtonForTesting() { + return mStandardPreloading; + } + + @VisibleForTesting + public RadioButtonWithDescription getNoPreloadingButtonForTesting() { + return mNoPreloading; + } +}
diff --git a/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/StandardPreloadingSettingsFragment.java b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/StandardPreloadingSettingsFragment.java new file mode 100644 index 0000000..ce2fcf70 --- /dev/null +++ b/chrome/browser/prefetch/android/java/src/org/chromium/chrome/browser/prefetch/settings/StandardPreloadingSettingsFragment.java
@@ -0,0 +1,15 @@ +// 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. + +package org.chromium.chrome.browser.prefetch.settings; + +/** + * Fragment containing standard preloading settings. + */ +public class StandardPreloadingSettingsFragment extends PreloadPagesSettingsFragmentBase { + @Override + protected int getPreferenceResource() { + return R.xml.standard_preloading_preferences; + } +}
diff --git a/chrome/browser/prefetch/android/preload_pages_settings_bridge.cc b/chrome/browser/prefetch/android/preload_pages_settings_bridge.cc new file mode 100644 index 0000000..cb22e9a --- /dev/null +++ b/chrome/browser/prefetch/android/preload_pages_settings_bridge.cc
@@ -0,0 +1,42 @@ +// 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 <jni.h> + +#include "chrome/browser/net/prediction_options.h" +#include "chrome/browser/prefetch/android/jni_headers/PreloadPagesSettingsBridge_jni.h" +#include "chrome/browser/prefetch/prefetch_prefs.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/pref_names.h" +#include "components/metrics/metrics_pref_names.h" +#include "components/prefs/pref_service.h" + +namespace { + +PrefService* GetPrefService() { + return ProfileManager::GetActiveUserProfile() + ->GetOriginalProfile() + ->GetPrefs(); +} + +} // namespace + +namespace prefetch { + +static jint JNI_PreloadPagesSettingsBridge_GetState(JNIEnv* env) { + return static_cast<int>(prefetch::GetPreloadPagesState(*GetPrefService())); +} + +static jboolean JNI_PreloadPagesSettingsBridge_IsNetworkPredictionManaged( + JNIEnv* env) { + return GetPrefService()->IsManagedPreference( + prefs::kNetworkPredictionOptions); +} + +static void JNI_PreloadPagesSettingsBridge_SetState(JNIEnv* env, jint state) { + prefetch::SetPreloadPagesState( + GetPrefService(), static_cast<prefetch::PreloadPagesState>(state)); +} + +} // namespace prefetch
diff --git a/chrome/browser/prefetch/pref_names.cc b/chrome/browser/prefetch/pref_names.cc index ede6c972..252e357 100644 --- a/chrome/browser/prefetch/pref_names.cc +++ b/chrome/browser/prefetch/pref_names.cc
@@ -22,5 +22,10 @@ const char kRetryAfterPrefPath[] = "chrome.prefetch_proxy.origin_decider.retry_after"; +// This pref contains an integer (enum of type PreloadPagesState), determining +// which preload pages mode (specifying whether or how much we are allowed to +// preload pages) has been selected by the user. +const char kPrefetchPagesState[] = "chrome.prefetch.preload_pages_state"; + } // namespace prefs } // namespace prefetch
diff --git a/chrome/browser/prefetch/pref_names.h b/chrome/browser/prefetch/pref_names.h index 553d176..e730891 100644 --- a/chrome/browser/prefetch/pref_names.h +++ b/chrome/browser/prefetch/pref_names.h
@@ -12,6 +12,8 @@ extern const char kRetryAfterPrefPath[]; +extern const char kPrefetchPagesState[]; + } // namespace prefs } // namespace prefetch
diff --git a/chrome/browser/prefetch/prefetch_prefs.cc b/chrome/browser/prefetch/prefetch_prefs.cc new file mode 100644 index 0000000..61f78940 --- /dev/null +++ b/chrome/browser/prefetch/prefetch_prefs.cc
@@ -0,0 +1,18 @@ +// 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 "chrome/browser/prefetch/prefetch_prefs.h" + +namespace prefetch { + +PreloadPagesState GetPreloadPagesState(const PrefService& prefs) { + // TODO(crbug.com/1263586): implement. + return PreloadPagesState::STANDARD_PRELOADING; +} + +void SetPreloadPagesState(PrefService* prefs, PreloadPagesState state) { + // TODO(crbug.com/1263586): implement. +} + +} // namespace prefetch
diff --git a/chrome/browser/prefetch/prefetch_prefs.h b/chrome/browser/prefetch/prefetch_prefs.h new file mode 100644 index 0000000..4e4e9c99 --- /dev/null +++ b/chrome/browser/prefetch/prefetch_prefs.h
@@ -0,0 +1,34 @@ +// 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_PREFETCH_PREFETCH_PREFS_H_ +#define CHROME_BROWSER_PREFETCH_PREFETCH_PREFS_H_ + +class PrefService; + +namespace prefetch { + +// Enum representing possible values of the Preload Pages opt-in state. +// These values are persisted to prefs. Entries should not be renumbered and +// numeric values should never be reused. +// A Java counterpart will be generated for this enum. +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.prefetch.settings +enum class PreloadPagesState { + // The user is not opted into preloading. + NO_PRELOADING = 0, + // The user selected standard preloading. + STANDARD_PRELOADING = 1, + // The user selected extended preloading. + EXTENDED_PRELOADING = 2, + + kMaxValue = EXTENDED_PRELOADING, +}; + +PreloadPagesState GetPreloadPagesState(const PrefService& prefs); + +void SetPreloadPagesState(PrefService* prefs, PreloadPagesState state); + +} // namespace prefetch + +#endif // CHROME_BROWSER_PREFETCH_PREFETCH_PREFS_H_
diff --git a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc index 4011ff60..b6747065 100644 --- a/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc +++ b/chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_browsertest.cc
@@ -3606,50 +3606,6 @@ } IN_PROC_BROWSER_TEST_F(PrefetchProxyWithNSPBrowserTest, - DISABLE_ON_WIN_MAC_CHROMEOS(NoAppCache)) { - SetDataSaverEnabled(true); - GURL starting_page = GetOriginServerURL("/simple.html"); - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), starting_page)); - WaitForUpdatedCustomProxyConfig(); - - PrefetchProxyTabHelper* tab_helper = - PrefetchProxyTabHelper::FromWebContents(GetWebContents()); - - GURL eligible_link = - GetOriginServerURL("/prefetch/prefetch_proxy/app_cache.html"); - - TestTabHelperObserver tab_helper_observer(tab_helper); - tab_helper_observer.SetExpectedSuccessfulURLs({eligible_link}); - - base::RunLoop prefetch_run_loop; - base::RunLoop nsp_run_loop; - tab_helper_observer.SetOnPrefetchSuccessfulClosure( - prefetch_run_loop.QuitClosure()); - - tab_helper_observer.SetOnNSPFinishedClosure(nsp_run_loop.QuitClosure()); - - GURL doc_url("https://www.google.com/search?q=test"); - MakeNavigationPrediction(doc_url, {eligible_link}); - - // This run loop will quit when all the prefetch responses have been - // successfully done and processed. - prefetch_run_loop.Run(); - - std::vector<net::test_server::HttpRequest> origin_requests_before_prerender = - origin_server_requests(); - - // This run loop will quit when a NSP finishes. - nsp_run_loop.Run(); - - std::vector<net::test_server::HttpRequest> origin_requests_after_prerender = - origin_server_requests(); - - // There should not have been any additional requests. - EXPECT_EQ(origin_requests_before_prerender.size(), - origin_requests_after_prerender.size()); -} - -IN_PROC_BROWSER_TEST_F(PrefetchProxyWithNSPBrowserTest, DISABLE_ON_WIN_MAC_CHROMEOS(NoLinkRelSearch)) { SetDataSaverEnabled(true); GURL starting_page = GetOriginServerURL("/simple.html");
diff --git a/chrome/browser/printing/print_preview_dialog_controller.cc b/chrome/browser/printing/print_preview_dialog_controller.cc index 42798f81..96929c41 100644 --- a/chrome/browser/printing/print_preview_dialog_controller.cc +++ b/chrome/browser/printing/print_preview_dialog_controller.cc
@@ -344,7 +344,7 @@ void PrintPreviewDialogController::OnInitiatorNavigated( WebContents* initiator, const content::LoadCommittedDetails& details) { - if (details.type == content::NAVIGATION_TYPE_EXISTING_ENTRY) { + if (details.type == content::NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY) { static const ui::PageTransition kTransitions[] = { ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR), @@ -367,7 +367,7 @@ // New |preview_dialog| is created. Don't update/erase map entry. if (waiting_for_new_preview_page_ && ui::PageTransitionCoreTypeIs(type, ui::PAGE_TRANSITION_AUTO_TOPLEVEL) && - details.type == content::NAVIGATION_TYPE_NEW_ENTRY) { + details.type == content::NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY) { waiting_for_new_preview_page_ = false; SaveInitiatorTitle(preview_dialog); return; @@ -376,7 +376,7 @@ // Cloud print sign-in causes a reload. if (!waiting_for_new_preview_page_ && ui::PageTransitionCoreTypeIs(type, ui::PAGE_TRANSITION_RELOAD) && - details.type == content::NAVIGATION_TYPE_EXISTING_ENTRY && + details.type == content::NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY && IsPrintPreviewURL(details.previous_main_frame_url)) { return; }
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn index 04f6824..c481513 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/BUILD.gn
@@ -48,6 +48,7 @@ "dictation/macros/macro.js", "dictation/macros/macro_names.js", "dictation/macros/repeatable_key_press_macro.js", + "dictation/metrics_utils.js", "dictation/speech_parser.js", "magnifier/magnifier.js", ] @@ -166,6 +167,7 @@ "$externs_path/automation.js", "$externs_path/command_line_private.js", "$externs_path/input_method_private.js", + "$externs_path/metrics_private.js", "$externs_path/language_settings_private.js", "$externs_path/speech_recognition_private.js", ] @@ -190,6 +192,7 @@ deps = [ ":dictation_commands", ":dictation_input_controller", + ":dictation_metrics", ] externs_list = [ "$externs_path/accessibility_private.js", @@ -233,3 +236,11 @@ ":dictation_macros", ] } + +js_library("dictation_metrics") { + sources = [ "dictation/metrics_utils.js" ] + externs_list = [ + "$externs_path/metrics_private.js", + "$externs_path/speech_recognition_private.js", + ] +}
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js index 030671c..dd2e3f3 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
@@ -5,6 +5,7 @@ import {InputController} from './input_controller.js'; import {Macro} from './macros/macro.js'; import {MacroName} from './macros/macro_names.js'; +import {MetricsUtils} from './metrics_utils.js'; import {SpeechParser} from './speech_parser.js'; const ErrorEvent = chrome.speechRecognitionPrivate.SpeechRecognitionErrorEvent; @@ -12,14 +13,14 @@ chrome.speechRecognitionPrivate.SpeechRecognitionResultEvent; const StartOptions = chrome.speechRecognitionPrivate.StartOptions; const StopEvent = chrome.speechRecognitionPrivate.SpeechRecognitionStopEvent; +const SpeechRecognitionType = + chrome.speechRecognitionPrivate.SpeechRecognitionType; /** * Main class for the Chrome OS dictation feature. * Please note: this is being developed behind the flag * --enable-experimental-accessibility-dictation-extension */ -// TODO(crbug.com/1216111): Metrics and offline speech recognition -// functionality. export class Dictation { constructor() { /** @private {InputController} */ @@ -64,6 +65,9 @@ /** @private {?StartOptions} */ this.speechRecognitionOptions_ = null; + /** @private {?MetricsUtils} */ + this.metricsUtils_ = null; + this.initialize_(); } @@ -147,7 +151,7 @@ if (this.state_ === Dictation.DictationState.STARTING) { chrome.speechRecognitionPrivate.start( /** @type {!StartOptions} */ (this.speechRecognitionOptions_), - () => this.onSpeechRecognitionStarted_()); + (type) => this.onSpeechRecognitionStarted_(type)); this.setStopTimeout_(Dictation.Timeouts.NO_SPEECH_MS); } else { // We are no longer starting up - perhaps a stop came @@ -272,9 +276,10 @@ /** * Called when Speech Recognition starts up and begins listening. Passed as * a callback to speechRecognitionPrivate.start(). + * @param {SpeechRecognitionType} type The type of speech recognition used. * @private */ - onSpeechRecognitionStarted_() { + onSpeechRecognitionStarted_(type) { if (chrome.runtime.lastError) { // chrome.runtime.lastError will be set if the call to // speechRecognitionPrivate.start() caused an error. When this happens, @@ -288,9 +293,14 @@ // We tried to stop during speech shutdown. return; } + this.state_ = Dictation.DictationState.LISTENING; // Display the "....". this.clearInterimText_(); + + // Record metrics. + this.metricsUtils_ = new MetricsUtils(type, this.localePref_); + this.metricsUtils_.recordSpeechRecognitionStarted(); } /** @@ -300,6 +310,11 @@ * @private */ onSpeechRecognitionStopped_(event) { + if (this.metricsUtils_ !== null) { + this.metricsUtils_.recordSpeechRecognitionStopped(); + } + this.metricsUtils_ = null; + // Stop dictation if it wasn't already stopped. this.stopDictation_(); }
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/metrics_utils.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/metrics_utils.js new file mode 100644 index 0000000..c8c97eb --- /dev/null +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/metrics_utils.js
@@ -0,0 +1,82 @@ +// 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. + +const SpeechRecognitionType = + chrome.speechRecognitionPrivate.SpeechRecognitionType; + +/** A class used record metrics for the dictation feature. */ +export class MetricsUtils { + /** + * @param {!SpeechRecognitionType} type + * @param {string} locale + */ + constructor(type, locale) { + /** @private {boolean} */ + this.onDevice_ = type === SpeechRecognitionType.ON_DEVICE; + /** @private {string} */ + this.locale_ = locale; + /** @private {?Date} */ + this.speechRecognitionStartTime_ = null; + } + + /** Records metrics when speech recognition starts. */ + recordSpeechRecognitionStarted() { + chrome.metricsPrivate.recordBoolean( + MetricsUtils.ON_DEVICE_SPEECH_METRIC, this.onDevice_); + chrome.metricsPrivate.recordSparseHashable( + MetricsUtils.LOCALE_METRIC, this.locale_); + this.speechRecognitionStartTime_ = new Date(); + } + + /** + * Records metrics when speech recognition stops. Must be called after + * `recordSpeechRecognitionStarted` is called. + */ + recordSpeechRecognitionStopped() { + if (this.speechRecognitionStartTime_ === null) { + // Check that we have called `recordSpeechRecognitionStarted` by + // checking `speechRecognitionStartTime_`. + console.warn( + `Failed to record metrics when speech recognition stopped, valid + speech recognition start time required.`); + return; + } + + const metricName = this.onDevice_ ? + MetricsUtils.LISTENING_DURATION_METRIC_ON_DEVICE : + MetricsUtils.LISTENING_DURATION_METRIC_NETWORK; + const listeningDuration = new Date() - this.speechRecognitionStartTime_; + chrome.metricsPrivate.recordLongTime(metricName, listeningDuration); + } +} + +/** + * The metric used to record whether on-device or network speech recognition + * was used. + * @const {string} + */ +MetricsUtils.ON_DEVICE_SPEECH_METRIC = + 'Accessibility.CrosDictation.UsedOnDeviceSpeech'; + +/** + * The metric used to record which locale Dictation used for speech recognition. + * @const {string} + */ +MetricsUtils.LOCALE_METRIC = 'Accessibility.CrosDictation.Language'; + +/** + * The metric used to record the listening duration for on-device speech + * recognition. + * @const {string} + */ +MetricsUtils.LISTENING_DURATION_METRIC_ON_DEVICE = + 'Accessibility.CrosDictation.ListeningDuration.OnDeviceRecognition'; + +/** + * The metric used to record the listening duration for network speech + * recognition. + * @const {string} + */ +MetricsUtils.LISTENING_DURATION_METRIC_NETWORK = + 'Accessibility.CrosDictation.ListeningDuration.NetworkRecognition';
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common_manifest.json.jinja2 b/chrome/browser/resources/chromeos/accessibility/accessibility_common_manifest.json.jinja2 index d8425066..c9557a977 100644 --- a/chrome/browser/resources/chromeos/accessibility/accessibility_common_manifest.json.jinja2 +++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common_manifest.json.jinja2
@@ -20,6 +20,7 @@ "commandLinePrivate", "input", "inputMethodPrivate", + "metricsPrivate", "settingsPrivate", "languageSettingsPrivate", "speechRecognitionPrivate"
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js index 3bc3fc3..90f52da 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/command_handler.js
@@ -406,6 +406,16 @@ speechProps['phoneticCharacters'] = true; current = current.move(cursors.Unit.CHARACTER, dir); break; + case 'nativeNextCharacter': + case 'nativePreviousCharacter': + if (DesktopAutomationHandler.instance.textEditHandler) { + DesktopAutomationHandler.instance.textEditHandler.injectInferredIntents( + [{ + command: chrome.automation.IntentCommandType.MOVE_SELECTION, + textBoundary: chrome.automation.IntentTextBoundaryType.CHARACTER + }]); + } + return true; case 'nextWord': shouldSetSelection = true; didNavigate = true; @@ -417,6 +427,16 @@ didNavigate = true; current = current.move(cursors.Unit.WORD, dir); break; + case 'nativeNextWord': + case 'nativePreviousWord': + if (DesktopAutomationHandler.instance.textEditHandler) { + DesktopAutomationHandler.instance.textEditHandler.injectInferredIntents( + [{ + command: chrome.automation.IntentCommandType.MOVE_SELECTION, + textBoundary: chrome.automation.IntentTextBoundaryType.WORD_END + }]); + } + return true; case 'forward': case 'nextLine': didNavigate = true;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing.js index f24cff7..3d9fa202 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing.js
@@ -55,6 +55,9 @@ /** @private {AutomationEditableText} */ this.editableText_; + /** @private {!Array<AutomationIntent>} */ + this.inferredIntents_ = []; + chrome.automation.getDesktop(function(desktop) { // ChromeVox handles two general groups of text fields: // A rich text field is one where selection gets placed on a DOM @@ -103,7 +106,23 @@ return; } - this.editableText_.onUpdate(evt.intents); + let intents = evt.intents; + + // Check for inferred intents applied by other modules e.g. CommandHandler. + // Be strict about what's allowed and limit only to overriding set + // selections. + if (this.inferredIntents_.length > 0 && + (evt.intents.length === 0 || + evt.intents.some( + intent => intent.command === + chrome.automation.IntentCommandType.SET_SELECTION || + intent.command === + chrome.automation.IntentCommandType.CLEAR_SELECTION))) { + intents = this.inferredIntents_; + } + this.inferredIntents_ = []; + + this.editableText_.onUpdate(intents); } /** @@ -135,6 +154,15 @@ } /** + * Injects intents into the stream of editing events. In particular, |intents| + * will be applied to the next processed edfiting event. + * @param {!Array<AutomationIntent>} intents + */ + injectInferredIntents(intents) { + this.inferredIntents_ = intents; + } + + /** * @param {!AutomationNode} node The root editable node, i.e. the root of a * contenteditable subtree or a text field. * @return {editing.TextEditHandler}
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js index 0363c71..f560494 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/editing/editing_test.js
@@ -1682,6 +1682,67 @@ }); }); +TEST_F('ChromeVoxEditingTest', 'MoveByWordSuggestionsNoIntents', function() { + const mockFeedback = this.createMockFeedback(); + const site = ` + <div contenteditable="true" role="textbox" id="textbox"> + <p>Start</p> + <span>I </span> + <span role="suggestion" aria-description="Username"> + <span role="insertion">was</span> + <span role="deletion">am</span></span><span> typing</span> + <p>End</p> + </div> + <script> + const textbox = document.getElementById('textbox'); + let firstRightSkipped = false; + textbox.addEventListener('keydown', event => { + if (event.keyCode === 40) { + return; + } + + if (!firstRightSkipped) { + firstRightSkipped = true; + return; + } + + event.preventDefault(); + event.stopPropagation(); + + const contentEditable = document.activeElement; + const selection = getSelection(); + selection.removeAllRanges(); + const range = new Range(); + const text = contentEditable.children[2].children[0].firstChild; + range.setStart(text, 3); + range.setEnd(text, 3); + selection.addRange(range); + }); + </script> + `; + this.runWithLoadedTree(site, async function(root) { + await this.focusFirstTextField(root); + + mockFeedback.call(this.press(KeyCode.DOWN)) + .expectSpeech(' typing') + // Move forward through line. + + // This first right arrow is allowed to be processed by the content + // editable. + .call(this.press(KeyCode.RIGHT, {ctrl: true})) + .expectSpeech('I') + + // This next right is swallowed by the content editable mimicking custom + // rich editors. It manually moves selection (and looses intent data). + // We infer it by getting a command mapped for a raw control right arrow + // key. + .call(doCmd('nativeNextWord')) + .call(this.press(KeyCode.RIGHT, {ctrl: true})) + .expectSpeech('Suggest', 'Username', 'Insert', 'was', 'Insert end') + .replay(); + }); +}); + TEST_F('ChromeVoxEditingTest', 'Separator', function() { // In the past, an ARIA leaf role would cause subtree content to be removed. // However, the new decision is to not remove any content the user might
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/keymaps/key_map.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/keymaps/key_map.js index cafb4d54..c5e7cf6d 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/keymaps/key_map.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/keymaps/key_map.js
@@ -245,6 +245,14 @@ {cvoxModifier: true, keys: {keyCode: [KeyCode.LEFT], shiftKey: [true]}} }, { + command: 'nativeNextCharacter', + sequence: {cvoxModifier: false, keys: {keyCode: [KeyCode.RIGHT]}} + }, + { + command: 'nativePreviousCharacter', + sequence: {cvoxModifier: false, keys: {keyCode: [KeyCode.LEFT]}} + }, + { command: 'nextWord', sequence: { cvoxModifier: true, @@ -259,6 +267,16 @@ } }, { + command: 'nativeNextWord', + sequence: + {cvoxModifier: false, keys: {keyCode: [KeyCode.RIGHT], ctrlKey: [true]}} + }, + { + command: 'nativePreviousWord', + sequence: + {cvoxModifier: false, keys: {keyCode: [KeyCode.LEFT], ctrlKey: [true]}} + }, + { command: 'nextButton', sequence: {cvoxModifier: true, keys: {keyCode: [KeyCode.B]}} },
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_be.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_be.xtb index 58d34c7..3083fba 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_be.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_be.xtb
@@ -69,6 +69,7 @@ <translation id="1354356357730355833">скапіраваць</translation> <translation id="135978014023467274">ChromeVox абноўлены да версіі 63!</translation> <translation id="1360699455582016846">Націснуць на элемент пад ключом маршрутызацыі <ph name="ROUTING_KEY_NUMBER" /></translation> +<translation id="1376703628032300005">перайсці да наступнага сімвала</translation> <translation id="1377925789329510816">Гэта апошні загаловак. Націсніце "Пошук"+H, каб прагартаць да першага загалоўка, або "Пошук"+Shift+H, каб перайсці да другога загалоўка на гэтай старонцы.</translation> <translation id="138218114945450791">Светла-сіні</translation> <translation id="1383876407941801731">Пошук</translation> @@ -213,6 +214,7 @@ <translation id="2450814015951372393">Поле для птушкі</translation> <translation id="2461822463642141190">Цяпер</translation> <translation id="2462626033734746142">Група кнопак-пераключальнікаў</translation> +<translation id="2467741090055146971">скасаваць выбар</translation> <translation id="2471138580042810658">Загаловак 6</translation> <translation id="248982282205370495">{COUNT,plural, =1{зорачка}one{# зорачка}few{# зорачкі}many{# зорачак}other{# зорачкі}}</translation> <translation id="2490721194269245365">Ружова-карычневы</translation> @@ -566,6 +568,7 @@ <translation id="4854380505292502090">Няма папярэдняга мультымедыйнага віджэта</translation> <translation id="4855927945655956315">Асноўныя клавішы: Ctrl</translation> <translation id="4862744964787595316">Не паўтлустым шрыфтам</translation> +<translation id="4865995900839719272">перайсці на папярэдні радок</translation> <translation id="4866956062845190338">пункт меню з кнопкай-пераключальнікам</translation> <translation id="4867316986324544967">Уключыць вядзенне журнала сінтэзу маўлення</translation> <translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation> @@ -624,6 +627,7 @@ <translation id="5304943142864553931"><ph name="TITLE" />, укладка</translation> <translation id="5308380583665731573">Падключыцца</translation> <translation id="5310788376443009632">выдалены:</translation> +<translation id="5316825363044614340">перайсці на наступны радок</translation> <translation id="5320727453979144100">Рэжым заліпання клавіш уключаны</translation> <translation id="5321085947096604457">{COUNT,plural, =1{коска}one{# коска}few{# коскі}many{# косак}other{# коскі}}</translation> <translation id="532485153932049746">Фармаціраванне тэксту @@ -903,6 +907,7 @@ <translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation> <translation id="7308519659008003150">Няма папярэдняга поля формы</translation> <translation id="731121099745151312">элдрва</translation> +<translation id="7313717760367325059">паказаць даведку</translation> <translation id="7317017974771324508">часткова выбрана</translation> <translation id="7322442671176251901">Азнаямленне дотыкам</translation> <translation id="7344012264516629579">Вы можаце выкарыстоўваць дадатковыя каманды хуткага пераходу і з дапамогай іх пераходзіць да патрэбных спасылак, кнопак, палёў для птушак і не толькі. Поўны спіс каманд хуткага пераходу даступны ў меню ChromeVox. Каб адкрыць меню, націсніце Пошук + клавішу з кропкай.</translation> @@ -1130,6 +1135,7 @@ <translation id="9014206344398081366">Дапаможнік па ChromeVox</translation> <translation id="9040132695316389094">Загаловак 1</translation> <translation id="9061884144798498064">Выберыце васьмікропкавую табліцу Брайля:</translation> +<translation id="9063946545000394379">перайсці да папярэдняга сімвала</translation> <translation id="9065283790526219006">+успл.акно</translation> <translation id="9065912140022662363">Няма наступнай кнопкі-пераключальніка</translation> <translation id="9067522039955793016">Разрыў старонкі</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gl.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gl.xtb index 55d49dc..5f87baf 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gl.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_gl.xtb
@@ -69,6 +69,7 @@ <translation id="1354356357730355833">copia</translation> <translation id="135978014023467274">Instalouse a versión 63 de ChromeVox.</translation> <translation id="1360699455582016846">Fai clic no elemento situado baixo a tecla de encamiñamento <ph name="ROUTING_KEY_NUMBER" /></translation> +<translation id="1376703628032300005">moverse ao seguinte carácter</translation> <translation id="1377925789329510816">Este é o último título. Preme Buscar + H para volver ao primeiro ou Buscar + Maiúsculas + H para ir ao segundo desta páxina.</translation> <translation id="138218114945450791">Azul claro</translation> <translation id="1383876407941801731">Buscar</translation> @@ -213,6 +214,7 @@ <translation id="2450814015951372393">Caixa de verificación</translation> <translation id="2461822463642141190">Actual</translation> <translation id="2462626033734746142">Grupo de botóns de opción</translation> +<translation id="2467741090055146971">anular a selección</translation> <translation id="2471138580042810658">Título 6</translation> <translation id="248982282205370495">{COUNT,plural, =1{asterisco}other{# asteriscos}}</translation> <translation id="2490721194269245365">Marrón rosado</translation> @@ -566,6 +568,7 @@ <translation id="4854380505292502090">Non hai ningún widget multimedia anterior</translation> <translation id="4855927945655956315">Teclas esenciais: Control</translation> <translation id="4862744964787595316">Texto sen grosa</translation> +<translation id="4865995900839719272">moverse á liña anterior</translation> <translation id="4866956062845190338">rdmnuitm</translation> <translation id="4867316986324544967">Activa o rexistro de conversión de texto a voz</translation> <translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation> @@ -624,6 +627,7 @@ <translation id="5304943142864553931"><ph name="TITLE" /> (pestana)</translation> <translation id="5308380583665731573">Conectar</translation> <translation id="5310788376443009632">eliminado:</translation> +<translation id="5316825363044614340">moverse á liña seguinte</translation> <translation id="5320727453979144100">Modo de teclas presas activado</translation> <translation id="5321085947096604457">{COUNT,plural, =1{coma}other{# comas}}</translation> <translation id="532485153932049746">Formato do texto @@ -903,6 +907,7 @@ <translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation> <translation id="7308519659008003150">Non hai ningún campo de formulario anterior</translation> <translation id="731121099745151312">tritm</translation> +<translation id="7313717760367325059">axuda</translation> <translation id="7317017974771324508">seleccionado parcialmente</translation> <translation id="7322442671176251901">Exploración táctil</translation> <translation id="7344012264516629579">Os comandos de desprazamento adicionais permiten pasar dunha ligazón a outra, dun botón a outro, dunha caixa de verificación a outra… Podes consultar a lista completa nos menús de ChromeVox, que se poden abrir premendo Buscar + Punto.</translation> @@ -1130,6 +1135,7 @@ <translation id="9014206344398081366">Titorial de ChromeVox</translation> <translation id="9040132695316389094">Título 1</translation> <translation id="9061884144798498064">Selecciona unha táboa de braille de 8 puntos:</translation> +<translation id="9063946545000394379">moverse ao carácter anterior</translation> <translation id="9065283790526219006">máis compoñente emerxente</translation> <translation id="9065912140022662363">Non hai ningún botón de opción posterior</translation> <translation id="9067522039955793016">Salto de páxina</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_hr.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_hr.xtb index 5cc26fe8..4c7dd92b8 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_hr.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_hr.xtb
@@ -69,6 +69,7 @@ <translation id="1354356357730355833">kopiraj</translation> <translation id="135978014023467274">ChromeVox je ažuriran na verziju 63!</translation> <translation id="1360699455582016846">Klikanje stavke ispod tipke za usmjeravanje <ph name="ROUTING_KEY_NUMBER" /></translation> +<translation id="1376703628032300005">prijeđi na sljedeći znak</translation> <translation id="1377925789329510816">Ovo je posljednji naslov. Pritisnite tipku za pretraživanje + H za povratak na prvi naslov ili tipku za pretraživanje + Shift + H da biste prešli na drugi naslov na ovoj stranici.</translation> <translation id="138218114945450791">Svijetloplava</translation> <translation id="1383876407941801731">Traži</translation> @@ -213,6 +214,7 @@ <translation id="2450814015951372393">Potvrdni okvir</translation> <translation id="2461822463642141190">Trenutačno</translation> <translation id="2462626033734746142">Grupa izbornog gumba</translation> +<translation id="2467741090055146971">poništi odabir</translation> <translation id="2471138580042810658">Naslov 6</translation> <translation id="248982282205370495">{COUNT,plural, =1{zvjezdica}one{# zvjezdica}few{# zvjezdice}other{# zvjezdica}}</translation> <translation id="2490721194269245365">Ružičastosmeđa</translation> @@ -566,6 +568,7 @@ <translation id="4854380505292502090">Nema widgeta za prethodni medij</translation> <translation id="4855927945655956315">Ključne tipke: Control</translation> <translation id="4862744964787595316">Nepodebljano</translation> +<translation id="4865995900839719272">prijeđi na prethodni redak</translation> <translation id="4866956062845190338">rdstizb</translation> <translation id="4867316986324544967">Omogući TTS prijave</translation> <translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation> @@ -624,6 +627,7 @@ <translation id="5304943142864553931"><ph name="TITLE" />, kartica</translation> <translation id="5308380583665731573">Povežite se</translation> <translation id="5310788376443009632">uklonjeno:</translation> +<translation id="5316825363044614340">prijeđi na sljedeći redak</translation> <translation id="5320727453979144100">Ljepljiv način omogućen</translation> <translation id="5321085947096604457">{COUNT,plural, =1{zarez}one{# zarez}few{# zareza}other{# zareza}}</translation> <translation id="532485153932049746">Oblikovanje teksta @@ -903,6 +907,7 @@ <translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation> <translation id="7308519659008003150">Nema prethodnog polja obrasca</translation> <translation id="731121099745151312">stvkstab</translation> +<translation id="7313717760367325059">pomoć</translation> <translation id="7317017974771324508">djelomično odabrano</translation> <translation id="7322442671176251901">Istraži dodirom</translation> <translation id="7344012264516629579">Dodatne naredbe za preskakanje među ostalim uključuju preskakanje među vezama, gumbima i potvrdnim okvirima. Popis svih naredbi za preskakanje možete pronaći u ChromeVoxovim izbornicima, koje možete otvoriti tako da pritisnete tipku za pretraživanje i točku.</translation> @@ -1130,6 +1135,7 @@ <translation id="9014206344398081366">Vodič za ChromeVox</translation> <translation id="9040132695316389094">Naslov 1</translation> <translation id="9061884144798498064">Odaberite tablicu s 8-točkastom brajicom:</translation> +<translation id="9063946545000394379">prijeđi na prethodni znak</translation> <translation id="9065283790526219006">+ skočni prozor</translation> <translation id="9065912140022662363">Nema sljedećeg izbornog gumba</translation> <translation id="9067522039955793016">Prijelom stranice</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_hy.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_hy.xtb index e052566..68cf8183 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_hy.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_hy.xtb
@@ -389,6 +389,7 @@ <translation id="3492609944033322585">{COUNT,plural, =1{աջ փակագիծ}one{# աջ փակագիծ}other{# աջ փակագիծ}}</translation> <translation id="3494946239022273294">mnuitm</translation> <translation id="3497063866483065785">{COUNT,plural, =1{հարցական նշան}one{# հարցական նշան}other{# հարցական նշան}}</translation> +<translation id="3505359110822747654">Ծալել ChromeVox-ի ընտրացանկերը</translation> <translation id="3514822174137761109">{COUNT,plural, =1{տանիք}one{# տանիք}other{# տանիք}}</translation> <translation id="352577523970648069">խմբագրելի տեքստային դաշտ</translation> <translation id="3538907380453898475">նկարագրությունների ցանկ</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_it.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_it.xtb index 9a83fe4..850408a6 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_it.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_it.xtb
@@ -387,6 +387,7 @@ <translation id="3492609944033322585">{COUNT,plural, =1{parentesi quadra di chiusura}one{# right brackets}other{# parentesi quadre di chiusura}}</translation> <translation id="3494946239022273294">mnuitm</translation> <translation id="3497063866483065785">{COUNT,plural, =1{punto interrogativo}one{# question marks}other{# punti interrogativi}}</translation> +<translation id="3505359110822747654">Comprimi menu di ChromeVox</translation> <translation id="3514822174137761109">{COUNT,plural, =1{accento circonflesso}one{# carets}other{# accenti circonflessi}}</translation> <translation id="352577523970648069">Un campo di testo modificabile</translation> <translation id="3538907380453898475">dscrplst</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_iw.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_iw.xtb index 2e5e1b2..36869c1 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_iw.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_iw.xtb
@@ -69,6 +69,7 @@ <translation id="1354356357730355833">העתקה</translation> <translation id="135978014023467274">ChromeVox עודכן לגירסה 63.</translation> <translation id="1360699455582016846">יש ללחוץ על הפריט שמתחת למפתח הניתוב <ph name="ROUTING_KEY_NUMBER" /></translation> +<translation id="1376703628032300005">מעבר לתו הבא</translation> <translation id="1377925789329510816">זו הכותרת האחרונה. יש ללחוץ על מקש החיפוש ועל H כדי לחזור לכותרת הראשונה. לחלופין, יש ללחוץ על מקש החיפוש, על Shift ועל H כדי לעבור אל הכותרת השנייה בדף הזה.</translation> <translation id="138218114945450791">כחול בהיר</translation> <translation id="1383876407941801731">חיפוש</translation> @@ -213,6 +214,7 @@ <translation id="2450814015951372393">תיבת סימון</translation> <translation id="2461822463642141190">כרגע</translation> <translation id="2462626033734746142">קבוצת לחצני בחירה</translation> +<translation id="2467741090055146971">ביטול הבחירה</translation> <translation id="2471138580042810658">כותרת 6</translation> <translation id="248982282205370495">{COUNT,plural, =1{כוכבית}two{# סימני כוכבית}many{# סימני כוכבית}other{# סימני כוכבית}}</translation> <translation id="2490721194269245365">חום ורוד</translation> @@ -566,6 +568,7 @@ <translation id="4854380505292502090">אין ווידג'ט קודם של מדיה</translation> <translation id="4855927945655956315">מקשים חיוניים: Control</translation> <translation id="4862744964787595316">לא מודגש</translation> +<translation id="4865995900839719272">מעבר לשורה הקודמת</translation> <translation id="4866956062845190338">rdmnuitm</translation> <translation id="4867316986324544967">אפשר רישום TTS</translation> <translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation> @@ -624,6 +627,7 @@ <translation id="5304943142864553931"><ph name="TITLE" />, כרטיסייה</translation> <translation id="5308380583665731573">התחברות</translation> <translation id="5310788376443009632">הוסר:</translation> +<translation id="5316825363044614340">מעבר לשורה הבאה</translation> <translation id="5320727453979144100">מצב דביק מופעל</translation> <translation id="5321085947096604457">{COUNT,plural, =1{פסיק}two{# פסיקים}many{# פסיקים}other{# פסיקים}}</translation> <translation id="532485153932049746">עיצוב טקסט @@ -903,6 +907,7 @@ <translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation> <translation id="7308519659008003150">אין שדה טופס קודם</translation> <translation id="731121099745151312">tritm</translation> +<translation id="7313717760367325059">עזרה</translation> <translation id="7317017974771324508">נבחר באופן חלקי</translation> <translation id="7322442671176251901">גילוי באמצעות מגע</translation> <translation id="7344012264516629579">דוגמאות לפקודות קפיצה נוספות: קפיצה באמצעות קישור, לחצן או תיבת סימון. רשימה מלאה של פקודות קפיצה מופיעה בתפריטי ChromeVox, שאותם ניתן לפתוח על ידי הקשה על מקש החיפוש ועל מקש הנקודה.</translation> @@ -1130,6 +1135,7 @@ <translation id="9014206344398081366">מדריך של ChromeVox</translation> <translation id="9040132695316389094">כותרת 1</translation> <translation id="9061884144798498064">יש לבחור טבלת ברייל 8 נקודות:</translation> +<translation id="9063946545000394379">מעבר לתו הקודם</translation> <translation id="9065283790526219006">+popup</translation> <translation id="9065912140022662363">אין עוד לחצני בחירה</translation> <translation id="9067522039955793016">מעבר דף</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_mk.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_mk.xtb index bf217579..af801d6a 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_mk.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_mk.xtb
@@ -389,6 +389,7 @@ <translation id="3492609944033322585">{COUNT,plural, =1{десна заграда}one{# десна заграда}other{# десни загради}}</translation> <translation id="3494946239022273294">mnuitm</translation> <translation id="3497063866483065785">{COUNT,plural, =1{прашалник}one{# прашалник}other{# прашалници}}</translation> +<translation id="3505359110822747654">Менијата на ChromeVox се собираат</translation> <translation id="3514822174137761109">{COUNT,plural, =1{карет }one{# карет}other{# карети}}</translation> <translation id="352577523970648069">Текстуално поле за уредување</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_sv.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_sv.xtb index 99d9e4c..e2f5ce6 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_sv.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_sv.xtb
@@ -69,6 +69,7 @@ <translation id="1354356357730355833">kopiera</translation> <translation id="135978014023467274">Du har uppdaterat till ChromeVox 63.</translation> <translation id="1360699455582016846">Klicka på objektet under markörhämtaren <ph name="ROUTING_KEY_NUMBER" /></translation> +<translation id="1376703628032300005">flytta till nästa tecken</translation> <translation id="1377925789329510816">Det här är den sista rubriken. Tryck på söktangenten + H för fortsätta runt tillbaka till den första rubriken eller på söktangenten + Skift + H för att fortsätta till den andra rubriken på den här sidan.</translation> <translation id="138218114945450791">Ljusblå</translation> <translation id="1383876407941801731">Sök</translation> @@ -213,6 +214,7 @@ <translation id="2450814015951372393">Kryssruta</translation> <translation id="2461822463642141190">Nuvarande</translation> <translation id="2462626033734746142">Alternativknappsgrupp</translation> +<translation id="2467741090055146971">avmarkera</translation> <translation id="2471138580042810658">Rubrik 6</translation> <translation id="248982282205370495">{COUNT,plural, =1{asterisk}other{# asterisker}}</translation> <translation id="2490721194269245365">Brunrosa</translation> @@ -566,6 +568,7 @@ <translation id="4854380505292502090">Det finns ingen föregående mediewidget</translation> <translation id="4855927945655956315">Viktiga tangenter: Ctrl</translation> <translation id="4862744964787595316">Inte fetstilt</translation> +<translation id="4865995900839719272">flytta till föregående rad</translation> <translation id="4866956062845190338">menyalternativ med alternativknapp</translation> <translation id="4867316986324544967">Aktivera loggning av text-till-tal</translation> <translation id="4886524826165775965"><ph name="INDEX" />/<ph name="TOTAL" /></translation> @@ -624,6 +627,7 @@ <translation id="5304943142864553931">Fliken <ph name="TITLE" /></translation> <translation id="5308380583665731573">Anslut</translation> <translation id="5310788376443009632">har tagits bort:</translation> +<translation id="5316825363044614340">flytta till nästa rad</translation> <translation id="5320727453979144100">Låsta knappar har aktiverats</translation> <translation id="5321085947096604457">{COUNT,plural, =1{komma}other{# komman}}</translation> <translation id="532485153932049746">Textformatering @@ -903,6 +907,7 @@ <translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation> <translation id="7308519659008003150">Det finns inget föregående formulärfält</translation> <translation id="731121099745151312">trädobjekt</translation> +<translation id="7313717760367325059">hjälp</translation> <translation id="7317017974771324508">delvis vald</translation> <translation id="7322442671176251901">Explore by touch</translation> <translation id="7344012264516629579">Exempel på ytterligare hoppkommandon är via en länk, en knapp eller en kryssruta. En komplett lista över hoppkommandon finns i ChromeVox-menyerna, som du kan öppna genom att trycka på Sök + punkt.</translation> @@ -1130,6 +1135,7 @@ <translation id="9014206344398081366">Självstudier för ChromeVox</translation> <translation id="9040132695316389094">Rubrik 1</translation> <translation id="9061884144798498064">Välj punktskrift med åtta punkter:</translation> +<translation id="9063946545000394379">flytta till föregående tecken</translation> <translation id="9065283790526219006">+popup</translation> <translation id="9065912140022662363">Det finns inga fler alternativknappar</translation> <translation id="9067522039955793016">Sidbrytning</translation>
diff --git a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_tr.xtb b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_tr.xtb index 8295e6c..e077559f 100644 --- a/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_tr.xtb +++ b/chrome/browser/resources/chromeos/accessibility/strings/accessibility_strings_tr.xtb
@@ -69,6 +69,7 @@ <translation id="1354356357730355833">kopyala</translation> <translation id="135978014023467274">ChromeVox 63 sürümüne güncellendi!</translation> <translation id="1360699455582016846"><ph name="ROUTING_KEY_NUMBER" /> yönlendirme tuşunun altındaki öğeyi tıklayın</translation> +<translation id="1376703628032300005">sonraki karaktere git</translation> <translation id="1377925789329510816">Bu son başlık. Bu sayfadaki ilk başlığa dönmek için Ara+H tuşlarına ya da ikinci başlığa gitmek için Ara+Üst Karakter+H tuşlarına basın.</translation> <translation id="138218114945450791">Açık Mavi</translation> <translation id="1383876407941801731">Ara</translation> @@ -213,6 +214,7 @@ <translation id="2450814015951372393">Onay kutusu</translation> <translation id="2461822463642141190">Mevcut güç tüketimi</translation> <translation id="2462626033734746142">Radyo düğmesi grubu</translation> +<translation id="2467741090055146971">seçimi kaldır</translation> <translation id="2471138580042810658">Başlık 6</translation> <translation id="248982282205370495">{COUNT,plural, =1{yıldız işareti}other{# yıldız işareti}}</translation> <translation id="2490721194269245365">Pembemsi Kahverengi</translation> @@ -566,6 +568,7 @@ <translation id="4854380505292502090">Önceki media widget'ı yok</translation> <translation id="4855927945655956315">Temel Tuşlar: Control</translation> <translation id="4862744964787595316">Kalın değil</translation> +<translation id="4865995900839719272">önceki satıra git</translation> <translation id="4866956062845190338">rdmnuitm</translation> <translation id="4867316986324544967">TTS günlük kaydını etkinleştir</translation> <translation id="4886524826165775965"><ph name="INDEX" /> / <ph name="TOTAL" /></translation> @@ -624,6 +627,7 @@ <translation id="5304943142864553931"><ph name="TITLE" />, sekme</translation> <translation id="5308380583665731573">Bağlan</translation> <translation id="5310788376443009632">kaldırıldı:</translation> +<translation id="5316825363044614340">sonraki satıra git</translation> <translation id="5320727453979144100">Yapışkan mod etkinleştirildi</translation> <translation id="5321085947096604457">{COUNT,plural, =1{virgül}other{# virgül}}</translation> <translation id="532485153932049746">Metin biçimlendirme @@ -903,6 +907,7 @@ <translation id="7292195267473691167"><ph name="LOCALE" /> (<ph name="VARIANT" />)</translation> <translation id="7308519659008003150">Önceki form alanı yok</translation> <translation id="731121099745151312">tritm</translation> +<translation id="7313717760367325059">yardım</translation> <translation id="7317017974771324508">kısmen seçildi</translation> <translation id="7322442671176251901">Dokunarak keşfetme</translation> <translation id="7344012264516629579">Bağlantılar, düğmeler ve onay kutuları arasında atlama, diğer atlama komutlarından bazılarıdır. Atlama komutlarının tam listesini ChromeVox menülerinde bulabilirsiniz. Bu menüleri açmak için Arama + Nokta tuşlarına basabilirsiniz.</translation> @@ -1129,6 +1134,7 @@ <translation id="9014206344398081366">ChromeVox eğitimi</translation> <translation id="9040132695316389094">Başlık 1</translation> <translation id="9061884144798498064">8 noktalı bir braille tablosu seçin:</translation> +<translation id="9063946545000394379">önceki karaktere git</translation> <translation id="9065283790526219006">+popup</translation> <translation id="9065912140022662363">Sonraki radyo düğmesi yok</translation> <translation id="9067522039955793016">Sayfa sonu</translation>
diff --git a/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.html b/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.html index fb28589..6632716 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.html +++ b/chrome/browser/resources/chromeos/login/screens/common/consolidated_consent.html
@@ -329,7 +329,8 @@ <oobe-modal-dialog id="locationLearnMorePopUp"> <div slot="content"> <span - inner-h-t-m-l="[[getLocationLearnMoreText_(locale)]]"> + inner-h-t-m-l="[[getLocationLearnMoreText_(locale, + isChildAccount_)]]"> </span> </div> </oobe-modal-dialog>
diff --git a/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.html b/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.html index 2660cb726..3979ccb 100644 --- a/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.html +++ b/chrome/browser/resources/settings/chromeos/os_privacy_page/smart_privacy_page.html
@@ -1,6 +1,69 @@ -<style include="settings-shared"></style> +<style include="settings-shared"> + cr-radio-group { + display: flex; + flex-flow: column wrap; + } + + .underbar { + border-bottom: var(--cr-separator-line); + } + + .left-float-graphic { + float: left; + height: 200px; + margin-inline-end: 10px; + } + + .large-icon { + --iron-icon-fill-color: var(--cros-icon-color-prominent); + --iron-icon-stroke-color: var(--cros-icon-color-prominent); + --iron-icon-height: 32px; + --iron-icon-width: 32px; + margin-bottom: 10px; + } + + .banner { + display: inline-block; + margin: 0 0 10px 0; + padding: 0 10px 10px 10px; + } +</style> + +<div class="banner underbar"> + <!-- No alt since image is purely decorative. --> + <img class="left-float-graphic" + src="chrome://os-settings/images/smart_privacy.svg" + alt="" aria-hidden="true"> + <div> + <iron-icon class="large-icon" icon="cr:security"> + </iron-icon> + </div> + <div> + $i18n{smartPrivacyDesc} + </div> +</div> +<!-- TODO(crbug.com/1262869): Currently inert. Once the screen dim + feature has an associated preference, + reference it from here. --> +<settings-toggle-button class="underbar" + label="$i18n{smartPrivacyScreenLockTitle}" + sub-label="$i18n{smartPrivacyScreenLockSubtext}"> +</settings-toggle-button> <settings-toggle-button pref="{{prefs.ash.privacy.snooping_protection_enabled}}" label="$i18n{smartPrivacySnoopingTitle}" sub-label="$i18n{smartPrivacySnoopingSubtext}"> </settings-toggle-button> +<iron-collapse id="snoopingProtectionOptions" + opened="[[prefs.ash.privacy.snooping_protection_enabled.value]]"> + <div class="settings-box continuation embedded"> + <cr-radio-group> + <cr-radio-button name="dim" class="list-item" + label="$i18n{smartPrivacySnoopingDim}"> + </cr-radio-button> + <cr-radio-button name="icon" class="list-item" + label="$i18n{smartPrivacySnoopingIcon}"> + </cr-radio-button> + </cr-radio-group> + </div> +</iron-collapse>
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index 6f55fda4..fe7640f 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -62,7 +62,8 @@ </template> <iph-bubble id="iphBubble" anchor-id="cookiesLinkRow" - body="Click on the "Cookies and other site data" section"> + body="Click on the "Cookies and other site data" section" + position="below"> </iph-bubble> <cr-link-row id="cookiesLinkRow" start-icon="settings:cookie" class="hr" label="$i18n{cookiePageTitle}"
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc index 0ee614e..206b0a0 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.cc
@@ -23,8 +23,13 @@ ExtensionTelemetryService::~ExtensionTelemetryService() = default; -ExtensionTelemetryService::ExtensionTelemetryService(Profile* profile) +ExtensionTelemetryService::ExtensionTelemetryService( + Profile* profile, + extensions::ExtensionRegistry* extension_registry, + extensions::ExtensionPrefs* extension_prefs) : profile_(profile), + extension_registry_(extension_registry), + extension_prefs_(extension_prefs), enabled_(false), current_reporting_interval_( base::Seconds(kExtensionTelemetryUploadIntervalSeconds.Get())) { @@ -90,8 +95,13 @@ // the case where the extension is uninstalled after generating the signal // but before a report is generated. The extension information is also // cleared after each telemetry report is sent to keep the data fresh. + const extensions::Extension* extension = + extension_registry_->GetInstalledExtension(signal->extension_id()); + // The signal is added synchronously and it should never be reported for + // a non-existent extension. + DCHECK(extension); extension_store_.emplace(signal->extension_id(), - GetExtensionInfoForReport(signal->extension_id())); + GetExtensionInfoForReport(*extension)); } processor.ProcessSignal(std::move(signal)); @@ -110,19 +120,22 @@ std::unique_ptr<ExtensionTelemetryReportRequest> ExtensionTelemetryService::CreateReport() { - if (extension_store_.empty()) + // Don't create a telemetry report if there were no signals generated (i.e., + // extension store is empty) AND there are no installed extensions currently. + std::unique_ptr<extensions::ExtensionSet> installed_extensions = + extension_registry_->GenerateInstalledExtensionsSet(); + if (extension_store_.empty() && installed_extensions->is_empty()) return nullptr; - // Create a telemetry report containing signal data for extension ids - // in the extension store (the extensions that triggered signals). using google::protobuf::RepeatedPtrField; auto telemetry_report_pb = std::make_unique<ExtensionTelemetryReportRequest>(); RepeatedPtrField<ExtensionTelemetryReportRequest_Report>* reports_pb = telemetry_report_pb->mutable_reports(); + // Create per-extension reports for all the extensions in the extension store. + // These represent extensions that have signal information to report. for (auto& extension_store_it : extension_store_) { - // Create a per-extension report. auto report_entry_pb = std::make_unique<ExtensionTelemetryReportRequest_Report>(); @@ -144,37 +157,46 @@ reports_pb->AddAllocated(report_entry_pb.release()); } - telemetry_report_pb->set_creation_timestamp_msec( - base::Time::Now().ToJavaTime()); + // Create per-extension reports for all the installed extensions. Exclude + // extension store extensions since reports have already been created for + // them. Note that these installed extension reports will only contain + // extension information (and no signal data). + for (const auto& entry : extension_store_) { + installed_extensions->Remove(entry.first /* extension_id */); + } + + for (const scoped_refptr<const extensions::Extension> installed_entry : + *installed_extensions) { + auto report_entry_pb = + std::make_unique<ExtensionTelemetryReportRequest_Report>(); + + report_entry_pb->set_allocated_extension( + GetExtensionInfoForReport(*installed_entry.get()).release()); + reports_pb->AddAllocated(report_entry_pb.release()); + } + + DCHECK(reports_pb->size() > 0); // Clear out the extension store data to ensure that: // - extension info is refreshed for every telemetry report. // - no stale extension entry is left over in the extension store. extension_store_.clear(); + telemetry_report_pb->set_creation_timestamp_msec( + base::Time::Now().ToJavaTime()); return telemetry_report_pb; } std::unique_ptr<ExtensionTelemetryReportRequest_ExtensionInfo> ExtensionTelemetryService::GetExtensionInfoForReport( - const extensions::ExtensionId& extension_id) { + const extensions::Extension& extension) { auto extension_info = std::make_unique<ExtensionTelemetryReportRequest_ExtensionInfo>(); - extension_info->set_id(extension_id); - extensions::ExtensionPrefs* extension_prefs = - extensions::ExtensionPrefs::Get(profile_); - extensions::ExtensionRegistry* extension_registry = - extensions::ExtensionRegistry::Get(profile_); - const extensions::Extension* extension = - extension_registry->GetInstalledExtension(extension_id); - // The ExtensionStore entry is always created synchronously from a signal - // being reported, and signals should never be reported for non-existent - // extensions. - DCHECK(extension); - extension_info->set_name(extension->name()); - extension_info->set_version(extension->version().GetString()); + extension_info->set_id(extension.id()); + extension_info->set_name(extension.name()); + extension_info->set_version(extension.version().GetString()); extension_info->set_install_timestamp_msec( - extension_prefs->GetInstallTime(extension->id()).ToJavaTime()); + extension_prefs_->GetInstallTime(extension.id()).ToJavaTime()); return extension_info; }
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h index 4a613feb..330836f 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service.h
@@ -19,6 +19,12 @@ class Profile; class PrefService; +namespace extensions { +class Extension; +class ExtensionPrefs; +class ExtensionRegistry; +} // namespace extensions + namespace safe_browsing { enum class ExtensionSignalType; @@ -42,7 +48,9 @@ // signals are ignored and no reports are sent to the SB servers. class ExtensionTelemetryService : public KeyedService { public: - explicit ExtensionTelemetryService(Profile* profile); + ExtensionTelemetryService(Profile* profile, + extensions::ExtensionRegistry* extension_registry, + extensions::ExtensionPrefs* extension_prefs); ExtensionTelemetryService(const ExtensionTelemetryService&) = delete; ExtensionTelemetryService& operator=(const ExtensionTelemetryService&) = @@ -71,13 +79,14 @@ // Creates and uploads telemetry reports. void CreateAndUploadReports(); - // Creates telemetry report protobuf from extension store data and - // data retrieved from signal processors. + // Creates telemetry report protobuf for all extension store extensions + // and currently installed extensions along with signal data retrieved from + // signal processors. std::unique_ptr<ExtensionTelemetryReportRequest> CreateReport(); // Collects extension information for reporting. std::unique_ptr<ExtensionTelemetryReportRequest_ExtensionInfo> - GetExtensionInfoForReport(const extensions::ExtensionId& extension_id); + GetExtensionInfoForReport(const extensions::Extension& extension); // Records UMA metric: signal type. void RecordSignalType(ExtensionSignalType signal_type); @@ -91,6 +100,10 @@ // Observes changes to kSafeBrowsingEnhanced. PrefChangeRegistrar pref_change_registrar_; + // Unowned objects used for getting extension information. + extensions::ExtensionRegistry* const extension_registry_; + extensions::ExtensionPrefs* const extension_prefs_; + // Keeps track of the state of the service. bool enabled_;
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_factory.cc b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_factory.cc index 6dce463..6bec847 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_factory.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_factory.cc
@@ -12,7 +12,9 @@ #include "components/safe_browsing/core/common/features.h" #include "components/safe_browsing/core/common/utils.h" #include "content/public/browser/browser_context.h" +#include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_prefs_factory.h" +#include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_registry_factory.h" namespace safe_browsing { @@ -44,7 +46,9 @@ if (!base::FeatureList::IsEnabled(kExtensionTelemetry)) return nullptr; Profile* profile = Profile::FromBrowserContext(context); - return new ExtensionTelemetryService(profile); + return new ExtensionTelemetryService( + profile, extensions::ExtensionRegistry::Get(context), + extensions::ExtensionPrefs::Get(context)); } } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_unittest.cc b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_unittest.cc index 7ded33c..1b3abc25 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_unittest.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/extension_telemetry_service_unittest.cc
@@ -25,8 +25,10 @@ namespace { -constexpr const char kExtensionId[] = "aaaabbbbccccddddeeeeffffgggghhhh"; -constexpr const char kExtensionName[] = "Test Extension"; +constexpr const char* kExtensionId[] = {"aaaaaaaabbbbbbbbccccccccdddddddd", + "eeeeeeeeffffffffgggggggghhhhhhhh"}; +constexpr const char* kExtensionName[] = {"Test Extension 1", + "Test Extension 2"}; constexpr const char kExtensionVersion[] = "1"; constexpr const char kScriptCode[] = "document.write('Hello World')"; @@ -35,21 +37,27 @@ class ExtensionTelemetryServiceTest : public ::testing::Test { protected: ExtensionTelemetryServiceTest(); - void RegisterExtensionWithExtensionService( - const extensions::ExtensionId& extension_id = kExtensionId, - const std::string& extension_name = kExtensionName, - const base::Time& install_time = base::Time::Now(), - const std::string& version = kExtensionVersion); - void PrimeTelemetryServiceWithSignal(); - void SetUp() override { ASSERT_NE(telemetry_service_, nullptr); } + void RegisterExtensionWithExtensionService( + const extensions::ExtensionId& extension_id, + const std::string& extension_name, + const base::Time& install_time, + const std::string& version); + void UnregisterExtensionWithExtensionService( + const extensions::ExtensionId& extension_id); + void PrimeTelemetryServiceWithSignal(); + bool IsTelemetryServiceEnabled() { return telemetry_service_->enabled() && !telemetry_service_->signal_processors_.empty() && telemetry_service_->timer_.IsRunning(); } + bool IsExtensionStoreEmpty() { + return telemetry_service_->extension_store_.empty(); + } + using ExtensionInfo = ExtensionTelemetryReportRequest_ExtensionInfo; const ExtensionInfo* GetExtensionInfoFromExtensionStore( const extensions::ExtensionId& extension_id) { @@ -69,13 +77,19 @@ std::unique_ptr<ExtensionTelemetryService> telemetry_service_; extensions::ExtensionService* extension_service_; extensions::ExtensionPrefs* extension_prefs_; + extensions::ExtensionRegistry* extension_registry_; }; ExtensionTelemetryServiceTest::ExtensionTelemetryServiceTest() : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) { + // Create extension prefs and registry instances. + extension_prefs_ = extensions::ExtensionPrefs::Get(&profile_); + extension_registry_ = extensions::ExtensionRegistry::Get(&profile_); + // Create telemetry service instance. profile_.GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnhanced, true); - telemetry_service_ = std::make_unique<ExtensionTelemetryService>(&profile_); + telemetry_service_ = std::make_unique<ExtensionTelemetryService>( + &profile_, extension_registry_, extension_prefs_); // Create fake extension service instance. base::CommandLine command_line(base::CommandLine::NO_PROGRAM); @@ -85,11 +99,11 @@ &command_line, base::FilePath() /* install_directory */, false /* autoupdate_enabled */); - // Create extension prefs instance. - extension_prefs_ = extensions::ExtensionPrefs::Get(&profile_); - - // Register a test extension with the fake extension service. - RegisterExtensionWithExtensionService(); + // Register test extensions with the extension service. + RegisterExtensionWithExtensionService(kExtensionId[0], kExtensionName[0], + base::Time::Now(), kExtensionVersion); + RegisterExtensionWithExtensionService(kExtensionId[1], kExtensionName[1], + base::Time::Now(), kExtensionVersion); } void ExtensionTelemetryServiceTest::RegisterExtensionWithExtensionService( @@ -116,13 +130,20 @@ base::NumberToString(install_time.ToJavaTime()))); } +void ExtensionTelemetryServiceTest::UnregisterExtensionWithExtensionService( + const extensions::ExtensionId& extension_id) { + extension_service_->UnloadExtension( + extension_id, extensions::UnloadedExtensionReason::UNINSTALL); + extension_prefs_->DeleteExtensionPrefs(extension_id); +} + void ExtensionTelemetryServiceTest::PrimeTelemetryServiceWithSignal() { // Verify that service is enabled. EXPECT_TRUE(IsTelemetryServiceEnabled()); // Add a tabs.executeScript API invocation signal to the telemetry service. auto signal = - std::make_unique<TabsExecuteScriptSignal>(kExtensionId, kScriptCode); + std::make_unique<TabsExecuteScriptSignal>(kExtensionId[0], kScriptCode); telemetry_service_->AddSignal(std::move(signal)); } @@ -136,7 +157,8 @@ EXPECT_FALSE(IsTelemetryServiceEnabled()); // Destruct and restart service and verify that it starts disabled. - telemetry_service_ = std::make_unique<ExtensionTelemetryService>(&profile_); + telemetry_service_ = std::make_unique<ExtensionTelemetryService>( + &profile_, extension_registry_, extension_prefs_); EXPECT_FALSE(IsTelemetryServiceEnabled()); // Re-enable ESB, service should become enabled. @@ -148,32 +170,14 @@ PrimeTelemetryServiceWithSignal(); // Verify that the registered extension information is saved in the // telemetry service's extension store. - const ExtensionInfo* info = GetExtensionInfoFromExtensionStore(kExtensionId); + const ExtensionInfo* info = + GetExtensionInfoFromExtensionStore(kExtensionId[0]); ASSERT_NE(info, nullptr); - EXPECT_EQ(info->id(), kExtensionId); - EXPECT_EQ(info->name(), kExtensionName); + EXPECT_EQ(info->id(), kExtensionId[0]); + EXPECT_EQ(info->name(), kExtensionName[0]); EXPECT_EQ(info->version(), kExtensionVersion); EXPECT_EQ(info->install_timestamp_msec(), - extension_prefs_->GetInstallTime(kExtensionId).ToJavaTime()); -} - -TEST_F(ExtensionTelemetryServiceTest, GeneratesTelemetryReport) { - PrimeTelemetryServiceWithSignal(); - // Verify the contents of telemetry report generated. - std::unique_ptr<TelemetryReport> telemetry_report_pb = GetTelemetryReport(); - ASSERT_NE(telemetry_report_pb, nullptr); - ASSERT_EQ(telemetry_report_pb->reports_size(), 1); - EXPECT_EQ(telemetry_report_pb->reports(0).extension().id(), kExtensionId); - EXPECT_EQ(telemetry_report_pb->reports(0).extension().name(), kExtensionName); - EXPECT_EQ(telemetry_report_pb->reports(0).extension().version(), - kExtensionVersion); - EXPECT_EQ( - telemetry_report_pb->reports(0).extension().install_timestamp_msec(), - extension_prefs_->GetInstallTime(kExtensionId).ToJavaTime()); - // Verify that extension store contents have been cleared after creating a - // telemetry report. - const ExtensionInfo* info = GetExtensionInfoFromExtensionStore(kExtensionId); - EXPECT_EQ(info, nullptr); + extension_prefs_->GetInstallTime(kExtensionId[0]).ToJavaTime()); } TEST_F(ExtensionTelemetryServiceTest, GeneratesReportAtProperIntervals) { @@ -181,7 +185,7 @@ PrimeTelemetryServiceWithSignal(); { const ExtensionInfo* info = - GetExtensionInfoFromExtensionStore(kExtensionId); + GetExtensionInfoFromExtensionStore(kExtensionId[0]); EXPECT_NE(info, nullptr); } // Check that extension store still has extension info stored before @@ -190,17 +194,88 @@ task_environment_.FastForwardBy(interval - base::Seconds(1)); { const ExtensionInfo* info = - GetExtensionInfoFromExtensionStore(kExtensionId); + GetExtensionInfoFromExtensionStore(kExtensionId[0]); EXPECT_NE(info, nullptr); } // Check that extension store is cleared after reporting interval elapses. task_environment_.FastForwardBy(base::Seconds(1)); { const ExtensionInfo* info = - GetExtensionInfoFromExtensionStore(kExtensionId); + GetExtensionInfoFromExtensionStore(kExtensionId[0]); EXPECT_EQ(info, nullptr); } } } +TEST_F(ExtensionTelemetryServiceTest, DoesNotGenerateEmptyTelemetryReport) { + // Check that telemetry service does not generate a telemetry report + // when there are no signals and no installed extensions. + UnregisterExtensionWithExtensionService(kExtensionId[0]); + UnregisterExtensionWithExtensionService(kExtensionId[1]); + task_environment_.FastForwardBy( + telemetry_service_->current_reporting_interval()); + + // Verify that no telemetry report is generated. + EXPECT_FALSE(GetTelemetryReport()); +} + +TEST_F(ExtensionTelemetryServiceTest, GeneratesTelemetryReportWithNoSignals) { + // Check that telemetry service generates a telemetry report even when + // there are no signals to report. The report consists of only extension + // info for the installed extensions. + task_environment_.FastForwardBy( + telemetry_service_->current_reporting_interval()); + // Verify the contents of telemetry report generated. + std::unique_ptr<TelemetryReport> telemetry_report_pb = GetTelemetryReport(); + ASSERT_NE(telemetry_report_pb, nullptr); + // Telemetry report should contain reports for both test extensions. + ASSERT_EQ(telemetry_report_pb->reports_size(), 2); + for (int i = 0; i < 2; i++) { + EXPECT_EQ(telemetry_report_pb->reports(i).extension().id(), + kExtensionId[i]); + EXPECT_EQ(telemetry_report_pb->reports(i).extension().name(), + kExtensionName[i]); + EXPECT_EQ(telemetry_report_pb->reports(i).extension().version(), + kExtensionVersion); + EXPECT_EQ( + telemetry_report_pb->reports(i).extension().install_timestamp_msec(), + extension_prefs_->GetInstallTime(kExtensionId[i]).ToJavaTime()); + // Verify that there is no signal data associated with the extension. + EXPECT_EQ(telemetry_report_pb->reports(i).signals().size(), 0); + } + + // Verify that extension store has been cleared after creating a telemetry + // report. + EXPECT_TRUE(IsExtensionStoreEmpty()); +} + +TEST_F(ExtensionTelemetryServiceTest, GeneratesTelemetryReportWithSignal) { + PrimeTelemetryServiceWithSignal(); + // Verify the contents of telemetry report generated. + std::unique_ptr<TelemetryReport> telemetry_report_pb = GetTelemetryReport(); + ASSERT_NE(telemetry_report_pb, nullptr); + // Telemetry report should contain reports for both test extensions. + ASSERT_EQ(telemetry_report_pb->reports_size(), 2); + for (int i = 0; i < 2; i++) { + EXPECT_EQ(telemetry_report_pb->reports(i).extension().id(), + kExtensionId[i]); + EXPECT_EQ(telemetry_report_pb->reports(i).extension().name(), + kExtensionName[i]); + EXPECT_EQ(telemetry_report_pb->reports(i).extension().version(), + kExtensionVersion); + EXPECT_EQ( + telemetry_report_pb->reports(i).extension().install_timestamp_msec(), + extension_prefs_->GetInstallTime(kExtensionId[i]).ToJavaTime()); + } + + // Verify that first extension's report has signal data. + EXPECT_EQ(telemetry_report_pb->reports(0).signals().size(), 1); + // Verify that second extension's report has no signal data. + EXPECT_EQ(telemetry_report_pb->reports(1).signals().size(), 0); + + // Verify that extension store has been cleared after creating a telemetry + // report. + EXPECT_TRUE(IsExtensionStoreEmpty()); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/extension_telemetry/tabs_execute_script_signal_processor_unittest.cc b/chrome/browser/safe_browsing/extension_telemetry/tabs_execute_script_signal_processor_unittest.cc index 8cb56de..cd84901a 100644 --- a/chrome/browser/safe_browsing/extension_telemetry/tabs_execute_script_signal_processor_unittest.cc +++ b/chrome/browser/safe_browsing/extension_telemetry/tabs_execute_script_signal_processor_unittest.cc
@@ -32,30 +32,29 @@ class TabsExecuteScriptSignalProcessorTest : public ::testing::Test { protected: TabsExecuteScriptSignalProcessorTest() - : processor_(std::make_unique<TabsExecuteScriptSignalProcessor>()), - script_data_{{ScriptData("document.write('Hello World')")}, + : script_data_{{ScriptData("document.write('Hello World')")}, {ScriptData("document.write('Goodbye World')")}} {} - const std::unique_ptr<TabsExecuteScriptSignalProcessor> processor_; + TabsExecuteScriptSignalProcessor processor_; const ScriptData script_data_[2]; }; TEST_F(TabsExecuteScriptSignalProcessorTest, NoDataPresentInitially) { - EXPECT_FALSE(processor_->HasDataToReportForTest()); + EXPECT_FALSE(processor_.HasDataToReportForTest()); } TEST_F(TabsExecuteScriptSignalProcessorTest, StoresDataAfterProcessingSignal) { // Process a signal. auto signal = std::make_unique<TabsExecuteScriptSignal>(kExtensionId[0], script_data_[0].code); - processor_->ProcessSignal(std::move(signal)); + processor_.ProcessSignal(std::move(signal)); // Verify that processor now has some data to report. - EXPECT_TRUE(processor_->HasDataToReportForTest()); + EXPECT_TRUE(processor_.HasDataToReportForTest()); // Verify that there is signal info only for the correct extension id. - EXPECT_TRUE(processor_->GetSignalInfoForReport(kExtensionId[0])); - EXPECT_FALSE(processor_->GetSignalInfoForReport(kExtensionId[1])); + EXPECT_TRUE(processor_.GetSignalInfoForReport(kExtensionId[0])); + EXPECT_FALSE(processor_.GetSignalInfoForReport(kExtensionId[1])); } TEST_F(TabsExecuteScriptSignalProcessorTest, ReportsSignalInfoCorrectly) { @@ -64,7 +63,7 @@ for (int i = 0; i < 3; i++) { auto signal = std::make_unique<TabsExecuteScriptSignal>( kExtensionId[0], script_data_[0].code); - processor_->ProcessSignal(std::move(signal)); + processor_.ProcessSignal(std::move(signal)); } // Process 3 signals for second extension. Two signal corresponds to the @@ -72,29 +71,29 @@ for (int i = 0; i < 2; i++) { auto signal = std::make_unique<TabsExecuteScriptSignal>( kExtensionId[1], script_data_[0].code); - processor_->ProcessSignal(std::move(signal)); + processor_.ProcessSignal(std::move(signal)); } { auto signal = std::make_unique<TabsExecuteScriptSignal>( kExtensionId[1], script_data_[1].code); - processor_->ProcessSignal(std::move(signal)); + processor_.ProcessSignal(std::move(signal)); } // Retrieve signal info for first extension. std::unique_ptr<SignalInfo> extension_0_signal_info = - processor_->GetSignalInfoForReport(kExtensionId[0]); + processor_.GetSignalInfoForReport(kExtensionId[0]); ASSERT_NE(extension_0_signal_info, nullptr); // Verify that processor still has some data to report (for second extension). - EXPECT_TRUE(processor_->HasDataToReportForTest()); + EXPECT_TRUE(processor_.HasDataToReportForTest()); // Retrieve signal info for second extension. std::unique_ptr<SignalInfo> extension_1_signal_info = - processor_->GetSignalInfoForReport(kExtensionId[1]); + processor_.GetSignalInfoForReport(kExtensionId[1]); ASSERT_NE(extension_1_signal_info, nullptr); // Verify that processor no longer has data to report. - EXPECT_FALSE(processor_->HasDataToReportForTest()); + EXPECT_FALSE(processor_.HasDataToReportForTest()); // Verify signal info contents for first extension. {
diff --git a/chrome/browser/sharesheet/sharesheet_service.cc b/chrome/browser/sharesheet/sharesheet_service.cc index 8e2019d..a7808cd 100644 --- a/chrome/browser/sharesheet/sharesheet_service.cc +++ b/chrome/browser/sharesheet/sharesheet_service.cc
@@ -17,7 +17,9 @@ #include "chrome/browser/sharesheet/share_action/share_action.h" #include "chrome/browser/sharesheet/sharesheet_service_delegator.h" #include "chrome/browser/sharesheet/sharesheet_types.h" +#include "chrome/common/chrome_features.h" #include "chrome/grit/generated_resources.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/intent_util.h" #include "content/public/browser/web_contents.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -262,13 +264,24 @@ // Making a copy because we move |intent_launch_info| out below. auto app_id = intent_launch_info[index].app_id; auto app_type = app_service_proxy_->AppRegistryCache().GetAppType(app_id); - auto icon_type = apps::mojom::IconType::kStandard; constexpr bool allow_placeholder_icon = false; - app_service_proxy_->LoadIcon( - app_type, app_id, icon_type, kIconSize, allow_placeholder_icon, - base::BindOnce(&SharesheetService::OnIconLoaded, - weak_factory_.GetWeakPtr(), std::move(intent_launch_info), - std::move(targets), index, std::move(callback))); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + app_service_proxy_->LoadIcon( + apps::ConvertMojomAppTypToAppType(app_type), app_id, + apps::IconType::kStandard, kIconSize, allow_placeholder_icon, + base::BindOnce(&SharesheetService::OnIconLoaded, + weak_factory_.GetWeakPtr(), + std::move(intent_launch_info), std::move(targets), index, + std::move(callback))); + } else { + app_service_proxy_->LoadIcon( + app_type, app_id, apps::mojom::IconType::kStandard, kIconSize, + allow_placeholder_icon, + apps::MojomIconValueToIconValueCallback(base::BindOnce( + &SharesheetService::OnIconLoaded, weak_factory_.GetWeakPtr(), + std::move(intent_launch_info), std::move(targets), index, + std::move(callback)))); + } } void SharesheetService::OnIconLoaded( @@ -276,7 +289,7 @@ std::vector<TargetInfo> targets, size_t index, SharesheetServiceIconLoaderCallback callback, - apps::mojom::IconValuePtr icon_value) { + apps::IconValuePtr icon_value) { const auto& launch_entry = intent_launch_info[index]; const auto& app_type = app_service_proxy_->AppRegistryCache().GetAppType(launch_entry.app_id); @@ -290,7 +303,11 @@ app_service_proxy_->AppRegistryCache().ForOneApp( launch_entry.app_id, [&launch_entry, &targets, &icon_value, &target_type](const apps::AppUpdate& update) { - targets.emplace_back(target_type, icon_value->uncompressed, + gfx::ImageSkia image_skia = + (icon_value && icon_value->icon_type == apps::IconType::kStandard) + ? icon_value->uncompressed + : gfx::ImageSkia(); + targets.emplace_back(target_type, image_skia, base::UTF8ToUTF16(launch_entry.app_id), base::UTF8ToUTF16(update.Name()), base::UTF8ToUTF16(launch_entry.activity_label),
diff --git a/chrome/browser/sharesheet/sharesheet_service.h b/chrome/browser/sharesheet/sharesheet_service.h index a62526a..8955e74a 100644 --- a/chrome/browser/sharesheet/sharesheet_service.h +++ b/chrome/browser/sharesheet/sharesheet_service.h
@@ -18,6 +18,7 @@ #include "chrome/browser/sharesheet/sharesheet_metrics.h" #include "chrome/browser/sharesheet/sharesheet_types.h" #include "components/keyed_service/core/keyed_service.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "ui/base/accelerators/accelerator.h" #include "ui/gfx/native_widget_types.h" @@ -141,7 +142,7 @@ std::vector<TargetInfo> targets, size_t index, SharesheetServiceIconLoaderCallback callback, - apps::mojom::IconValuePtr icon_value); + apps::IconValuePtr icon_value); void OnAppIconsLoaded(base::WeakPtr<content::WebContents> web_contents, apps::mojom::IntentPtr intent,
diff --git a/chrome/browser/sharing_hub/sharing_hub_features.cc b/chrome/browser/sharing_hub/sharing_hub_features.cc index 8c0bb7c..5dbf1bdc 100644 --- a/chrome/browser/sharing_hub/sharing_hub_features.cc +++ b/chrome/browser/sharing_hub/sharing_hub_features.cc
@@ -55,8 +55,8 @@ const base::Feature kSharingHubDesktopAppMenu{ "SharingHubDesktopAppMenu", base::FEATURE_DISABLED_BY_DEFAULT}; -const base::Feature kSharingHubDesktopOmnibox{ - "SharingHubDesktopOmnibox", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSharingHubDesktopOmnibox{"SharingHubDesktopOmnibox", + base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kDesktopScreenshots{"DesktopScreenshots", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/browser/site_isolation/origin_agent_cluster_browsertest.cc b/chrome/browser/site_isolation/origin_agent_cluster_browsertest.cc index 9bfa969..7ce6971 100644 --- a/chrome/browser/site_isolation/origin_agent_cluster_browsertest.cc +++ b/chrome/browser/site_isolation/origin_agent_cluster_browsertest.cc
@@ -5,7 +5,9 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/feature_list.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" +#include "chrome/browser/metrics/metrics_memory_details.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" @@ -20,16 +22,82 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_request.h" #include "net/test/embedded_test_server/http_response.h" +#include "services/network/public/cpp/features.h" #include "url/gurl.h" +using base::Bucket; + +namespace { + +class TestMemoryDetails : public MetricsMemoryDetails { + public: + TestMemoryDetails() : MetricsMemoryDetails(base::DoNothing()) {} + + TestMemoryDetails(const TestMemoryDetails&) = delete; + TestMemoryDetails& operator=(const TestMemoryDetails&) = delete; + + void StartFetchAndWait() { + uma_ = std::make_unique<base::HistogramTester>(); + StartFetch(); + run_loop_.Run(); + } + + // Returns a HistogramTester which observed the most recent call to + // StartFetchAndWait(). + base::HistogramTester* uma() { return uma_.get(); } + + int GetTotalProcessCount() { + std::vector<Bucket> buckets = uma_->GetAllSamples( + "Memory.RenderProcessHost.Count.InitializedAndNotDead"); + DCHECK(buckets.size() == 1U); + return buckets[0].min; + } + + int GetOacProcessCount() { + std::vector<Bucket> buckets = uma_->GetAllSamples( + "Memory.RenderProcessHost.Count.OriginAgentClusterOverhead"); + // The bucket size will be zero when testing with OriginAgentCluster + // disabled. + CHECK(buckets.size() == 1U || buckets.size() == 0U); + return buckets.size() == 1U ? buckets[0].min : 0; + } + + int GetOacProcessCountPercent() { + std::vector<Bucket> buckets = uma_->GetAllSamples( + "Memory.RenderProcessHost.Percent.OriginAgentClusterOverhead"); + // The bucket size will be zero when testing with OriginAgentCluster + // disabled. + CHECK(buckets.size() == 1U || buckets.size() == 0U); + return buckets.size() == 1U ? buckets[0].min : 0; + } + + private: + ~TestMemoryDetails() override = default; + + void OnDetailsAvailable() override { + MetricsMemoryDetails::OnDetailsAvailable(); + // Exit the loop initiated by StartFetchAndWait(). + run_loop_.QuitWhenIdle(); + } + + std::unique_ptr<base::HistogramTester> uma_; + base::RunLoop run_loop_; +}; + +// Matches a container of histogram samples, for the common case where the +// histogram received just one sample. +#define HasOneSample(x) ElementsAre(Sample(x, 1)) + +} // namespace + // General browsertests for the Origin-Agent-Cluster header can be found in -// content/browser/isolated_origin_browsertest.cc. However testing use counters -// is best done from chrome/; thus, this file exists. +// content/browser/isolated_origin_browsertest.cc. However testing metrics +// related behavior is best done from chrome/; thus, this file exists. class OriginAgentClusterBrowserTest : public InProcessBrowserTest { public: OriginAgentClusterBrowserTest() - : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} + : OriginAgentClusterBrowserTest(true /* enable_origin_agent_cluster_*/) {} OriginAgentClusterBrowserTest(const OriginAgentClusterBrowserTest&) = delete; OriginAgentClusterBrowserTest& operator=( @@ -40,19 +108,36 @@ void SetUpCommandLine(base::CommandLine* command_line) override { ASSERT_TRUE(embedded_test_server()->InitializeAndListen()); - command_line->AppendSwitch(switches::kIgnoreCertificateErrors); - - feature_list_.InitAndEnableFeature(features::kOriginIsolationHeader); - } - - void SetUpOnMainThread() override { + // Start the HTTPS server here so we can properly get the URL for the + // command-line isolated origin. https_server()->AddDefaultHandlers(GetChromeTestDataDir()); https_server()->RegisterRequestHandler( base::BindRepeating(&OriginAgentClusterBrowserTest::HandleResponse, base::Unretained(this))); - ASSERT_TRUE(https_server()->Start()); + command_line->AppendSwitch(switches::kIgnoreCertificateErrors); + std::string origin_list = + https_server()->GetURL("isolated.foo.com", "/").spec(); + command_line->AppendSwitchASCII(switches::kIsolateOrigins, origin_list); + + // To keep the tests easier to reason about, turn off both the spare + // renderer process and process reuse for subframes in different + // BrowsingInstances. + if (enable_origin_agent_cluster_) { + feature_list_.InitWithFeatures( + /* enable_features */ {features::kOriginIsolationHeader, + features::kDisableProcessReuse}, + /* disable_features */ {features::kSpareRendererForSitePerProcess}); + } else { + feature_list_.InitWithFeatures( + /* enable_features */ {features::kDisableProcessReuse}, + /* disable_features */ {features::kOriginIsolationHeader, + features::kSpareRendererForSitePerProcess}); + } + } + + void SetUpOnMainThread() override { host_resolver()->AddRule("*", "127.0.0.1"); embedded_test_server()->StartAcceptingConnections(); } @@ -63,6 +148,11 @@ net::EmbeddedTestServer* https_server() { return &https_server_; } + protected: + explicit OriginAgentClusterBrowserTest(bool enable_oac) + : https_server_(net::EmbeddedTestServer::TYPE_HTTPS), + enable_origin_agent_cluster_(enable_oac) {} + private: std::unique_ptr<net::test_server::HttpResponse> HandleResponse( const net::test_server::HttpRequest& request) { @@ -73,6 +163,13 @@ response->AddCustomHeader("Origin-Agent-Cluster", "?1"); response->set_content("I like origin keys!"); return std::move(response); + } else if (request.relative_url == "/origin_key_me_iframe") { + auto response = std::make_unique<net::test_server::BasicHttpResponse>(); + response->set_code(net::HTTP_OK); + response->set_content_type("text/html"); + response->AddCustomHeader("Origin-Agent-Cluster", "?1"); + response->set_content("<body><iframe id='test'></iframe></body>"); + return std::move(response); } return nullptr; @@ -80,8 +177,23 @@ net::EmbeddedTestServer https_server_; base::test::ScopedFeatureList feature_list_; + bool enable_origin_agent_cluster_; }; +class OriginAgentClusterDisabledBrowserTest + : public OriginAgentClusterBrowserTest { + public: + OriginAgentClusterDisabledBrowserTest() + : OriginAgentClusterBrowserTest(false /* enable_origin_agent_cluster_*/) { + } + OriginAgentClusterDisabledBrowserTest( + const OriginAgentClusterDisabledBrowserTest&) = delete; + OriginAgentClusterDisabledBrowserTest& operator=( + const OriginAgentClusterDisabledBrowserTest&) = delete; + + ~OriginAgentClusterDisabledBrowserTest() override = default; +}; // class OriginAgentClusterDisabledBrowserTest + IN_PROC_BROWSER_TEST_F(OriginAgentClusterBrowserTest, Navigations) { GURL start_url(https_server()->GetURL("foo.com", "/iframe.html")); GURL origin_keyed_url( @@ -105,3 +217,257 @@ web_feature_waiter->Wait(); } + +IN_PROC_BROWSER_TEST_F(OriginAgentClusterBrowserTest, + ProcessCountMetricsSimple) { + GURL start_url(https_server()->GetURL("foo.com", "/iframe.html")); + GURL origin_keyed_url( + https_server()->GetURL("origin-keyed.foo.com", "/origin_key_me")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), start_url)); + EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", origin_keyed_url)); + + // Get the metrics. + scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails(); + details->StartFetchAndWait(); + + EXPECT_EQ(2, details->GetTotalProcessCount()); + EXPECT_EQ(1, details->GetOacProcessCount()); + EXPECT_EQ(50, details->GetOacProcessCountPercent()); +} + +// Same as OriginAgentClusterBrowserTest.ProcessCountMetricsSimple, but with +// OriginAgentCluster disabled, so no metrics should be recorded. +IN_PROC_BROWSER_TEST_F(OriginAgentClusterDisabledBrowserTest, + ProcessCountMetricsSimple) { + GURL start_url(https_server()->GetURL("foo.com", "/iframe.html")); + GURL origin_keyed_url( + https_server()->GetURL("origin-keyed.foo.com", "/origin_key_me")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), start_url)); + EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", origin_keyed_url)); + + // Get the metrics. + scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails(); + details->StartFetchAndWait(); + + EXPECT_EQ(1, details->GetTotalProcessCount()); + EXPECT_EQ(0, details->GetOacProcessCount()); + EXPECT_EQ(0, details->GetOacProcessCountPercent()); +} + +// In the case where we load an OAC origin with no base-origin, we expect zero +// overhead since the isolated origin only creates a single process, and no +// process is created for the base-origin. +IN_PROC_BROWSER_TEST_F(OriginAgentClusterBrowserTest, + ProcessCountMetricsNoBaseOrigin) { + GURL origin_keyed_url( + https_server()->GetURL("origin-keyed.foo.com", "/origin_key_me")); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), origin_keyed_url)); + + // Get the metrics. + scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails(); + details->StartFetchAndWait(); + + EXPECT_EQ(1, details->GetTotalProcessCount()); + EXPECT_EQ(0, details->GetOacProcessCount()); + EXPECT_EQ(0, details->GetOacProcessCountPercent()); +} + +// We expect the OAC overhead to be zero when no OAC origins are present. +IN_PROC_BROWSER_TEST_F(OriginAgentClusterBrowserTest, + ProcessCountMetricsNoOACs) { + GURL start_url(https_server()->GetURL("foo.com", "/iframe.html")); + GURL sub_origin_url(https_server()->GetURL("sub.foo.com", "/title1.html")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), start_url)); + EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", sub_origin_url)); + + // Get the metrics. + scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails(); + details->StartFetchAndWait(); + + EXPECT_EQ(1, details->GetTotalProcessCount()); + EXPECT_EQ(0, details->GetOacProcessCount()); + EXPECT_EQ(0, details->GetOacProcessCountPercent()); +} + +// Two distinct OAC sub-origins with a base-origin should have an overhead of +// two processes. +IN_PROC_BROWSER_TEST_F(OriginAgentClusterBrowserTest, + ProcessCountMetricsTwoSubOrigins) { + GURL start_url(https_server()->GetURL("foo.com", "/two_iframes_blank.html")); + GURL origin_keyed_url1( + https_server()->GetURL("sub1.foo.com", "/origin_key_me")); + GURL origin_keyed_url2( + https_server()->GetURL("sub2.foo.com", "/origin_key_me")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), start_url)); + EXPECT_TRUE(NavigateIframeToURL(web_contents, "iframe1", origin_keyed_url1)); + EXPECT_TRUE(NavigateIframeToURL(web_contents, "iframe2", origin_keyed_url2)); + + // Get the metrics. + scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails(); + details->StartFetchAndWait(); + + EXPECT_EQ(3, details->GetTotalProcessCount()); + EXPECT_EQ(2, details->GetOacProcessCount()); + EXPECT_EQ(66, details->GetOacProcessCountPercent()); +} + +// This test loads the same base-origin with an isolated sub-origin in each of +// two tabs. Each tab represents a separate BrowsingInstance, so we expect the +// OAC overhead of 1 to be counted twice. +IN_PROC_BROWSER_TEST_F(OriginAgentClusterBrowserTest, + ProcessCountMetricsTwoTabs) { + GURL start_url(https_server()->GetURL("foo.com", "/iframe.html")); + GURL origin_keyed_url( + https_server()->GetURL("sub.foo.com", "/origin_key_me")); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), start_url)); + content::WebContents* tab1 = + browser()->tab_strip_model()->GetWebContentsAt(0); + EXPECT_TRUE(NavigateIframeToURL(tab1, "test", origin_keyed_url)); + // Open two a.com tabs (with cross site http iframes). IsolateExtensions mode + // should have no effect so far, since there are no frames straddling the + // extension/web boundary. + AddTabAtIndex(1, start_url, ui::PAGE_TRANSITION_TYPED); + content::WebContents* tab2 = + browser()->tab_strip_model()->GetWebContentsAt(1); + EXPECT_TRUE(NavigateIframeToURL(tab2, "test", origin_keyed_url)); + + EXPECT_NE(tab1, tab2); + + // Get the metrics. + scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails(); + details->StartFetchAndWait(); + + EXPECT_EQ(4, details->GetTotalProcessCount()); + EXPECT_EQ(2, details->GetOacProcessCount()); + EXPECT_EQ(50, details->GetOacProcessCountPercent()); +} + +// Make sure command-line isolated origins don't trigger the OAC metrics. +IN_PROC_BROWSER_TEST_F(OriginAgentClusterBrowserTest, + ProcessCountMetricsNoCmdLineIsolation) { + GURL main_frame_url(https_server()->GetURL("foo.com", "/iframe.html")); + GURL cmd_line_isolated_url( + https_server()->GetURL("isolated.foo.com", "/title1.html")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", cmd_line_isolated_url)); + + // Make sure we got two SiteInstances. + auto* main_frame = web_contents->GetMainFrame(); + auto* child_frame = ChildFrameAt(main_frame, 0); + EXPECT_NE(main_frame->GetSiteInstance(), child_frame->GetSiteInstance()); + + // Get the metrics. + scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails(); + details->StartFetchAndWait(); + + EXPECT_EQ(0, details->GetOacProcessCount()); + EXPECT_EQ(0, details->GetOacProcessCountPercent()); +} + +// Make sure command-line isolated origins don't trigger the OAC metrics. +// Same as ProcessCountMetricsNoCmdLineIsolation but isolated child has OAC. +// We don't consider this as overhead because the extra process would still +// exist for this user even without OAC. +IN_PROC_BROWSER_TEST_F(OriginAgentClusterBrowserTest, + ProcessCountMetricsNoCmdLineIsolationWithOAC1) { + GURL main_frame_url(https_server()->GetURL("foo.com", "/iframe.html")); + GURL cmd_line_isolated_url( + https_server()->GetURL("isolated.foo.com", "/origin_key_me")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", cmd_line_isolated_url)); + + // Make sure we got two SiteInstances. + auto* main_frame = web_contents->GetMainFrame(); + auto* child_frame = ChildFrameAt(main_frame, 0); + EXPECT_NE(main_frame->GetSiteInstance(), child_frame->GetSiteInstance()); + + // Get the metrics. + scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails(); + details->StartFetchAndWait(); + + EXPECT_EQ(0, details->GetOacProcessCount()); + EXPECT_EQ(0, details->GetOacProcessCountPercent()); +} + +// Make sure command-line isolated origins don't trigger the OAC metrics. +// Same as ProcessCountMetricsNoCmdLineIsolation but both mainframe and child +// have OAC. +IN_PROC_BROWSER_TEST_F(OriginAgentClusterBrowserTest, + ProcessCountMetricsNoCmdLineIsolationWithOAC2) { + GURL main_frame_url( + https_server()->GetURL("foo.com", "/origin_key_me_iframe")); + GURL cmd_line_isolated_url( + https_server()->GetURL("isolated.foo.com", "/origin_key_me")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", cmd_line_isolated_url)); + + // Make sure we got two SiteInstances. + auto* main_frame = web_contents->GetMainFrame(); + auto* child_frame = ChildFrameAt(main_frame, 0); + EXPECT_NE(main_frame->GetSiteInstance(), child_frame->GetSiteInstance()); + + // Get the metrics. + scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails(); + details->StartFetchAndWait(); + + EXPECT_EQ(0, details->GetOacProcessCount()); + EXPECT_EQ(0, details->GetOacProcessCountPercent()); +} + +// Make sure command-line isolated origins don't trigger the OAC metrics. +// Same as ProcessCountMetricsNoCmdLineIsolation but mainframe has OAC. +IN_PROC_BROWSER_TEST_F(OriginAgentClusterBrowserTest, + ProcessCountMetricsNoCmdLineIsolationWithOAC3) { + GURL main_frame_url( + https_server()->GetURL("foo.com", "/origin_key_me_iframe")); + GURL cmd_line_isolated_url( + https_server()->GetURL("isolated.foo.com", "/title1.html")); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", cmd_line_isolated_url)); + + // Make sure we got two SiteInstances. + auto* main_frame = web_contents->GetMainFrame(); + auto* child_frame = ChildFrameAt(main_frame, 0); + EXPECT_NE(main_frame->GetSiteInstance(), child_frame->GetSiteInstance()); + + // Get the metrics. + scoped_refptr<TestMemoryDetails> details = new TestMemoryDetails(); + details->StartFetchAndWait(); + + EXPECT_EQ(0, details->GetOacProcessCount()); + EXPECT_EQ(0, details->GetOacProcessCountPercent()); +}
diff --git a/chrome/browser/site_isolation/site_details.cc b/chrome/browser/site_isolation/site_details.cc index c310463..1596631a1 100644 --- a/chrome/browser/site_isolation/site_details.cc +++ b/chrome/browser/site_isolation/site_details.cc
@@ -12,6 +12,7 @@ #include "content/public/browser/page.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/site_isolation_policy.h" #include "extensions/buildflags/buildflags.h" #include "url/origin.h" @@ -97,14 +98,33 @@ &page, site_data)); } +int SiteDetails::EstimateOriginAgentClusterOverhead(const SiteData& site_data) { + if (!content::SiteIsolationPolicy:: + IsProcessIsolationForOriginAgentClusterEnabled()) { + return 0; + } + + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + int oac_overhead = 0; + // We only want to call GetOacOverhead() once per BrowsingInstance, so only + // call it using the primary SiteInstance. + for (auto& entry : site_data.browsing_instances) + oac_overhead += entry.first->EstimateOriginAgentClusterOverheadForMetrics(); + + return oac_overhead; +} + void SiteDetails::UpdateHistograms( - const BrowserContextSiteDataMap& site_data_map) { + const BrowserContextSiteDataMap& site_data_map, + size_t live_process_count) { // Sum the number of sites and SiteInstances in each BrowserContext and // the total number of out-of-process iframes. int num_browsing_instances = 0; int num_oopifs = 0; int num_proxies = 0; int num_oop_inner_frame_trees = 0; + int extra_processes_from_oac = 0; for (auto& site_data_map_entry : site_data_map) { const SiteData& site_data = site_data_map_entry.second; for (const auto& entry : site_data.browsing_instances) { @@ -118,12 +138,31 @@ num_browsing_instances += site_data.browsing_instances.size(); num_oopifs += site_data.out_of_process_frames; num_oop_inner_frame_trees += site_data.out_of_process_inner_frame_trees; + extra_processes_from_oac += EstimateOriginAgentClusterOverhead(site_data); } + int oac_overhead_percent = + live_process_count == 0 + ? 0 + : static_cast<int>(100 * + (static_cast<float>(extra_processes_from_oac) / + static_cast<float>(live_process_count))); + base::UmaHistogramCounts100("SiteIsolation.BrowsingInstanceCount", num_browsing_instances); base::UmaHistogramCounts10000("SiteIsolation.ProxyCount", num_proxies); base::UmaHistogramCounts100("SiteIsolation.OutOfProcessIframes", num_oopifs); base::UmaHistogramCounts100("SiteIsolation.OutOfProcessInnerFrameTrees", num_oop_inner_frame_trees); + if (!content::SiteIsolationPolicy:: + IsProcessIsolationForOriginAgentClusterEnabled()) { + return; + } + + UMA_HISTOGRAM_COUNTS_100( + "Memory.RenderProcessHost.Count.OriginAgentClusterOverhead", + extra_processes_from_oac); + UMA_HISTOGRAM_PERCENTAGE( + "Memory.RenderProcessHost.Percent.OriginAgentClusterOverhead", + oac_overhead_percent); }
diff --git a/chrome/browser/site_isolation/site_details.h b/chrome/browser/site_isolation/site_details.h index 1202f0da..34a9812 100644 --- a/chrome/browser/site_isolation/site_details.h +++ b/chrome/browser/site_isolation/site_details.h
@@ -48,6 +48,10 @@ // A count of all inner frame trees which are in a different RenderProcessHost // from their parents. int out_of_process_inner_frame_trees = 0; + + // Estimated increase in process count due to OriginAgentCluster (OAC) + // SiteInstances over all elements in |browsing_instances|. + int oac_overhead; }; // Maps a BrowserContext to information about the sites it contains. @@ -62,8 +66,14 @@ // on the UI thread. static void CollectSiteInfo(content::Page& page, SiteData* site_data); + // Collect count of OriginAgentCluster SiteInstances, and compare to what we + // would expect with OAC off (and no coalescing different BrowsingInstances + // into shared RenderProcesses). + static int EstimateOriginAgentClusterOverhead(const SiteData& site_data); + // Updates the global histograms for tracking memory usage. - static void UpdateHistograms(const BrowserContextSiteDataMap& site_data_map); + static void UpdateHistograms(const BrowserContextSiteDataMap& site_data_map, + size_t live_process_count); private: // Only static methods - never needs to be constructed.
diff --git a/chrome/browser/supervised_user/supervised_user_interstitial.cc b/chrome/browser/supervised_user/supervised_user_interstitial.cc index 8f47c9a..f811d6e 100644 --- a/chrome/browser/supervised_user/supervised_user_interstitial.cc +++ b/chrome/browser/supervised_user/supervised_user_interstitial.cc
@@ -85,7 +85,8 @@ private: friend class content::WebContentsUserData<TabCloser>; - explicit TabCloser(WebContents* web_contents) : web_contents_(web_contents) { + explicit TabCloser(WebContents* web_contents) + : content::WebContentsUserData<TabCloser>(*web_contents) { content::GetUIThreadTaskRunner({})->PostTask( FROM_HERE, base::BindOnce(&TabCloser::CloseTabImpl, weak_ptr_factory_.GetWeakPtr())); @@ -94,21 +95,20 @@ void CloseTabImpl() { // On Android, FindBrowserWithWebContents and TabStripModel don't exist. #if !defined(OS_ANDROID) - Browser* browser = chrome::FindBrowserWithWebContents(web_contents_); + Browser* browser = chrome::FindBrowserWithWebContents(&GetWebContents()); DCHECK(browser); TabStripModel* tab_strip = browser->tab_strip_model(); DCHECK_NE(TabStripModel::kNoTab, - tab_strip->GetIndexOfWebContents(web_contents_)); + tab_strip->GetIndexOfWebContents(&GetWebContents())); if (tab_strip->count() <= 1) { // Don't close the last tab in the window. - web_contents_->RemoveUserData(UserDataKey()); + GetWebContents().RemoveUserData(UserDataKey()); return; } #endif - web_contents_->Close(); + GetWebContents().Close(); } - WebContents* web_contents_; base::WeakPtrFactory<TabCloser> weak_ptr_factory_{this}; WEB_CONTENTS_USER_DATA_KEY_DECL(); @@ -134,7 +134,7 @@ details.previous_main_frame_url = controller.GetLastCommittedEntry()->GetURL(); } - details.type = content::NAVIGATION_TYPE_NEW_ENTRY; + details.type = content::NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY; for (int i = manager->infobar_count() - 1; i >= 0; --i) { infobars::InfoBar* infobar = manager->infobar_at(i); if (infobar->delegate()->ShouldExpire(
diff --git a/chrome/browser/supervised_user/supervised_user_navigation_observer.cc b/chrome/browser/supervised_user/supervised_user_navigation_observer.cc index 5f7183c..ae56b5a 100644 --- a/chrome/browser/supervised_user/supervised_user_navigation_observer.cc +++ b/chrome/browser/supervised_user/supervised_user_navigation_observer.cc
@@ -46,7 +46,9 @@ SupervisedUserNavigationObserver::SupervisedUserNavigationObserver( content::WebContents* web_contents) - : content::WebContentsObserver(web_contents), + : content::WebContentsUserData<SupervisedUserNavigationObserver>( + *web_contents), + content::WebContentsObserver(web_contents), receivers_(web_contents, this) { Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext());
diff --git a/chrome/browser/themes/theme_helper.cc b/chrome/browser/themes/theme_helper.cc index 021b07d..cfe2ec5 100644 --- a/chrome/browser/themes/theme_helper.cc +++ b/chrome/browser/themes/theme_helper.cc
@@ -33,13 +33,23 @@ // unpacked on the filesystem.) constexpr char kDefaultThemeGalleryID[] = "hkacjpbfdknhflllbcmjibkdeoafencn"; +// Returns an array of light and dark mode versions of the given color id +// Ex: [light mode, dark mode] const std::array<SkColor, 2> GetTabGroupColors(int color_id) { - // Depending on UI varition enabled, dark mode saved group chip colors are + // Depending on UI variation enabled, dark mode saved group chip colors are // calculated by blending the default dark mode toolbar color with the tab // strip group colors at 24% or 48% alpha. - const SkColor default_dark_toolbar_color = - TP::GetDefaultColor(TP::COLOR_TOOLBAR, false, true); - float tab_group_chip_alpha = 0.24f; + + // Flat version of dark mode colors used in bookmarks bar to fill + // the buttons. + const SkColor kFlatGrey = SkColorSetRGB(0x5D, 0x5E, 0x62); + const SkColor kFlatBlue = SkColorSetRGB(0x49, 0x54, 0x68); + const SkColor kFlatRed = SkColorSetRGB(0x62, 0x4A, 0x4B); + const SkColor kFlatGreen = SkColorSetRGB(0x47, 0x59, 0x50); + const SkColor kFlatYellow = SkColorSetRGB(0x65, 0x5C, 0x44); + const SkColor kFlatCyan = SkColorSetRGB(0x45, 0x5D, 0x65); + const SkColor kFlatPurple = SkColorSetRGB(0x58, 0x4A, 0x68); + const SkColor kFlatPink = SkColorSetRGB(0x65, 0x4A, 0x5D); switch (color_id) { case TP::COLOR_TAB_GROUP_CONTEXT_MENU_BLUE: @@ -48,81 +58,57 @@ case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_INACTIVE_BLUE: return {gfx::kGoogleBlue600, gfx::kGoogleBlue300}; case TP::COLOR_TAB_GROUP_BOOKMARK_BAR_BLUE: - return {gfx::kGoogleBlue050, - color_utils::AlphaBlend(gfx::kGoogleBlue600, - default_dark_toolbar_color, - tab_group_chip_alpha)}; + return {gfx::kGoogleBlue050, kFlatBlue}; case TP::COLOR_TAB_GROUP_CONTEXT_MENU_RED: case TP::COLOR_TAB_GROUP_DIALOG_RED: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_ACTIVE_RED: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_INACTIVE_RED: return {gfx::kGoogleRed600, gfx::kGoogleRed300}; case TP::COLOR_TAB_GROUP_BOOKMARK_BAR_RED: - return {gfx::kGoogleRed050, - color_utils::AlphaBlend(gfx::kGoogleRed600, - default_dark_toolbar_color, - tab_group_chip_alpha)}; + return {gfx::kGoogleRed050, kFlatRed}; case TP::COLOR_TAB_GROUP_CONTEXT_MENU_YELLOW: case TP::COLOR_TAB_GROUP_DIALOG_YELLOW: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_ACTIVE_YELLOW: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_INACTIVE_YELLOW: - return {gfx::kGoogleYellow900, gfx::kGoogleYellow300}; + return {gfx::kGoogleYellow600, gfx::kGoogleYellow300}; case TP::COLOR_TAB_GROUP_BOOKMARK_BAR_YELLOW: - return {gfx::kGoogleYellow100, - color_utils::AlphaBlend(gfx::kGoogleYellow900, - default_dark_toolbar_color, - tab_group_chip_alpha)}; + return {gfx::kGoogleYellow050, kFlatYellow}; case TP::COLOR_TAB_GROUP_CONTEXT_MENU_GREEN: case TP::COLOR_TAB_GROUP_DIALOG_GREEN: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_ACTIVE_GREEN: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_INACTIVE_GREEN: return {gfx::kGoogleGreen700, gfx::kGoogleGreen300}; case TP::COLOR_TAB_GROUP_BOOKMARK_BAR_GREEN: - return {gfx::kGoogleGreen050, - color_utils::AlphaBlend(gfx::kGoogleGreen700, - default_dark_toolbar_color, - tab_group_chip_alpha)}; + return {gfx::kGoogleGreen050, kFlatGreen}; case TP::COLOR_TAB_GROUP_CONTEXT_MENU_PINK: case TP::COLOR_TAB_GROUP_DIALOG_PINK: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_ACTIVE_PINK: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_INACTIVE_PINK: return {gfx::kGooglePink700, gfx::kGooglePink300}; case TP::COLOR_TAB_GROUP_BOOKMARK_BAR_PINK: - return {gfx::kGooglePink050, - color_utils::AlphaBlend(gfx::kGooglePink700, - default_dark_toolbar_color, - tab_group_chip_alpha)}; + return {gfx::kGooglePink050, kFlatPink}; case TP::COLOR_TAB_GROUP_CONTEXT_MENU_PURPLE: case TP::COLOR_TAB_GROUP_DIALOG_PURPLE: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_ACTIVE_PURPLE: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_INACTIVE_PURPLE: - return {gfx::kGooglePurple600, gfx::kGooglePurple200}; + return {gfx::kGooglePurple500, gfx::kGooglePurple300}; case TP::COLOR_TAB_GROUP_BOOKMARK_BAR_PURPLE: - return {gfx::kGooglePurple050, - color_utils::AlphaBlend(gfx::kGooglePurple600, - default_dark_toolbar_color, - tab_group_chip_alpha)}; + return {gfx::kGooglePurple050, kFlatPurple}; case TP::COLOR_TAB_GROUP_CONTEXT_MENU_CYAN: case TP::COLOR_TAB_GROUP_DIALOG_CYAN: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_ACTIVE_CYAN: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_INACTIVE_CYAN: return {gfx::kGoogleCyan900, gfx::kGoogleCyan300}; case TP::COLOR_TAB_GROUP_BOOKMARK_BAR_CYAN: - return {gfx::kGoogleCyan050, - color_utils::AlphaBlend(gfx::kGoogleCyan900, - default_dark_toolbar_color, - tab_group_chip_alpha)}; + return {gfx::kGoogleCyan050, kFlatCyan}; case TP::COLOR_TAB_GROUP_BOOKMARK_BAR_GREY: - return {gfx::kGoogleGrey050, - color_utils::AlphaBlend(gfx::kGoogleGrey700, - default_dark_toolbar_color, - tab_group_chip_alpha)}; + return {gfx::kGoogleGrey100, kFlatGrey}; case TP::COLOR_TAB_GROUP_CONTEXT_MENU_GREY: case TP::COLOR_TAB_GROUP_DIALOG_GREY: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_ACTIVE_GREY: case TP::COLOR_TAB_GROUP_TABSTRIP_FRAME_INACTIVE_GREY: default: - return {gfx::kGoogleGrey700, gfx::kGoogleGrey400}; + return {gfx::kGoogleGrey600, gfx::kGoogleGrey300}; } }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index ad4e943de..a7930e8 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -682,6 +682,9 @@ "//chrome/browser/ui/webui/connectors_internals:mojo_bindings", ] } + if (is_chromeos) { + deps += [ "//chromeos/crosapi/cpp:cpp" ] + } if (!is_fuchsia) { deps += [ "//components/crash/core/app" ] @@ -2143,6 +2146,8 @@ "ash/projector/projector_app_client_impl.h", "ash/projector/projector_client_impl.cc", "ash/projector/projector_client_impl.h", + "ash/projector/projector_soda_installation_controller.cc", + "ash/projector/projector_soda_installation_controller.h", "ash/quick_answers/quick_answers_browser_client_impl.cc", "ash/quick_answers/quick_answers_browser_client_impl.h", "ash/quick_answers/quick_answers_controller_impl.cc", @@ -4451,8 +4456,8 @@ "views/sharing_hub/sharing_hub_bubble_view_impl.h", "views/sharing_hub/sharing_hub_icon_view.cc", "views/sharing_hub/sharing_hub_icon_view.h", - "views/side_panel.cc", - "views/side_panel.h", + "views/side_panel/side_panel.cc", + "views/side_panel/side_panel.h", "views/ssl_client_certificate_selector.cc", "views/ssl_client_certificate_selector.h", "views/status_bubble_views.cc",
diff --git a/chrome/browser/ui/android/appmenu/internal/BUILD.gn b/chrome/browser/ui/android/appmenu/internal/BUILD.gn index 3a8362a6..279c7cd 100644 --- a/chrome/browser/ui/android/appmenu/internal/BUILD.gn +++ b/chrome/browser/ui/android/appmenu/internal/BUILD.gn
@@ -60,6 +60,7 @@ resources_package = "org.chromium.chrome.browser.ui.appmenu.test" sources = [ + "java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinderRenderTest.java", "java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinderTest.java", "java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuTest.java", "java/src/org/chromium/chrome/browser/ui/appmenu/TestAppMenuDelegate.java", @@ -84,6 +85,7 @@ "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_test_runner_java", + "//third_party/hamcrest:hamcrest_library_java", "//third_party/junit", "//third_party/mockito:mockito_java", "//ui/android:ui_full_java",
diff --git a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinder.java b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinder.java index d04abd57..02d7d9a9 100644 --- a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinder.java +++ b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinder.java
@@ -13,6 +13,7 @@ import androidx.annotation.ColorRes; import androidx.appcompat.content.res.AppCompatResources; +import androidx.core.graphics.drawable.DrawableCompat; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.browser.ui.appmenu.internal.R; @@ -109,12 +110,14 @@ PropertyModel buttonModel = null; boolean checkable = false; boolean checked = false; + boolean buttonEnabled = true; Drawable subIcon = null; if (subList.size() == 2) { buttonModel = subList.get(1).model; checkable = buttonModel.get(AppMenuItemProperties.CHECKABLE); checked = buttonModel.get(AppMenuItemProperties.CHECKED); + buttonEnabled = buttonModel.get(AppMenuItemProperties.ENABLED); subIcon = buttonModel.get(AppMenuItemProperties.ICON); } @@ -131,6 +134,15 @@ // Display an icon alongside the MenuItem. checkbox.setVisibility(View.GONE); button.setVisibility(View.VISIBLE); + if (!buttonEnabled) { + // Only grey out the icon when disabled. When the menu is enabled, use the + // icon's original color. + Drawable icon = buttonModel.get(AppMenuItemProperties.ICON); + DrawableCompat.setTintList(icon, + AppCompatResources.getColorStateList(button.getContext(), + R.color.default_icon_color_secondary_tint_list)); + buttonModel.set(AppMenuItemProperties.ICON, icon); + } setupImageButton(button, buttonModel, appMenuClickHandler); } else { // Display just the label of the MenuItem.
diff --git a/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinderRenderTest.java b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinderRenderTest.java new file mode 100644 index 0000000..7e91af9 --- /dev/null +++ b/chrome/browser/ui/android/appmenu/internal/java/src/org/chromium/chrome/browser/ui/appmenu/AppMenuItemViewBinderRenderTest.java
@@ -0,0 +1,382 @@ +// 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. + +package org.chromium.chrome.browser.ui.appmenu; + +import android.app.Activity; +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.ListView; + +import androidx.annotation.Nullable; +import androidx.appcompat.content.res.AppCompatResources; +import androidx.test.filters.MediumTest; + +import org.hamcrest.Matchers; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.BaseActivityTestRule; +import org.chromium.base.test.params.ParameterAnnotations; +import org.chromium.base.test.params.ParameterSet; +import org.chromium.base.test.params.ParameterizedRunner; +import org.chromium.base.test.util.Criteria; +import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.ui.appmenu.AppMenuHandler.AppMenuItemType; +import org.chromium.chrome.browser.ui.appmenu.internal.R; +import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; +import org.chromium.chrome.test.util.ChromeRenderTestRule; +import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.ui.modelutil.LayoutViewBuilder; +import org.chromium.ui.modelutil.ModelListAdapter; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.test.util.DisableAnimationsTestRule; +import org.chromium.ui.test.util.DummyUiActivity; +import org.chromium.ui.test.util.NightModeTestUtils; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +/** + * Render tests for {@link AppMenuItemViewBinder}. + */ +@RunWith(ParameterizedRunner.class) +@ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class) +public class AppMenuItemViewBinderRenderTest { + @ParameterAnnotations.ClassParameter + private static List<ParameterSet> sClassParams = + Arrays.asList(new ParameterSet().value(false, true).name("LiteMode_MenuItemEnabled"), + new ParameterSet().value(false, false).name("LiteMode_MenuItemDisabled"), + new ParameterSet().value(true, true).name("NightMode_MenuItemEnabled"), + new ParameterSet().value(true, false).name("NightMode_MenuItemDisabled")); + + @ClassRule + public static DisableAnimationsTestRule disableAnimationsRule = new DisableAnimationsTestRule(); + @ClassRule + public static BaseActivityTestRule<DummyUiActivity> mActivityTestRule = + new BaseActivityTestRule<>(DummyUiActivity.class); + @Rule + public ChromeRenderTestRule mRenderTestRule = + ChromeRenderTestRule.Builder.withPublicCorpus().build(); + private static Activity sActivity; + private static ListView sListView; + private static View sContentView; + + static final int MENU_ID1 = 100; + static final int MENU_ID2 = 200; + static final int MENU_ID3 = 300; + static final int MENU_ID4 = 400; + static final int MENU_ID5 = 500; + static final String TITLE_1 = "Menu Item One"; + static final String TITLE_2 = "Menu Item Two"; + static final String TITLE_3 = "Menu Item Three"; + static final String TITLE_4 = "Menu Item Four"; + static final String TITLE_5 = "Menu Item Five"; + + private ModelListAdapter.ModelList mMenuList; + private ModelListAdapter mModelListAdapter; + private boolean mMenuItemEnabled; + + public AppMenuItemViewBinderRenderTest(boolean nightMode, boolean menuItemEnabled) { + mMenuItemEnabled = menuItemEnabled; + NightModeTestUtils.setUpNightModeForDummyUiActivity(nightMode); + mRenderTestRule.setNightModeEnabled(nightMode); + mRenderTestRule.setVariantPrefix(menuItemEnabled ? "MenuItemEnabled" : "MenuItemDisabled"); + } + + @Before + public void setUpTest() throws Exception { + mActivityTestRule.launchActivity(null); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + sActivity = mActivityTestRule.getActivity(); + mMenuList = new ModelListAdapter.ModelList(); + mModelListAdapter = new ModelListAdapter(mMenuList); + + sActivity.setContentView(R.layout.app_menu_layout); + sContentView = sActivity.findViewById(android.R.id.content); + sListView = sContentView.findViewById(R.id.app_menu_list); + sListView.setAdapter(mModelListAdapter); + + mModelListAdapter.registerType(AppMenuItemType.STANDARD, + new LayoutViewBuilder(R.layout.menu_item_start_with_icon), + AppMenuItemViewBinder::bindStandardItem); + mModelListAdapter.registerType(AppMenuItemType.TITLE_BUTTON, + new LayoutViewBuilder(R.layout.title_button_menu_item), + AppMenuItemViewBinder::bindTitleButtonItem); + mModelListAdapter.registerType(AppMenuItemType.THREE_BUTTON_ROW, + new LayoutViewBuilder(R.layout.icon_row_menu_item), + AppMenuItemViewBinder::bindIconRowItem); + mModelListAdapter.registerType(AppMenuItemType.FOUR_BUTTON_ROW, + new LayoutViewBuilder(R.layout.icon_row_menu_item), + AppMenuItemViewBinder::bindIconRowItem); + mModelListAdapter.registerType(AppMenuItemType.FIVE_BUTTON_ROW, + new LayoutViewBuilder(R.layout.icon_row_menu_item), + AppMenuItemViewBinder::bindIconRowItem); + }); + } + + @After + public void tearDownTest() throws Exception { + TestThreadUtils.runOnUiThreadBlocking(() -> { mMenuList.clear(); }); + } + + @AfterClass + public static void afterClass() { + NightModeTestUtils.tearDownNightModeForDummyUiActivity(); + } + + private PropertyModel createStandardMenuItem( + int menuId, String title, boolean enabled, @Nullable Drawable icon) { + PropertyModel model = new PropertyModel.Builder(AppMenuItemProperties.ALL_KEYS) + .with(AppMenuItemProperties.MENU_ITEM_ID, menuId) + .with(AppMenuItemProperties.TITLE, title) + .with(AppMenuItemProperties.ENABLED, enabled) + .build(); + if (icon != null) { + model.set(AppMenuItemProperties.ICON, icon); + } + mMenuList.add(new ModelListAdapter.ListItem(AppMenuItemType.STANDARD, model)); + + return model; + } + + private PropertyModel createTitleMenuItem(int mainMenuId, int titleMenuId, String title, + boolean enabled, @Nullable Drawable menuIcon, int buttonMenuId, String buttonTitle, + boolean checkable, boolean checked, boolean buttonEnabled, + @Nullable Drawable buttonIcon) { + PropertyModel model = new PropertyModel.Builder(AppMenuItemProperties.ALL_KEYS) + .with(AppMenuItemProperties.MENU_ITEM_ID, mainMenuId) + .build(); + + ModelListAdapter.ModelList subList = new ModelListAdapter.ModelList(); + PropertyModel titleModel = new PropertyModel.Builder(AppMenuItemProperties.ALL_KEYS) + .with(AppMenuItemProperties.MENU_ITEM_ID, titleMenuId) + .with(AppMenuItemProperties.TITLE, title) + .with(AppMenuItemProperties.ENABLED, enabled) + .build(); + if (menuIcon != null) { + titleModel.set(AppMenuItemProperties.ICON, menuIcon); + } + PropertyModel buttonModel = new PropertyModel.Builder(AppMenuItemProperties.ALL_KEYS) + .with(AppMenuItemProperties.MENU_ITEM_ID, buttonMenuId) + .with(AppMenuItemProperties.TITLE, buttonTitle) + .with(AppMenuItemProperties.CHECKABLE, checkable) + .with(AppMenuItemProperties.CHECKED, checked) + .with(AppMenuItemProperties.ENABLED, buttonEnabled) + .build(); + if (buttonIcon != null) { + buttonModel.set(AppMenuItemProperties.ICON, buttonIcon); + } + subList.add(new ModelListAdapter.ListItem(0, titleModel)); + subList.add(new ModelListAdapter.ListItem(0, buttonModel)); + model.set(AppMenuItemProperties.SUBMENU, subList); + mMenuList.add(new ModelListAdapter.ListItem(AppMenuItemType.TITLE_BUTTON, model)); + + return model; + } + + private PropertyModel createIconRowMenuItem(int menuId, int subId1, String titleCondensed1, + Drawable icon1, int subId2, String titleCondensed2, Drawable icon2, int subId3, + String titleCondensed3, Drawable icon3, int subId4, @Nullable String titleCondensed4, + @Nullable Drawable icon4, int subId5, @Nullable String titleCondensed5, + @Nullable Drawable icon5, boolean enabled) { + PropertyModel model = new PropertyModel.Builder(AppMenuItemProperties.ALL_KEYS) + .with(AppMenuItemProperties.MENU_ITEM_ID, menuId) + .build(); + + ModelListAdapter.ModelList subList = new ModelListAdapter.ModelList(); + int menutype = AppMenuItemType.THREE_BUTTON_ROW; + createIconMenuItem(subList, subId1, titleCondensed1, icon1, enabled); + createIconMenuItem(subList, subId2, titleCondensed2, icon2, enabled); + createIconMenuItem(subList, subId3, titleCondensed3, icon3, enabled); + if (subId4 != View.NO_ID) { + createIconMenuItem(subList, subId4, titleCondensed4, icon4, enabled); + menutype = AppMenuItemType.FOUR_BUTTON_ROW; + if (subId5 != View.NO_ID) { + createIconMenuItem(subList, subId5, titleCondensed5, icon5, enabled); + menutype = AppMenuItemType.FIVE_BUTTON_ROW; + } + } + + model.set(AppMenuItemProperties.SUBMENU, subList); + mMenuList.add(new ModelListAdapter.ListItem(menutype, model)); + + return model; + } + + private void createIconMenuItem(ModelListAdapter.ModelList list, int id, String titleCondensed, + Drawable icon, boolean enabled) { + PropertyModel model = new PropertyModel.Builder(AppMenuItemProperties.ALL_KEYS) + .with(AppMenuItemProperties.MENU_ITEM_ID, id) + .with(AppMenuItemProperties.TITLE_CONDENSED, titleCondensed) + .with(AppMenuItemProperties.ICON, icon) + .with(AppMenuItemProperties.ENABLED, enabled) + .build(); + list.add(new ModelListAdapter.ListItem(0, model)); + } + + private void waitListViewToBeDrawn() { + CriteriaHelper.pollUiThread( + () -> { Criteria.checkThat(sListView.getChildAt(0), Matchers.notNullValue()); }); + } + + @Test + @MediumTest + @Feature("RenderTest") + public void testStandardMenuItem() throws IOException { + TestThreadUtils.runOnUiThreadBlocking( + () -> { createStandardMenuItem(MENU_ID1, TITLE_1, mMenuItemEnabled, null); }); + waitListViewToBeDrawn(); + mRenderTestRule.render(sContentView, "standard"); + } + + @Test + @MediumTest + @Feature("RenderTest") + public void testStandardMenuItem_Icon() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + Drawable icon = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable.test_ic_vintage_filter); + createStandardMenuItem(MENU_ID1, TITLE_1, mMenuItemEnabled, icon); + }); + waitListViewToBeDrawn(); + mRenderTestRule.render(sContentView, "standard_with_icon"); + } + + @Test + @MediumTest + @Feature("RenderTest") + public void testTitleButtonMenuItem_Icon() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + Drawable buttonIcon = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_arrow_forward_black_24dp); + createTitleMenuItem(MENU_ID1, MENU_ID2, TITLE_2, mMenuItemEnabled, null, MENU_ID3, + TITLE_3, false, false, mMenuItemEnabled, buttonIcon); + }); + waitListViewToBeDrawn(); + mRenderTestRule.render(sContentView, "title_button_icon"); + } + + @Test + @MediumTest + @Feature("RenderTest") + public void testTitleButtonMenuItem_Checkbox_Checked() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + createTitleMenuItem(MENU_ID1, MENU_ID2, TITLE_2, mMenuItemEnabled, null, MENU_ID3, + TITLE_3, true, true, mMenuItemEnabled, null); + }); + waitListViewToBeDrawn(); + mRenderTestRule.render(sContentView, "title_button_checkbox_checked"); + } + + @Test + @MediumTest + @Feature("RenderTest") + public void testTitleButtonMenuItem_Checkbox_Unchecked() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + createTitleMenuItem(MENU_ID1, MENU_ID2, TITLE_2, mMenuItemEnabled, null, MENU_ID3, + TITLE_3, true, false, mMenuItemEnabled, null); + }); + waitListViewToBeDrawn(); + mRenderTestRule.render(sContentView, "title_button_checkbox_unchecked"); + } + + @Test + @MediumTest + @Feature("RenderTest") + public void testTitleButtonMenuItem_Checkbox_Unchecked_IconBeforeItem() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + Drawable icon = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable.test_ic_vintage_filter); + createTitleMenuItem(MENU_ID1, MENU_ID2, TITLE_2, mMenuItemEnabled, icon, MENU_ID3, + TITLE_3, true, false, mMenuItemEnabled, null); + }); + waitListViewToBeDrawn(); + mRenderTestRule.render(sContentView, "title_button_checkbox_unchecked_icon_before_item"); + } + + @Test + @MediumTest + @Feature("RenderTest") + public void testIconRow_ThreeIcons() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + Drawable icon1 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_arrow_forward_black_24dp); + Drawable icon2 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_star_border_black_24dp); + Drawable icon3 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_arrow_downward_black_24dp); + createIconRowMenuItem(1, MENU_ID1, TITLE_1, icon1, MENU_ID2, TITLE_2, icon2, MENU_ID3, + TITLE_3, icon3, View.NO_ID, null, null, View.NO_ID, null, null, + mMenuItemEnabled); + }); + waitListViewToBeDrawn(); + mRenderTestRule.render(sContentView, "iconrow_three_icons"); + } + + @Test + @MediumTest + @Feature("RenderTest") + public void testIconRow_FourIcons() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + Drawable icon1 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_arrow_forward_black_24dp); + Drawable icon2 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_star_border_black_24dp); + Drawable icon3 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_arrow_downward_black_24dp); + Drawable icon4 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_info_outline_black_24dp); + createIconRowMenuItem(1, MENU_ID1, TITLE_1, icon1, MENU_ID2, TITLE_2, icon2, MENU_ID3, + TITLE_3, icon3, MENU_ID4, TITLE_4, icon4, View.NO_ID, null, null, + mMenuItemEnabled); + }); + waitListViewToBeDrawn(); + mRenderTestRule.render(sContentView, "iconrow_four_icons"); + } + + @Test + @MediumTest + @Feature("RenderTest") + public void testIconRow_FiveIcons() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + Drawable icon1 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_arrow_forward_black_24dp); + Drawable icon2 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_star_border_black_24dp); + Drawable icon3 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_arrow_downward_black_24dp); + Drawable icon4 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_info_outline_black_24dp); + Drawable icon5 = AppCompatResources.getDrawable(sActivity, + org.chromium.chrome.browser.ui.appmenu.test.R.drawable + .test_ic_refresh_black_24dp); + createIconRowMenuItem(1, MENU_ID1, TITLE_1, icon1, MENU_ID2, TITLE_2, icon2, MENU_ID3, + TITLE_3, icon3, MENU_ID4, TITLE_4, icon4, MENU_ID5, TITLE_5, icon5, + mMenuItemEnabled); + }); + waitListViewToBeDrawn(); + mRenderTestRule.render(sContentView, "iconrow_five_icons"); + } +}
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index dd8f26d..c3a8df0 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -330,11 +330,62 @@ <message name ="IDS_SETTINGS_INCOGNITO_TAB_LOCK_SUMMARY_ANDROID_SETTING_OFF" desc = "Summary for the Incognito tab lock toggle in Settings which asks the user to turn on screen lock in Android settings if it's off. Clicking on the text takes the user to Android settings."> <ph name="BEGIN_LINK"><link></ph>Turn on screen lock in Android settings<ph name="END_LINK"></link></ph> </message> - <message name="IDS_PRELOAD_PAGES_TITLE" desc="Title for a checkbox in Settings that controls pages preloading and informs the user about the data shared by this feature."> - Preload pages for faster browsing and searching + <message name="IDS_PREFS_SECTION_PRELOAD_PAGES_TITLE" desc="Title for the Preload Pages section. This section allows the user to control whether Chrome will preload pages that it thinks the user is likely to load in the future. [CHAR_LIMIT=32]"> + Preload Pages </message> - <message name="IDS_PRELOAD_PAGES_SUMMARY" desc="Summary for a checkbox in Settings that controls pages preloading and informs the user about the data shared by this feature."> - Preloads pages that Chrome thinks you might visit. To do this, Chrome may use cookies, if you allow cookies, and may encrypt and send pages through Google to hide your identity from sites. + <message name="IDS_PRELOAD_PAGES_TITLE" desc="Title for a section in Settings that controls pages preloading and informs the user about the data shared by this feature."> + Preload pages + </message> + <message name="IDS_PRELOAD_PAGES_SUMMARY" desc="Summary for a section in Settings that controls pages preloading and informs the user about the data shared by this feature."> + You can browse and search faster when Chrome preloads pages that it thinks you might visit + </message> + <message name="IDS_PRELOAD_PAGES_NO_PRELOADING_TITLE" desc="Name of the no preloading option for the Preload Pages settings page. This option disables preloading pages that Chrome believes the user is likely to navigate to. [CHAR_LIMIT=32]"> + No preloading + </message> + <message name="IDS_PRELOAD_PAGES_NO_PRELOADING_SUMMARY" desc="Short explanation of what the no preloading mode does in the Preload Pages setting."> + Pages load only after you open them. + </message> + <message name="IDS_PRELOAD_PAGES_STANDARD_PRELOADING_TITLE" desc="Name of the standard preloading option for the Preload Pages settings page. This option enables preloading pages that Chrome believes the user is likely to navigate to. [CHAR_LIMIT=32]"> + Standard preloading + </message> + <message name="IDS_PRELOAD_PAGES_STANDARD_PRELOADING_SUBTITLE" desc="Subtitle for Preload Pages standard preloading mode. Informs the user about which preloading setting is being described on this page."> + Standard preloading: + </message> + <message name="IDS_PRELOAD_PAGES_STANDARD_PRELOADING_SUMMARY" desc="Short explanation of what the standard preloading mode does in the Preload Pages setting."> + Some of the pages you visit are preloaded. Pages may be preloaded through Google servers when linked from a Google site. + </message> + <message name="IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_ONE" desc="First bullet point under the Preload Pages standard preloading mode. Informs the user about what the standard preloading setting does."> + Preloads pages that Chrome thinks you are likely to visit. + </message> + <message name="IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_TWO" desc="Second bullet point under the Preload Pages standard preloading mode. Informs the user about what the standard preloading setting does."> + If you allow cookies, Chrome may use them for preloading. + </message> + <message name="IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_THREE" desc="Third bullet point under the Preload Pages standard preloading mode. Informs the user about what the standard preloading setting does."> + When a Google site asks to privately preload links on their page, Chrome encrypts and preloads pages through Google servers without cookies. This hides your identity from the preloaded site. + </message> + <message name="IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_FOUR" desc="Fourth bullet point under the Preload Pages standard preloading mode. Informs the user about what the standard preloading setting does."> + Because the preloaded pages are encrypted, and the site linking to the pages is a Google site, Google servers don’t receive new information when privately preloading these pages. + </message> + <message name="IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_TITLE" desc="Name of the extended preloading option for the Preload Pages settings page. This option enables more extensive preloading of pages that Chrome believes the user is likely to navigate to. [CHAR_LIMIT=32]"> + Extended preloading + </message> + <message name="IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_SUBTITLE" desc="Subtitle for Preload Pages extended preloading mode. Informs the user about which preloading setting is being described on this page."> + Extended preloading: + </message> + <message name="IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_SUMMARY" desc="Short explanation of what the extended preloading mode does in the Preload Pages setting."> + More pages are preloaded. Pages may be preloaded through Google servers when requested by other sites. + </message> + <message name="IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_ONE" desc="First bullet point under the Preload Pages extended preloading mode. Informs the user about what the extended preloading setting does."> + More frequently preloads pages that Chrome thinks you are likely to visit. This setting may result in increased data use. + </message> + <message name="IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_TWO" desc="Second bullet point under the Preload Pages extended preloading mode. Informs the user about what the extended preloading setting does."> + If you allow cookies, Chrome may use them for preloading. + </message> + <message name="IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_THREE" desc="Third bullet point under the Preload Pages extended preloading mode. Informs the user about what the extended preloading setting does."> + When a site asks to privately preload links on their page, Chrome encrypts and preloads pages through Google servers without cookies. This hides your identity from the preloaded site. + </message> + <message name="IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_FOUR" desc="Fourth bullet point under the Preload Pages extended preloading mode. Informs the user about what the extended preloading setting does."> + Because the preloaded pages are encrypted, Google will not learn anything about the preloaded page content. Google servers will learn which sites are privately preloaded. This information is only used to preload the pages, and is not linked to other information from your Google Account. </message> <message name="IDS_URL_KEYED_ANONYMIZED_DATA_TITLE" desc="Title for a checkbox in Settings that controls non-personalized URL collection and informs the user about the data shared by this feature."> Make searches and browsing better @@ -3482,7 +3533,7 @@ </message> <message name="IDS_IPH_SHOPPING_LIST_SAVE_FLOW" desc="In-product help text that notifies a user that they can organize their saved products from a folder in bookmarks."> Organize your tracked products in Bookmarks - </message> + </message> <message name="IDS_IPH_SHOPPING_LIST_SAVE_FLOW_ACCESSIBILITY" is_accessibility_with_no_ui="true" desc="In-product help accessibility text that notifies a user that they can organize their saved products from a folder in bookmarks."> Organize your tracked products in Bookmarks from the folder icon </message> @@ -5000,6 +5051,26 @@ Creating GIF <ph name="PERCENT">%1$d<ex>13</ex></ph>%% </message> + <message name="IDS_LIGHTWEIGHT_REACTIONS_TOOLBAR_ANNOUNCEMENT" is_accessibility_with_no_ui="true" desc="The accessibility text to read when the lightweight reactions toolbar is selected. The user can then select a reaction from the toolbar to place on the screen."> + Choose an emotion + </message> + + <message name="IDS_LIGHTWEIGHT_REACTIONS_RESIZE_AND_ROTATE_BUTTON" is_accessibility_with_no_ui="true" desc="The accessibility text to read when the resize and rotate editing tool is selected. The user can then resize and rotate the reaction on the scene."> + Resize and rotate + </message> + + <message name="IDS_LIGHTWEIGHT_REACTIONS_DUPLICATE_BUTTON" is_accessibility_with_no_ui="true" desc="The accessibility text to read when the duplicate editing tool is selected. The user can then dupicate the reaction on the scene."> + Duplicate + </message> + + <message name="IDS_LIGHTWEIGHT_REACTIONS_TITLE_FOR_SHARE" desc="The title of the shared lightweight reaction."> + Emotion GIF <ph name="CURRENT_DATE_ISO">%1$s<ex>2020-09-16</ex></ph> + </message> + + <message name="IDS_LIGHTWEIGHT_REACTIONS_FILENAME_PREFIX" desc="The file name prefix of the shared lightweight reaction. Followed by the timestamp."> + chrome_emotion_gif_<ph name="CURRENT_TIMESTAMP_MS">%1$s<ex>1582667748515</ex></ph> + </message> + <!-- Share Screenshot strings --> <message name="IDS_SCREENSHOT_EDIT_TITLE" desc="The text shown on the share option for screenshots."> Edit
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LIGHTWEIGHT_REACTIONS_FILENAME_PREFIX.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LIGHTWEIGHT_REACTIONS_FILENAME_PREFIX.png.sha1 new file mode 100644 index 0000000..b378306d --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LIGHTWEIGHT_REACTIONS_FILENAME_PREFIX.png.sha1
@@ -0,0 +1 @@ +2461f1ddea4b11f982cb63abe064685087fda3f9 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LIGHTWEIGHT_REACTIONS_TITLE_FOR_SHARE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LIGHTWEIGHT_REACTIONS_TITLE_FOR_SHARE.png.sha1 new file mode 100644 index 0000000..99826570 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LIGHTWEIGHT_REACTIONS_TITLE_FOR_SHARE.png.sha1
@@ -0,0 +1 @@ +dd5cc03ffd77747ea8ffc653da65a91203ef1623 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_PRELOAD_PAGES_NO_PRELOADING_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_PRELOAD_PAGES_NO_PRELOADING_TITLE.png.sha1 new file mode 100644 index 0000000..f03dc9f --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_PRELOAD_PAGES_NO_PRELOADING_TITLE.png.sha1
@@ -0,0 +1 @@ +2d3deeac4fdacdc187a51b74b6c30414c6c8b4f0 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_PRELOAD_PAGES_SUMMARY.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_PRELOAD_PAGES_SUMMARY.png.sha1 new file mode 100644 index 0000000..be741053 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_PRELOAD_PAGES_SUMMARY.png.sha1
@@ -0,0 +1 @@ +3bf16f78e96e4b30b08e5758676569b806464038 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_SECTION_PRELOAD_PAGES_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_SECTION_PRELOAD_PAGES_TITLE.png.sha1 new file mode 100644 index 0000000..940f72e8 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PREFS_SECTION_PRELOAD_PAGES_TITLE.png.sha1
@@ -0,0 +1 @@ +f5ab9539b5c8c089ccbd5c6b6507c7809345cc79 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_FOUR.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_FOUR.png.sha1 new file mode 100644 index 0000000..c80e1a3 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_FOUR.png.sha1
@@ -0,0 +1 @@ +d48159c38ae162cb78e23890055fc6a4be1f5761 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_ONE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_ONE.png.sha1 new file mode 100644 index 0000000..4096959 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_ONE.png.sha1
@@ -0,0 +1 @@ +59509344469e857c747ce2dc909b97b2bbc3a204 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_THREE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_THREE.png.sha1 new file mode 100644 index 0000000..e84f3a8f --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_THREE.png.sha1
@@ -0,0 +1 @@ +1e1b435812d0eccd049f538931f447b2b8e94f62 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_TWO.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_TWO.png.sha1 new file mode 100644 index 0000000..71df345 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_BULLET_TWO.png.sha1
@@ -0,0 +1 @@ +08557785e2c2e409911925be795623a586640121 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_SUBTITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_SUBTITLE.png.sha1 new file mode 100644 index 0000000..e682b54 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_SUBTITLE.png.sha1
@@ -0,0 +1 @@ +688549be3109dda7addf010abb0a17adb1cfb068 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_SUMMARY.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_SUMMARY.png.sha1 new file mode 100644 index 0000000..082c64d8 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_SUMMARY.png.sha1
@@ -0,0 +1 @@ +5db941b0708e6c083505192b7d62cea293a4f380 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_TITLE.png.sha1 new file mode 100644 index 0000000..e047179 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_EXTENDED_PRELOADING_TITLE.png.sha1
@@ -0,0 +1 @@ +3be647038dbc6bc481b92e9ba0fc183942d0e6e9 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_NO_PRELOADING_SUMMARY.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_NO_PRELOADING_SUMMARY.png.sha1 new file mode 100644 index 0000000..1d19dac --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_NO_PRELOADING_SUMMARY.png.sha1
@@ -0,0 +1 @@ +c7457665040a0c617b6011560342d39c754e6c62 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_NO_PRELOADING_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_NO_PRELOADING_TITLE.png.sha1 new file mode 100644 index 0000000..e914d8e1 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_NO_PRELOADING_TITLE.png.sha1
@@ -0,0 +1 @@ +09561d1bb6f6e8524c1dbc5108d7ac31fe2a5831 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_FOUR.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_FOUR.png.sha1 new file mode 100644 index 0000000..a1f8f08 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_FOUR.png.sha1
@@ -0,0 +1 @@ +120c4c9ac66c6399072b965536b6c0e57030f9a9 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_ONE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_ONE.png.sha1 new file mode 100644 index 0000000..442bb31 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_ONE.png.sha1
@@ -0,0 +1 @@ +61d3c302519e0e2d044b2f378913a6985a33563e \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_THREE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_THREE.png.sha1 new file mode 100644 index 0000000..bd2dc74 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_THREE.png.sha1
@@ -0,0 +1 @@ +a1f31193037a9e9277a36fbd77e8c3ea88f7680a \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_TWO.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_TWO.png.sha1 new file mode 100644 index 0000000..2307a30 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_BULLET_TWO.png.sha1
@@ -0,0 +1 @@ +7c716ecfb6c599e856095ba6daf6165a67285527 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_SUBTITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_SUBTITLE.png.sha1 new file mode 100644 index 0000000..939560d --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_SUBTITLE.png.sha1
@@ -0,0 +1 @@ +0d4d9f32984a5f33e2f7f47e0d31dd3a7a2f1aaa \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_SUMMARY.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_SUMMARY.png.sha1 new file mode 100644 index 0000000..79999d6f --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_SUMMARY.png.sha1
@@ -0,0 +1 @@ +70eb0c828af7a3b7931bad66436dd28134ab8d00 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_TITLE.png.sha1 new file mode 100644 index 0000000..f284756 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_STANDARD_PRELOADING_TITLE.png.sha1
@@ -0,0 +1 @@ +4ef75dd0cff75244117eed6940c745334aee8d5f \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_SUMMARY.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_SUMMARY.png.sha1 index 5008d5a..f5bb2d9 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_SUMMARY.png.sha1 +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_SUMMARY.png.sha1
@@ -1 +1 @@ -c355b241fb23dac1a62ce04ff21fa2b3730cc881 \ No newline at end of file +8b0419708ef55a53139ae1a03c79bfbe580e2027 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_TITLE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_TITLE.png.sha1 new file mode 100644 index 0000000..4f2080c --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRELOAD_PAGES_TITLE.png.sha1
@@ -0,0 +1 @@ +feae604066e936a0fcf26273f0f481cfa0588b81 \ No newline at end of file
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb index d9dc27a..0625c31 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_hy.xtb
@@ -36,6 +36,7 @@ <translation id="1177863135347784049">Անհատականացված</translation> <translation id="1197267115302279827">Տեղափոխել էջանիշները</translation> <translation id="1201402288615127009">Հաջորդը</translation> +<translation id="1202892408424955784">Ապրանքներ, որոնց գներին հետևում եք</translation> <translation id="1204037785786432551">Ներբեռնել հղումը</translation> <translation id="1206892813135768548">Պատճենել հղման տեքստը</translation> <translation id="1208340532756947324">Սարքերը համաժամացնելու և անհատականացնելու համար միացրեք համաժամացումը</translation> @@ -82,6 +83,7 @@ <translation id="1414981605391750300">Միացում Google-ին: Մի փոքր սպասեք…</translation> <translation id="1416550906796893042">Ծրագրի տարբերակ</translation> <translation id="1430915738399379752">Տպում</translation> +<translation id="1448440926884431741">Էջանիշներում դասավորեք ապրանքները, որոնց հետևում եք</translation> <translation id="1450753235335490080">Չհաջողվեց ուղարկել բովանդակությունը (<ph name="CONTENT_TYPE" />)</translation> <translation id="1466383950273130737">Ընտրեք Chrome-ի լեզուն</translation> <translation id="147113415845704694">Փորձեք հարցնել․ «What’s the weather today?» (Ի՞նչ եղանակ է այսօր)։</translation> @@ -134,6 +136,7 @@ <translation id="1877026089748256423">Chrome-ը հնացած է</translation> <translation id="1883903952484604915">Իմ ֆայլերը</translation> <translation id="189358972401248634">Այլ լեզուներ</translation> +<translation id="1894023287452300670">Հետևեք գներին այստեղ</translation> <translation id="1905320231301365059">Ինկոգնիտո ռեժիմում ներբեռնված տարրերը տեսանելի են այս սարքն օգտագործողներին։</translation> <translation id="1910950723001426294">Կիսվելու տարբերակների ցանկը փակված է։</translation> <translation id="1918175104945982129">Օգնականի միջոցով ձայնային որոնման միջերեսը բացվում է կես բարձրությամբ</translation> @@ -346,6 +349,7 @@ <translation id="3029704984691124060">Անցաբառերը չեն համընկնում</translation> <translation id="3031225630520268969">Օգնականի միջոցով ձայնային որոնման համաձայնության միջերես</translation> <translation id="3036750288708366620"><ph name="BEGIN_LINK" />Ստացեք օգնություն<ph name="END_LINK" /></translation> +<translation id="3037177537145227281">Դուք հետևում եք այս ապրանքի գնին</translation> <translation id="3037517125981011456">Ցույց է տալիս հաղորդագրություն Chrome-ում մուտք գործելու համար</translation> <translation id="3046945242843292318">Հաջորդ անգամ ավելի արագ անցեք այս կայք</translation> <translation id="305593374596241526">Տեղորոշումն անջատված է: Միացրեք այն <ph name="BEGIN_LINK" />Android-ի կարգավորումներում<ph name="END_LINK" />:</translation> @@ -504,6 +508,7 @@ <translation id="4016425174436051808">Սխալի պատճառով չհաջողվեց բաժանորդագրվել։</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ժամ}one{# ժամ}other{# ժամ}}</translation> <translation id="4045764304651014138">Օգտագործման տվյալներ</translation> +<translation id="405399507749852140">Դուք ծանուցում կստանաք, երբ որևէ կայքում գնիջեցում լինի</translation> <translation id="4056223980640387499">Սեպիա</translation> <translation id="4060598801229743805">Ընտրանքները հասանելի են էկրանի վերին հատվածում</translation> <translation id="4062305924942672200">Իրավական տեղեկություններ</translation> @@ -557,6 +562,7 @@ <translation id="4409271659088619928">Դուք օգտագործում եք <ph name="DSE" /> որոնողական համակարգը։ Որոնումների պատմությունը ջնջելու համար կարդացեք համապատասխան ցուցումները։</translation> <translation id="4411535500181276704">Lite ռեժիմ</translation> <translation id="4415276339145661267">Կառավարել Google հաշիվը</translation> +<translation id="4425140285732600465">Դուք հետևում եք այս ապրանքի գնին։ Երբ որևէ կայքում այն իջնի, դուք կստանաք ծանուցում։</translation> <translation id="4427306783828095590">Լրացուցիչ պաշտպանությունն օգնում է խուսափել ֆիշինգից և արգելափակել վնասաբեր ծրագրերը</translation> <translation id="4450672886426705087">Որոնման արդյունքներ Google-ից։</translation> <translation id="4452411734226507615">Փակել <ph name="TAB_TITLE" /> ներդիրը</translation> @@ -754,6 +760,7 @@ <translation id="5548606607480005320">Անվտանգության ստուգում</translation> <translation id="5555525474779371165">Ընտրեք Ապահով դիտարկման պաշտպանության տեսակը</translation> <translation id="5556459405103347317">Վերաբեռնել</translation> +<translation id="555816257274242153">Գների հետագծումը դադարեցված է</translation> <translation id="5561549206367097665">Ցանցի որոնում…</translation> <translation id="5568069709869097550">Չհաջողվեց մուտք գործել</translation> <translation id="55737423895878184">Տեղորոշումն ու ծանուցումները թույլատրված են</translation> @@ -804,9 +811,11 @@ <translation id="5833984609253377421">Կիսվել հղումով</translation> <translation id="5834764604050996579">QR կոդը սկանավորելու համար թույլ տվեք Chrome-ին օգտագործել ձեր տեսախցիկը</translation> <translation id="5839058148541733625">Chrome Dino</translation> +<translation id="5842437907245493289">Պանակների օգնությամբ էջանիշներում դասավորեք ապրանքները, որոնց հետևում եք</translation> <translation id="5853623416121554550">դադարեցված է</translation> <translation id="5854512288214985237">Google-ին վիճակագրություն կամ խափանման մասին հաշվետվություններ չեն ուղարկվում</translation> <translation id="5855546874025048181">Ճշտել՝ <ph name="REFINE_TEXT" /></translation> +<translation id="5857447844686706637">Սխալ առաջացավ։ Չհաջողվեց թարմացնել գների հետագծումը։</translation> <translation id="5860033963881614850">Անջատ.</translation> <translation id="5860491529813859533">Միացնել</translation> <translation id="5862731021271217234">Ձեր մյուս սարքերում եղած ներդիրներն օգտագործելու համար միացրեք համաժամացումը</translation> @@ -863,6 +872,7 @@ <translation id="6140912465461743537">Երկիր/տարածաշրջան</translation> <translation id="6141988275892716286">Հաստատեք ներբեռնումը</translation> <translation id="614940544461990577">Փորձեք՝</translation> +<translation id="6150320133806434356">Էջանիշը պահված է</translation> <translation id="6154478581116148741">Այս սարքից ձեր գաղտնաբառերն արտահանելու համար կարգավորումներում միացրեք էկրանի կողպումը։</translation> <translation id="6159335304067198720"><ph name="PERCENT" /> տվյալների խնայում</translation> <translation id="6159729262978459665">Մաքրում է պատմությունը բոլոր համաժամացված սարքերից։</translation> @@ -877,6 +887,7 @@ Օրինակ, որոշ վեբկայքեր կարող են այս հարցմանը պատասխանել՝ ներկայացնելով գովազդ, որը հիմնված չէ ձեր այցելությունների վրա: Շատ վեբկայքեր կշարունակեն հավաքել և օգտագործել ձեր այցելությունների պատմությունը: Այն կարող է օգտագործվել, օրինակ, անվտանգությունը բարելավելու, բովանդակություն, գովազդ և խորհուրդներ տրամադրելու և վիճակագրական տվյալներ հավաքելու նպատակով:</translation> <translation id="6264376385120300461">Ներբեռնել</translation> <translation id="6277522088822131679">Այս էջը տպելիս խնդիր առաջացավ: Նորից փորձեք:</translation> +<translation id="6277722725779679269">Չհաջողվեց թարմացնել գների հետագծումը</translation> <translation id="6278428485366576908">Թեմա</translation> <translation id="6292420053234093573">Օգտվելով Chrome-ից՝ դուք ընդունում եք <ph name="BEGIN_LINK1" />Google-ի օգտագործման պայմանները<ph name="END_LINK1" /> և <ph name="BEGIN_LINK2" />Google Chrome-ի և Chrome OS-ի օգտագործման լրացուցիչ պայմանները<ph name="END_LINK2" />։</translation> <translation id="6294610283659775533">Դուք կարող եք ուղարկել ներդիրները մի սարքից մյուսը, եթե դրանցում մտել եք հաշիվ միևնույն Google հաշվով</translation> @@ -910,6 +921,7 @@ <translation id="6411219469806822692">Հնարավոր չէ ավելի վերևից նշել։ Փորձեք նշել էջի վերևից։</translation> <translation id="6412673304250309937">Ստուգում է URL-ները Chrome-ում պահված վտանգավոր կայքերի ցանկի միջոցով։ Եթե կայքը փորձում է հափշտակել ձեր գաղտնաբառը, կամ երբ վնասակար ֆայլ եք ներբեռնում, Chrome-ը կարող է ուղարկել URL-ն ու էջի բովանդակությունը՝ անվտանգ դիտարկման միջոցով ստուգելու համար։</translation> <translation id="641643625718530986">Տպել…</translation> +<translation id="6422857128426228781">Այստեղ կցուցադրվեն ապրանքները, որոնց հետևում եք</translation> <translation id="6433501201775827830">Ընտրեք որոնիչը</translation> <translation id="6434309073475700221">Հրաժարվել</translation> <translation id="6437478888915024427">Տեղեկություններ էջի մասին</translation> @@ -987,6 +999,7 @@ <translation id="6817747507826986771">Արագ կիսվեք այս էջով։ Այս դյուրանցումը փոփոխելու համար հպեք դրան և պահեք։</translation> <translation id="6820686453637990663">CVC</translation> <translation id="6824899148643461612">«<ph name="TAB_TITLE" />» ներդիրն ընտրված է</translation> +<translation id="6828070228333235514">Դադարեցնել գների հետագծումը</translation> <translation id="6846298663435243399">Բեռնում…</translation> <translation id="6850409657436465440">Ներբեռնումն ընթացքում է</translation> <translation id="6850830437481525139"><ph name="TAB_COUNT" /> փակված ներդիր</translation> @@ -1303,6 +1316,7 @@ <translation id="8571213806525832805">Վերջին 4 շաբաթվա</translation> <translation id="8572344201470131220">Պատկերը պատճենվեց</translation> <translation id="8583805026567836021">Հաշվի տվյալների մաքրում</translation> +<translation id="859046281437143747">Հետևել գներին «Այլ ընտրանքներ» կոճակի օգնությամբ</translation> <translation id="860043288473659153">Քարտապանի անունը</translation> <translation id="8602358303461588329">Մուտք գործել Chrome, փակված է։</translation> <translation id="860282621117673749">Գների իջեցման մասին ծանուցումներ</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb index efad19f..58428f1e 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_it.xtb
@@ -36,6 +36,7 @@ <translation id="1177863135347784049">Personalizzati</translation> <translation id="1197267115302279827">Sposta i Preferiti</translation> <translation id="1201402288615127009">Avanti</translation> +<translation id="1202892408424955784">Prodotti monitorati</translation> <translation id="1204037785786432551">Scarica link</translation> <translation id="1206892813135768548">Copia testo link</translation> <translation id="1208340532756947324">Attiva la sincronizzazione per sincronizzare e personalizzare tutti i dispositivi</translation> @@ -82,6 +83,7 @@ <translation id="1414981605391750300">Connessione a Google in corso. L'operazione potrebbe richiedere un minuto…</translation> <translation id="1416550906796893042">Versione applicazione</translation> <translation id="1430915738399379752">Stampa</translation> +<translation id="1448440926884431741">Organizza i tuoi prodotti monitorati in Segnalibri</translation> <translation id="1450753235335490080">Impossibile condividere <ph name="CONTENT_TYPE" /></translation> <translation id="1466383950273130737">Seleziona la lingua di Chrome</translation> <translation id="147113415845704694">Prova "Che tempo fa oggi?"</translation> @@ -134,6 +136,7 @@ <translation id="1877026089748256423">Chrome non è aggiornato</translation> <translation id="1883903952484604915">I miei file</translation> <translation id="189358972401248634">Altre lingue</translation> +<translation id="1894023287452300670">Monitora qui il prezzo</translation> <translation id="1905320231301365059">I file che scarichi in modalità di navigazione in incognito sono ancora visibili a chiunque utilizzi questo dispositivo.</translation> <translation id="1910950723001426294">L'elenco di opzioni di condivisione è chiuso.</translation> <translation id="1918175104945982129">Interfaccia utente per il consenso all'utilizzo dell'assistente per la ricerca vocale aperta nella parte inferiore dello schermo</translation> @@ -345,6 +348,7 @@ <translation id="3029704984691124060">Le passphrase non corrispondono</translation> <translation id="3031225630520268969">Interfaccia utente per il consenso all'utilizzo dell'assistente per la ricerca vocale</translation> <translation id="3036750288708366620"><ph name="BEGIN_LINK" />Richiedi assistenza<ph name="END_LINK" /></translation> +<translation id="3037177537145227281">Monitoraggio del prezzo</translation> <translation id="3037517125981011456">Vengono mostrate richieste di accesso a Chrome</translation> <translation id="3046945242843292318">Accedi più velocemente a questo sito la prossima volta</translation> <translation id="305593374596241526">La geolocalizzazione non è attiva; attivala nelle <ph name="BEGIN_LINK" />Impostazioni Android<ph name="END_LINK" />.</translation> @@ -502,6 +506,7 @@ <translation id="4016425174436051808">Non è possibile seguire. Si è verificato un errore.</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ora}one{# hrs}other{# ore}}</translation> <translation id="4045764304651014138">Dati sull'utilizzo</translation> +<translation id="405399507749852140">Ricevi avvisi se il prezzo cala su qualsiasi sito</translation> <translation id="4056223980640387499">Seppia</translation> <translation id="4060598801229743805">Opzioni disponibili nella parte superiore dello schermo</translation> <translation id="4062305924942672200">Informazioni legali</translation> @@ -555,6 +560,7 @@ <translation id="4409271659088619928">Il tuo motore di ricerca è <ph name="DSE" />. Consulta le relative istruzioni per eliminare la tua cronologia delle ricerche, se applicabile.</translation> <translation id="4411535500181276704">Modalità Lite</translation> <translation id="4415276339145661267">Gestisci il tuo Account Google</translation> +<translation id="4425140285732600465">Monitoraggio del prezzo attivato. Ricevi avvisi se il prezzo cala su qualsiasi sito.</translation> <translation id="4427306783828095590">La protezione avanzata blocca malware e tentativi di phishing con maggiore efficacia</translation> <translation id="4450672886426705087">Risultati di ricerca di Google.</translation> <translation id="4452411734226507615">Chiudi la scheda <ph name="TAB_TITLE" /></translation> @@ -752,6 +758,7 @@ <translation id="5548606607480005320">Controllo di sicurezza</translation> <translation id="5555525474779371165">Scegli il livello di protezione di Navigazione sicura che preferisci</translation> <translation id="5556459405103347317">Ricarica</translation> +<translation id="555816257274242153">Monitoraggio del prezzo interrotto</translation> <translation id="5561549206367097665">In attesa della rete…</translation> <translation id="5568069709869097550">Non riesco a effettuare l'accesso</translation> <translation id="55737423895878184">La geolocalizzazione e le notifiche sono consentite</translation> @@ -802,9 +809,11 @@ <translation id="5833984609253377421">Condividi link</translation> <translation id="5834764604050996579">Per scansionare un codice QR, consenti a Chrome di usare la tua fotocamera</translation> <translation id="5839058148541733625">Dino di Chrome</translation> +<translation id="5842437907245493289">Organizza i tuoi prodotti monitorati in Segnalibri dall'icona della cartella</translation> <translation id="5853623416121554550">in pausa</translation> <translation id="5854512288214985237">Non vengono inviati report sugli arresti anomali né statistiche a Google</translation> <translation id="5855546874025048181">Perfeziona: <ph name="REFINE_TEXT" /></translation> +<translation id="5857447844686706637">Si è verificato un errore. Impossibile aggiornare Monitora prezzo.</translation> <translation id="5860033963881614850">Off</translation> <translation id="5860491529813859533">Attiva</translation> <translation id="5862731021271217234">Attiva la sincronizzazione per trovare le tue schede degli altri dispositivi</translation> @@ -861,6 +870,7 @@ <translation id="6140912465461743537">Paese/regione</translation> <translation id="6141988275892716286">Conferma download</translation> <translation id="614940544461990577">Prova a:</translation> +<translation id="6150320133806434356">Segnalibro salvato</translation> <translation id="6154478581116148741">Attiva il blocco schermo in Impostazioni per esportare le tue password da questo dispositivo</translation> <translation id="6159335304067198720">Riduzioni dei dati: <ph name="PERCENT" /></translation> <translation id="6159729262978459665">Consente di cancellare la cronologia da tutti i dispositivi sincronizzati.</translation> @@ -875,6 +885,7 @@ Ad esempio, alcuni siti web potrebbero rispondere alla richiesta mostrando annunci non basati su altri siti web visitati. Molti siti web continueranno tuttavia a raccogliere e a utilizzare i dati di navigazione, ad esempio per aumentare la sicurezza, fornire contenuti, annunci e consigli, nonché per generare statistiche sui rapporti.</translation> <translation id="6264376385120300461">Scarica comunque</translation> <translation id="6277522088822131679">Si è verificato un problema durante la stampa della pagina. Riprova.</translation> +<translation id="6277722725779679269">Impossibile aggiornare Monitora prezzo</translation> <translation id="6278428485366576908">Tema</translation> <translation id="6292420053234093573">Utilizzando Chrome, accetti i <ph name="BEGIN_LINK1" />Termini di servizio di Google<ph name="END_LINK1" /> e i <ph name="BEGIN_LINK2" />Termini di servizio aggiuntivi di Google Chrome e Chrome OS<ph name="END_LINK2" />.</translation> <translation id="6294610283659775533">Puoi inviare schede tra dispositivi su cui è stato eseguito l'accesso con lo stesso Account Google</translation> @@ -908,6 +919,7 @@ <translation id="6411219469806822692">Non puoi scorrere più in alto di così. Prova a partire da un punto più in alto nella pagina.</translation> <translation id="6412673304250309937">Verifica gli URL con un elenco di siti non sicuri archiviati in Chrome. Se un sito cerca di rubare la tua password o se scarichi un file dannoso, Chrome potrebbe inviare anche gli URL, inclusi bit e contenuti di pagina, a Navigazione sicura.</translation> <translation id="641643625718530986">Stampa…</translation> +<translation id="6422857128426228781">Qui troverai i tuoi prodotti monitorati</translation> <translation id="6433501201775827830">Scegli il motore di ricerca</translation> <translation id="6434309073475700221">Elimina</translation> <translation id="6437478888915024427">Informazioni sulla pagina</translation> @@ -984,6 +996,7 @@ <translation id="6817747507826986771">Condividi rapidamente questa pagina. Tocca e tieni premuto per modificare questa scorciatoia.</translation> <translation id="6820686453637990663">CVC</translation> <translation id="6824899148643461612"><ph name="TAB_TITLE" />, scheda, selezionata</translation> +<translation id="6828070228333235514">Interrompi monitoraggio prezzo</translation> <translation id="6846298663435243399">Caricamento in corso…</translation> <translation id="6850409657436465440">Il download è ancora in corso</translation> <translation id="6850830437481525139"><ph name="TAB_COUNT" /> schede chiuse</translation> @@ -1297,6 +1310,7 @@ <translation id="8571213806525832805">Ultime 4 settimane</translation> <translation id="8572344201470131220">Immagine copiata</translation> <translation id="8583805026567836021">Cancellazione dati dell'account</translation> +<translation id="859046281437143747">Monitora il prezzo dal pulsante Altre opzioni</translation> <translation id="860043288473659153">Nome del titolare della carta</translation> <translation id="8602358303461588329">Accedi a Chrome, foglio chiuso.</translation> <translation id="860282621117673749">Avvisi su cali di prezzo</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb index 11b43fd..cba2635 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_mk.xtb
@@ -36,6 +36,7 @@ <translation id="1177863135347784049">Приспособено</translation> <translation id="1197267115302279827">Премести обележувачи</translation> <translation id="1201402288615127009">Следно</translation> +<translation id="1202892408424955784">Следени производи</translation> <translation id="1204037785786432551">Преземи линк</translation> <translation id="1206892813135768548">Копирај текст од врска</translation> <translation id="1208340532756947324">За да ги синхронизирате и персонализирате уредите, вклучете синхронизација</translation> @@ -82,6 +83,7 @@ <translation id="1414981605391750300">Се воспоставува контакт со Google… Ова може да потрае</translation> <translation id="1416550906796893042">Верзија на апликација</translation> <translation id="1430915738399379752">Печати</translation> +<translation id="1448440926884431741">Организирајте ги следените производи во „Обележувачи“</translation> <translation id="1450753235335490080">Не може да се сподели <ph name="CONTENT_TYPE" /></translation> <translation id="1466383950273130737">Изберете јазик за Chrome</translation> <translation id="147113415845704694">Пробајте со „What’s the weather today?“ (Какво е времето денес?)</translation> @@ -134,6 +136,7 @@ <translation id="1877026089748256423">Chrome е застарен</translation> <translation id="1883903952484604915">Мои датотеки</translation> <translation id="189358972401248634">Други јазици</translation> +<translation id="1894023287452300670">Следете ја цената тука</translation> <translation id="1905320231301365059">Датотеките што ќе ги преземете во режим „Инкогнито“ сепак ќе бидат видливи за секој што ќе го користи уредов.</translation> <translation id="1910950723001426294">Списокот со опции за споделување е затворен.</translation> <translation id="1918175104945982129">Корисничкиот интерфејс за согласност за гласовно пребарување со „Помошникот“ е отворен на половина екран</translation> @@ -346,6 +349,7 @@ <translation id="3029704984691124060">Лозинките-фрази не се совпаѓаат</translation> <translation id="3031225630520268969">Кориснички интерфејс за согласност за гласовно пребарување со „Помошникот“</translation> <translation id="3036750288708366620"><ph name="BEGIN_LINK" />Побарајте помош<ph name="END_LINK" /></translation> +<translation id="3037177537145227281">Цената се следи</translation> <translation id="3037517125981011456">Прикажува prompt за најава на Chrome</translation> <translation id="3046945242843292318">Стигнете на сајтов побрзо следниот пат</translation> <translation id="305593374596241526">Локацијата е исклучена, вклучете ја во <ph name="BEGIN_LINK" />Поставки за Android<ph name="END_LINK" />.</translation> @@ -504,6 +508,7 @@ <translation id="4016425174436051808">Не може да се следи. Нешто тргна наопаку.</translation> <translation id="4034817413553209278">{HOURS,plural, =1{# ч.}one{# ч.}other{# ч.}}</translation> <translation id="4045764304651014138">Податоци за користењето</translation> +<translation id="405399507749852140">Добивајте предупредувања ако цената се намали на кој било сајт</translation> <translation id="4056223980640387499">Sepia</translation> <translation id="4060598801229743805">Достапни се опции речиси на врвот на екранот</translation> <translation id="4062305924942672200">Правни информации</translation> @@ -557,6 +562,7 @@ <translation id="4409271659088619928">Вашиот пребарувач е <ph name="DSE" />. Погледнете го неговото упатство за бришење на историјата на пребарување ако е применливо.</translation> <translation id="4411535500181276704">Лесен режим</translation> <translation id="4415276339145661267">Управувајте со сметката на Google</translation> +<translation id="4425140285732600465">Цената се следи. Добивајте предупредувања ако цената се намали на кој било сајт.</translation> <translation id="4427306783828095590">„Подобрената заштита“ помага при блокирање кражби на идентитетот и злонамерен софтвер</translation> <translation id="4450672886426705087">Резултати од пребарувањето од Google.</translation> <translation id="4452411734226507615">Затвори ја картичката <ph name="TAB_TITLE" /></translation> @@ -754,6 +760,7 @@ <translation id="5548606607480005320">Безбедносна проверка</translation> <translation id="5555525474779371165">Изберете ја вашата заштита со „Безбедно прелистување“</translation> <translation id="5556459405103347317">Повторно вчитај</translation> +<translation id="555816257274242153">Запре следењето цени</translation> <translation id="5561549206367097665">Се чека мрежа…</translation> <translation id="5568069709869097550">Не може да се најавите</translation> <translation id="55737423895878184">Локацијата и известувањата се дозволени</translation> @@ -804,9 +811,11 @@ <translation id="5833984609253377421">Сподели го линкот</translation> <translation id="5834764604050996579">За да скенирате QR-код, дозволете Chrome да ја користи камерата</translation> <translation id="5839058148541733625">Диносаурус на Chrome</translation> +<translation id="5842437907245493289">Организирајте ги следените производи во „Обележувачи“ од иконата на папката</translation> <translation id="5853623416121554550">паузирано</translation> <translation id="5854512288214985237">Не се испраќа ниту статистика ниту извештаи за падовите до Google</translation> <translation id="5855546874025048181">Рафинирајте: „<ph name="REFINE_TEXT" />“</translation> +<translation id="5857447844686706637">Нешто тргна наопаку. Не може да се ажурира „Следете ја цената“.</translation> <translation id="5860033963881614850">Исклучено</translation> <translation id="5860491529813859533">Вклучи</translation> <translation id="5862731021271217234">За да ги добиете вашите картички од другите уреди, вклучете ја синхронизацијата</translation> @@ -863,6 +872,7 @@ <translation id="6140912465461743537">Држава/регион</translation> <translation id="6141988275892716286">Потврдете го преземањето</translation> <translation id="614940544461990577">Обидете се:</translation> +<translation id="6150320133806434356">Обележувачот е зачуван</translation> <translation id="6154478581116148741">Вклучете го заклучувањето на екранот во „Поставки“ за да ги извезете лозинките од уредов</translation> <translation id="6159335304067198720"><ph name="PERCENT" /> заштеда на податоци</translation> <translation id="6159729262978459665">Ќе ја исчисти историјата од сите синхронизирани уреди.</translation> @@ -877,6 +887,7 @@ На пример, некои веб-сајтови може да реагираат на барањето со покажување реклами што не се базираат на другите веб-сајтови што сте ги посетиле. Повеќето веб-сајтови и понатаму ќе ги собираат и користат податоците од вашето прелистување - на пример, за да ја зголемат безбедноста, да обезбедат содржини, реклами и препораки, како и да генерираат статистички податоци за известување.</translation> <translation id="6264376385120300461">Сепак преземи</translation> <translation id="6277522088822131679">Настана проблем при печатење на страницата. Обидете се повторно.</translation> +<translation id="6277722725779679269">Не може да се ажурира „Следете ја цената“</translation> <translation id="6278428485366576908">Тема</translation> <translation id="6292420053234093573">Ако користите Chrome, се согласувате со <ph name="BEGIN_LINK1" />Условите за користење на Google<ph name="END_LINK1" /> и <ph name="BEGIN_LINK2" />Дополнителните услови за користење на Google Chrome и Chrome OS<ph name="END_LINK2" />.</translation> <translation id="6294610283659775533">Може да испраќате картички меѓу уредите што се најавени со истата сметка на Google</translation> @@ -910,6 +921,7 @@ <translation id="6411219469806822692">Не може да одите повисоко. Почнете од погоре на страницата.</translation> <translation id="6412673304250309937">Ги проверува URL-адресите во список со небезбедни сајтови меморирани во Chrome. Ако некој сајт се обиде да ви ја украде лозинката или кога ќе преземете штетна датотека, Chrome може да испрати и URL-адреси, вклучувајќи и делови од содржините на страницата, во „Безбедно прелистување“.</translation> <translation id="641643625718530986">Печати...</translation> +<translation id="6422857128426228781">Следените производи ќе ги најдете тука</translation> <translation id="6433501201775827830">Изберете пребарувач</translation> <translation id="6434309073475700221">Отфрли</translation> <translation id="6437478888915024427">Информации за страницата</translation> @@ -987,6 +999,7 @@ <translation id="6817747507826986771">Брзо споделете ја страницава. За да ја измените сликава од екранот, допрете и задржете.</translation> <translation id="6820686453637990663">CVC</translation> <translation id="6824899148643461612">Избрана е картичката <ph name="TAB_TITLE" /></translation> +<translation id="6828070228333235514">Запри го следењето цени</translation> <translation id="6846298663435243399">Се вчитува…</translation> <translation id="6850409657436465440">Вашето преземање е сѐ уште е во тек</translation> <translation id="6850830437481525139"><ph name="TAB_COUNT" /> затворени картички</translation> @@ -1303,6 +1316,7 @@ <translation id="8571213806525832805">Изминатите 4 седмици</translation> <translation id="8572344201470131220">Сликата е копирана</translation> <translation id="8583805026567836021">Чистење податоци за сметка</translation> +<translation id="859046281437143747">Следете ја цената преку копчето „Повеќе опции“</translation> <translation id="860043288473659153">Име на сопственикот на картичката</translation> <translation id="8602358303461588329">Најавете се на Chrome, затворено.</translation> <translation id="860282621117673749">Известувања за попусти</translation>
diff --git a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb index 33206f4f..a0d89e7 100644 --- a/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb +++ b/chrome/browser/ui/android/strings/translations/android_chrome_strings_pl.xtb
@@ -15,6 +15,7 @@ <translation id="1100066534610197918">Otwórz w nowej karcie w grupie</translation> <translation id="1103142993930332957">Pomożesz w ulepszaniu Chrome?</translation> <translation id="1105960400813249514">Zrzut ekranu</translation> +<translation id="1108938384783527433">Synchronizacja historii</translation> <translation id="1110914759170138831">Podświetlenie zostało skrócone</translation> <translation id="1111673857033749125">Tutaj wyświetlą się zakładki z innych urządzeń.</translation> <translation id="1113597929977215864">Pokaż widok uproszczony</translation> @@ -160,6 +161,7 @@ <translation id="2000419248597011803">Niektóre pliki cookie oraz zapytania wpisane na pasku adresu i w polu wyszukiwania zostaną wysłane do domyślnej wyszukiwarki</translation> <translation id="200114059308480249">Uwzględniać tekst otaczający słowa, które wyszukujesz w Google?</translation> <translation id="2013642289801508067">{FILE_COUNT,plural, =1{# plik}few{# pliki}many{# plików}other{# pliku}}</translation> +<translation id="2020309681647789787">Będziesz mieć dostęp do swojej historii na wszystkich zsynchronizowanych urządzeniach, aby możliwe było kontynuowanie przerwanych działań</translation> <translation id="2021896219286479412">Elementy sterowania stroną na pełnym ekranie</translation> <translation id="2038563949887743358">Włącz opcję „Wersja na komputer”</translation> <translation id="204321170514947529">Dane aplikacji <ph name="APP_NAME" /> znajdują się też w Chrome</translation> @@ -858,6 +860,7 @@ <translation id="6070730414166672373">Kontaktuję się z bankiem\u2026</translation> <translation id="6085886413119427067">Określa, jak nawiązywać połączenia ze stronami przez zabezpieczone połączenie</translation> <translation id="60923314841986378">Pozostało: <ph name="HOURS" /> godz.</translation> +<translation id="6095578583683628124">Jeśli Google jest Twoją domyślną wyszukiwarką, zobaczysz lepiej dopasowane sugestie</translation> <translation id="6108923351542677676">Trwa konfigurowanie…</translation> <translation id="6111020039983847643">użytych danych</translation> <translation id="6112702117600201073">Odświeżam stronę</translation> @@ -1411,6 +1414,7 @@ <translation id="9148126808321036104">Zaloguj się ponownie</translation> <translation id="9155898266292537608">Możesz też wyszukiwać szybkim kliknięciem słowa</translation> <translation id="9158770349521403363">Udostępnij tylko treść</translation> +<translation id="916446198114569890">Odwiedzane adresy URL są zapisywane na Twoim koncie Google</translation> <translation id="9169507124922466868">Historia nawigacji jest otwarta w połowie</translation> <translation id="9199368092038462496">{NUM_MINS,plural, =1{Sprawdzano minutę temu}few{Sprawdzano # minuty temu}many{Sprawdzano # minut temu}other{Sprawdzano # minuty temu}}</translation> <translation id="9204836675896933765">Pozostał jeden plik</translation>
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java index 9c27bb45..eed62cd 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -125,6 +125,7 @@ * enabled. * @param initializeWithIncognitoColors Whether the toolbar should be initialized with incognito * colors. + * @param shouldHideToolbarLayoutOnStart Whether to hide toolbar layout on startup. */ public TopToolbarCoordinator(ToolbarControlContainer controlContainer, ToolbarLayout toolbarLayout, ToolbarDataProvider toolbarDataProvider, @@ -148,7 +149,7 @@ boolean isTabToGtsAnimationEnabled, boolean isStartSurfaceEnabled, boolean isTabGroupsAndroidContinuationEnabled, HistoryDelegate historyDelegate, BooleanSupplier partnerHomepageEnabledSupplier, OfflineDownloader offlineDownloader, - boolean initializeWithIncognitoColors) { + boolean initializeWithIncognitoColors, boolean shouldHideToolbarLayoutOnStart) { mControlContainer = controlContainer; mToolbarLayout = toolbarLayout; mMenuButtonCoordinator = browsingModeMenuButtonCoordinator; @@ -160,6 +161,7 @@ if (mToolbarLayout instanceof ToolbarPhone) { if (isStartSurfaceEnabled) { + if (shouldHideToolbarLayoutOnStart) mToolbarLayout.setVisibility(View.GONE); View.OnClickListener homeButtonOnClickListener = v -> { if (tabController != null) { tabController.openHomepage();
diff --git a/chrome/browser/ui/app_list/DEPS b/chrome/browser/ui/app_list/DEPS index 69e401c..7fbe8cc 100644 --- a/chrome/browser/ui/app_list/DEPS +++ b/chrome/browser/ui/app_list/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+ash/app_list/model", + "+ash/resources", "+components/services/app_service/public", ] @@ -12,6 +13,8 @@ ], "app_list_sort_browsertest\.cc": [ + "+ash/app_list/views/app_list_item_view.h", + "+ash/app_list/views/app_list_menu_model_adapter.h", "+ash/app_list/views/apps_grid_context_menu.h", "+ash/app_list/views/apps_grid_view.h", "+ash/shell.h",
diff --git a/chrome/browser/ui/app_list/app_context_menu.cc b/chrome/browser/ui/app_list/app_context_menu.cc index 652f4f1f..581268b 100644 --- a/chrome/browser/ui/app_list/app_context_menu.cc +++ b/chrome/browser/ui/app_list/app_context_menu.cc
@@ -8,6 +8,7 @@ #include "ash/public/cpp/app_menu_constants.h" #include "ash/public/cpp/shelf_model.h" +#include "ash/resources/vector_icons/vector_icons.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/app_list/app_context_menu_delegate.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" @@ -115,6 +116,8 @@ case ash::USE_LAUNCH_TYPE_WINDOW: // Check items use the default icon. return gfx::kNoneIcon; + case ash::REORDER_SUBMENU: + return ash::kReorderIcon; case ash::NOTIFICATION_CONTAINER: NOTREACHED() << "NOTIFICATION_CONTAINER does not have an icon, and it is " "added to the model by NotificationMenuController.";
diff --git a/chrome/browser/ui/app_list/app_context_menu_unittest.cc b/chrome/browser/ui/app_list/app_context_menu_unittest.cc index 5b43101..06ac731 100644 --- a/chrome/browser/ui/app_list/app_context_menu_unittest.cc +++ b/chrome/browser/ui/app_list/app_context_menu_unittest.cc
@@ -126,11 +126,13 @@ ChromeAppListItem* item) { base::RunLoop run_loop; std::unique_ptr<ui::SimpleMenuModel> menu; - item->GetContextMenuModel(base::BindLambdaForTesting( - [&](std::unique_ptr<ui::SimpleMenuModel> created_menu) { - menu = std::move(created_menu); - run_loop.Quit(); - })); + item->GetContextMenuModel( + /*add_sort_options=*/false, + base::BindLambdaForTesting( + [&](std::unique_ptr<ui::SimpleMenuModel> created_menu) { + menu = std::move(created_menu); + run_loop.Quit(); + })); run_loop.Run(); return menu; } @@ -269,8 +271,8 @@ controller_->SetAppPinnable(app_id, pinnable); controller_->SetExtensionLaunchType(profile(), app_id, launch_type); - AppServiceContextMenu menu(menu_delegate(), profile(), app_id, - controller()); + AppServiceContextMenu menu(menu_delegate(), profile(), app_id, controller(), + /*add_sort_options=*/false); std::unique_ptr<ui::MenuModel> menu_model = GetMenuModel(&menu); ASSERT_NE(nullptr, menu_model); @@ -315,7 +317,8 @@ controller_ = std::make_unique<FakeAppListControllerDelegate>(); AppServiceContextMenu menu(menu_delegate(), profile(), - extension_misc::kChromeAppId, controller()); + extension_misc::kChromeAppId, controller(), + /*add_sort_options=*/false); std::unique_ptr<ui::MenuModel> menu_model = GetMenuModel(&menu); ASSERT_NE(nullptr, menu_model); @@ -368,7 +371,8 @@ TEST_F(AppContextMenuTest, NonExistingExtensionApp) { AppServiceContextMenu menu(menu_delegate(), profile(), - "some_non_existing_extension_app", controller()); + "some_non_existing_extension_app", controller(), + /*add_sort_options=*/false); std::unique_ptr<ui::MenuModel> menu_model = GetMenuModel(&menu); EXPECT_EQ(nullptr, menu_model); } @@ -706,7 +710,8 @@ // Create the context menu. AppServiceContextMenu menu(menu_delegate(), profile(), - extension_misc::kLacrosAppId, controller()); + extension_misc::kLacrosAppId, controller(), + /*add_sort_options=*/false); std::unique_ptr<ui::MenuModel> menu_model = GetMenuModel(&menu); ASSERT_NE(menu_model, nullptr);
diff --git a/chrome/browser/ui/app_list/app_list_client_impl.cc b/chrome/browser/ui/app_list/app_list_client_impl.cc index df744d6..8c8e212 100644 --- a/chrome/browser/ui/app_list/app_list_client_impl.cc +++ b/chrome/browser/ui/app_list/app_list_client_impl.cc
@@ -273,6 +273,7 @@ void AppListClientImpl::GetContextMenuModel( int profile_id, const std::string& id, + bool add_sort_options, GetContextMenuModelCallback callback) { auto* requested_model_updater = profile_model_mappings_[profile_id]; if (requested_model_updater != current_model_updater_ || @@ -281,12 +282,13 @@ return; } requested_model_updater->GetContextMenuModel( - id, base::BindOnce( - [](GetContextMenuModelCallback callback, - std::unique_ptr<ui::SimpleMenuModel> menu_model) { - std::move(callback).Run(std::move(menu_model)); - }, - std::move(callback))); + id, add_sort_options, + base::BindOnce( + [](GetContextMenuModelCallback callback, + std::unique_ptr<ui::SimpleMenuModel> menu_model) { + std::move(callback).Run(std::move(menu_model)); + }, + std::move(callback))); } void AppListClientImpl::OnAppListVisibilityWillChange(bool visible) {
diff --git a/chrome/browser/ui/app_list/app_list_client_impl.h b/chrome/browser/ui/app_list/app_list_client_impl.h index 9c26b82..aff6c0d 100644 --- a/chrome/browser/ui/app_list/app_list_client_impl.h +++ b/chrome/browser/ui/app_list/app_list_client_impl.h
@@ -95,6 +95,7 @@ int event_flags) override; void GetContextMenuModel(int profile_id, const std::string& id, + bool add_sort_options, GetContextMenuModelCallback callback) override; void OnAppListVisibilityWillChange(bool visible) override; void OnAppListVisibilityChanged(bool visible) override;
diff --git a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc index c34eafbe..81ebb91 100644 --- a/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc +++ b/chrome/browser/ui/app_list/app_list_client_impl_browsertest.cc
@@ -333,11 +333,13 @@ base::RunLoop run_loop; std::unique_ptr<ui::SimpleMenuModel> menu_model; - item->GetContextMenuModel(base::BindLambdaForTesting( - [&](std::unique_ptr<ui::SimpleMenuModel> created_menu) { - menu_model = std::move(created_menu); - run_loop.Quit(); - })); + item->GetContextMenuModel( + /*add_sort_options=*/false, + base::BindLambdaForTesting( + [&](std::unique_ptr<ui::SimpleMenuModel> created_menu) { + menu_model = std::move(created_menu); + run_loop.Quit(); + })); run_loop.Run(); EXPECT_TRUE(menu_model);
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h index 3ed8aab5..65e9cb1 100644 --- a/chrome/browser/ui/app_list/app_list_model_updater.h +++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -123,6 +123,7 @@ using GetMenuModelCallback = base::OnceCallback<void(std::unique_ptr<ui::SimpleMenuModel>)>; virtual void GetContextMenuModel(const std::string& id, + bool add_sort_options, GetMenuModelCallback callback) = 0; virtual size_t BadgedItemCount() = 0; // For SearchModel:
diff --git a/chrome/browser/ui/app_list/app_list_sort_browsertest.cc b/chrome/browser/ui/app_list/app_list_sort_browsertest.cc index c7f8b414..f808067 100644 --- a/chrome/browser/ui/app_list/app_list_sort_browsertest.cc +++ b/chrome/browser/ui/app_list/app_list_sort_browsertest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/app_list/views/app_list_item_view.h" +#include "ash/app_list/views/app_list_menu_model_adapter.h" #include "ash/app_list/views/apps_grid_context_menu.h" #include "ash/app_list/views/apps_grid_view.h" #include "ash/constants/ash_features.h" @@ -20,6 +22,23 @@ #include "ui/views/controls/menu/submenu_view.h" #include "ui/views/view.h" +namespace { + +// Creates a RunLoop that waits until the context menu of app list item is +// shown. +void WaitUntilItemMenuShown(ash::AppListItemView* item_view) { + base::RunLoop run_loop; + + // Set the callback that will quit the RunLoop when context menu is shown. + item_view->SetContextMenuShownCallbackForTest(run_loop.QuitClosure()); + run_loop.Run(); + + // Reset the callback. + item_view->SetContextMenuShownCallbackForTest(base::RepeatingClosure()); +} + +} // namespace + class AppListSortBrowserTest : public extensions::ExtensionBrowserTest { public: AppListSortBrowserTest() = default; @@ -295,3 +314,186 @@ EXPECT_EQ(GetAppIdsInOrdinalOrder(), std::vector<std::string>({app3_id_, app2_id_, app1_id_})); } + +// Verifies that the apps in the top level apps grid can be arranged in the +// (reverse) alphabetical order using the context menu in app list item view. +// TODO(crbug.com/1267369): Also add a test that verifies the behavior in tablet +// mode. +IN_PROC_BROWSER_TEST_F(AppListSortBrowserTest, + ContextMenuOnAppListItemSortItemsInTopLevel) { + ash::ShellTestApi().SetTabletModeEnabledForTest(false); + ash::AcceleratorController::Get()->PerformActionIfEnabled( + ash::TOGGLE_APP_LIST_FULLSCREEN, {}); + + ash::AppListItemView* item_view = + app_list_test_api_.GetTopLevelAppsGridView()->view_model()->view_at(0); + + // Right click on the app item to show the context menu. + gfx::Point point_on_app = item_view->GetBoundsInScreen().CenterPoint(); + event_generator_->MoveMouseTo(point_on_app); + event_generator_->ClickRightButton(); + WaitUntilItemMenuShown(item_view); + + ash::AppListMenuModelAdapter* menu_model_adapter = item_view->context_menu(); + ASSERT_TRUE(menu_model_adapter->root_for_testing()->SubmenuIsShowing()); + + // Cache the current context menu view. + views::MenuItemView* reorder_submenu = item_view->context_menu() + ->root_for_testing() + ->GetSubmenu() + ->GetLastItem(); + + ASSERT_EQ(reorder_submenu->title(), u"Reorder by name"); + + // Get a point on the Reorder by Name option. + gfx::Point reorder_submenu_point = + reorder_submenu->GetBoundsInScreen().CenterPoint(); + + // Open the Reorder by Name submenu. + event_generator_->MoveMouseTo(reorder_submenu_point); + event_generator_->ClickLeftButton(); + ASSERT_TRUE(reorder_submenu->SubmenuIsShowing()); + + // Sort the apps by name in alphabetical order. + const gfx::Point alphabetical_option = reorder_submenu->GetSubmenu() + ->GetMenuItemAt(0) + ->GetBoundsInScreen() + .CenterPoint(); + event_generator_->MoveMouseTo(alphabetical_option); + event_generator_->ClickLeftButton(); + EXPECT_EQ(GetAppIdsInOrdinalOrder(), + std::vector<std::string>({app1_id_, app2_id_, app3_id_})); + + // Update `item_view` and sort the apps in reverse alphabetical order this + // time. + item_view = + app_list_test_api_.GetTopLevelAppsGridView()->view_model()->view_at(0); + point_on_app = item_view->GetBoundsInScreen().CenterPoint(); + + // Right click on the app item to show the context menu. + event_generator_->MoveMouseTo(point_on_app); + event_generator_->ClickRightButton(); + WaitUntilItemMenuShown(item_view); + + menu_model_adapter = item_view->context_menu(); + ASSERT_TRUE(menu_model_adapter->root_for_testing()->SubmenuIsShowing()); + + // Update the context menu. + reorder_submenu = item_view->context_menu() + ->root_for_testing() + ->GetSubmenu() + ->GetLastItem(); + ASSERT_EQ(reorder_submenu->title(), u"Reorder by name"); + reorder_submenu_point = reorder_submenu->GetBoundsInScreen().CenterPoint(); + + // Open the Reorder by Name submenu. + event_generator_->MoveMouseTo(reorder_submenu_point); + event_generator_->ClickLeftButton(); + ASSERT_TRUE(reorder_submenu->SubmenuIsShowing()); + + // Sort the apps by name in reverse alphabetical order. + const gfx::Point reverse_option = reorder_submenu->GetSubmenu() + ->GetMenuItemAt(1) + ->GetBoundsInScreen() + .CenterPoint(); + event_generator_->MoveMouseTo(reverse_option); + event_generator_->ClickLeftButton(); + EXPECT_EQ(GetAppIdsInOrdinalOrder(), + std::vector<std::string>({app3_id_, app2_id_, app1_id_})); +} + +// Verifies that the apps in a folder can be arranged in the (reverse) +// alphabetical order using the context menu in app list item view. +// TODO(crbug.com/1267369): Also add a test that verifies the behavior in tablet +// mode. +IN_PROC_BROWSER_TEST_F(AppListSortBrowserTest, + ContextMenuOnAppListItemSortItemsInFolder) { + ash::ShellTestApi().SetTabletModeEnabledForTest(false); + ash::AcceleratorController::Get()->PerformActionIfEnabled( + ash::TOGGLE_APP_LIST_FULLSCREEN, {}); + + // Move apps to one folder. + app_list_test_api_.CreateFolderWithApps({app1_id_, app2_id_, app3_id_}); + + ash::AppListItemView* item_view = + app_list_test_api_.GetTopLevelAppsGridView()->view_model()->view_at(1); + + // Make sure we don't right click on a folder. + ASSERT_FALSE(item_view->is_folder()); + + // Right click on the app item to show the context menu. + gfx::Point point_on_app = item_view->GetBoundsInScreen().CenterPoint(); + event_generator_->MoveMouseTo(point_on_app); + event_generator_->ClickRightButton(); + WaitUntilItemMenuShown(item_view); + + ash::AppListMenuModelAdapter* menu_model_adapter = item_view->context_menu(); + ASSERT_TRUE(menu_model_adapter->root_for_testing()->SubmenuIsShowing()); + + // Cache the current context menu view. + views::MenuItemView* reorder_submenu = item_view->context_menu() + ->root_for_testing() + ->GetSubmenu() + ->GetLastItem(); + + ASSERT_EQ(reorder_submenu->title(), u"Reorder by name"); + + // Get a point on the Reorder by Name option. + gfx::Point reorder_submenu_point = + reorder_submenu->GetBoundsInScreen().CenterPoint(); + + // Open the Reorder by Name submenu. + event_generator_->MoveMouseTo(reorder_submenu_point); + event_generator_->ClickLeftButton(); + ASSERT_TRUE(reorder_submenu->SubmenuIsShowing()); + + // Sort the apps by name in alphabetical order. + const gfx::Point alphabetical_option = reorder_submenu->GetSubmenu() + ->GetMenuItemAt(0) + ->GetBoundsInScreen() + .CenterPoint(); + event_generator_->MoveMouseTo(alphabetical_option); + event_generator_->ClickLeftButton(); + EXPECT_EQ(GetAppIdsInOrdinalOrder(), + std::vector<std::string>({app1_id_, app2_id_, app3_id_})); + + // Update `item_view` and sort the apps in reverse alphabetical order this + // time. + item_view = + app_list_test_api_.GetTopLevelAppsGridView()->view_model()->view_at(1); + + // Make sure we don't right click on a folder. + ASSERT_FALSE(item_view->is_folder()); + point_on_app = item_view->GetBoundsInScreen().CenterPoint(); + + // Right click on the app item to show the context menu. + event_generator_->MoveMouseTo(point_on_app); + event_generator_->ClickRightButton(); + WaitUntilItemMenuShown(item_view); + + menu_model_adapter = item_view->context_menu(); + ASSERT_TRUE(menu_model_adapter->root_for_testing()->SubmenuIsShowing()); + + // Update the context menu. + reorder_submenu = item_view->context_menu() + ->root_for_testing() + ->GetSubmenu() + ->GetLastItem(); + ASSERT_EQ(reorder_submenu->title(), u"Reorder by name"); + reorder_submenu_point = reorder_submenu->GetBoundsInScreen().CenterPoint(); + + // Open the Reorder by Name submenu. + event_generator_->MoveMouseTo(reorder_submenu_point); + event_generator_->ClickLeftButton(); + ASSERT_TRUE(reorder_submenu->SubmenuIsShowing()); + + // Sort the apps by name in reverse alphabetical order. + const gfx::Point reverse_option = reorder_submenu->GetSubmenu() + ->GetMenuItemAt(1) + ->GetBoundsInScreen() + .CenterPoint(); + event_generator_->MoveMouseTo(reverse_option); + event_generator_->ClickLeftButton(); + EXPECT_EQ(GetAppIdsInOrdinalOrder(), + std::vector<std::string>({app3_id_, app2_id_, app1_id_})); +}
diff --git a/chrome/browser/ui/app_list/app_service/app_service_app_item.cc b/chrome/browser/ui/app_list/app_service/app_service_app_item.cc index 2e4c9bc..39b1ca8 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_app_item.cc +++ b/chrome/browser/ui/app_list/app_service/app_service_app_item.cc
@@ -24,6 +24,8 @@ #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" #include "chrome/browser/ui/app_list/app_service/app_service_context_menu.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" +#include "chrome/common/chrome_features.h" +#include "components/services/app_service/public/cpp/app_types.h" // static const char AppServiceAppItem::kItemType[] = "AppServiceAppItem"; @@ -151,9 +153,10 @@ return AppServiceAppItem::kItemType; } -void AppServiceAppItem::GetContextMenuModel(GetMenuModelCallback callback) { - context_menu_ = std::make_unique<AppServiceContextMenu>(this, profile(), id(), - GetController()); +void AppServiceAppItem::GetContextMenuModel(bool add_sort_options, + GetMenuModelCallback callback) { + context_menu_ = std::make_unique<AppServiceContextMenu>( + this, profile(), id(), GetController(), add_sort_options); context_menu_->GetMenuModel(std::move(callback)); } @@ -181,18 +184,26 @@ } void AppServiceAppItem::CallLoadIcon(bool allow_placeholder_icon) { - auto icon_type = apps::mojom::IconType::kStandard; - apps::AppServiceProxyFactory::GetForProfile(profile())->LoadIcon( - app_type_, id(), icon_type, - ash::SharedAppListConfig::instance().default_grid_icon_dimension(), - allow_placeholder_icon, - base::BindOnce(&AppServiceAppItem::OnLoadIcon, - weak_ptr_factory_.GetWeakPtr())); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + apps::AppServiceProxyFactory::GetForProfile(profile())->LoadIcon( + apps::ConvertMojomAppTypToAppType(app_type_), id(), + apps::IconType::kStandard, + ash::SharedAppListConfig::instance().default_grid_icon_dimension(), + allow_placeholder_icon, + base::BindOnce(&AppServiceAppItem::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr())); + } else { + apps::AppServiceProxyFactory::GetForProfile(profile())->LoadIcon( + app_type_, id(), apps::mojom::IconType::kStandard, + ash::SharedAppListConfig::instance().default_grid_icon_dimension(), + allow_placeholder_icon, + apps::MojomIconValueToIconValueCallback(base::BindOnce( + &AppServiceAppItem::OnLoadIcon, weak_ptr_factory_.GetWeakPtr()))); + } } -void AppServiceAppItem::OnLoadIcon(apps::mojom::IconValuePtr icon_value) { - auto icon_type = apps::mojom::IconType::kStandard; - if (icon_value->icon_type != icon_type) { +void AppServiceAppItem::OnLoadIcon(apps::IconValuePtr icon_value) { + if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) { return; } SetIcon(icon_value->uncompressed);
diff --git a/chrome/browser/ui/app_list/app_service/app_service_app_item.h b/chrome/browser/ui/app_list/app_service/app_service_app_item.h index afe90f51..e09fceb3 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_app_item.h +++ b/chrome/browser/ui/app_list/app_service/app_service_app_item.h
@@ -11,6 +11,7 @@ #include "chrome/browser/ui/app_list/app_context_menu_delegate.h" #include "chrome/browser/ui/app_list/chrome_app_list_item.h" #include "components/services/app_service/public/cpp/app_update.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/mojom/types.mojom-forward.h" class AppServiceAppItem : public ChromeAppListItem, @@ -37,7 +38,8 @@ void LoadIcon() override; void Activate(int event_flags) override; const char* GetItemType() const override; - void GetContextMenuModel(GetMenuModelCallback callback) override; + void GetContextMenuModel(bool add_sort_options, + GetMenuModelCallback callback) override; app_list::AppContextMenu* GetAppContextMenu() override; // app_list::AppContextMenuDelegate overrides: @@ -46,7 +48,7 @@ void Launch(int event_flags, apps::mojom::LaunchSource launch_source); void CallLoadIcon(bool allow_placeholder_icon); - void OnLoadIcon(apps::mojom::IconValuePtr icon_value); + void OnLoadIcon(apps::IconValuePtr icon_value); apps::mojom::AppType app_type_; bool is_platform_app_;
diff --git a/chrome/browser/ui/app_list/app_service/app_service_context_menu.cc b/chrome/browser/ui/app_list/app_service/app_service_context_menu.cc index 754dd5c..f6b2d2d 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_context_menu.cc +++ b/chrome/browser/ui/app_list/app_service/app_service_context_menu.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/app_list/app_service/app_service_context_menu.h" +#include "ash/public/cpp/app_list/app_list_types.h" #include "ash/public/cpp/app_menu_constants.h" #include "ash/public/cpp/new_window_delegate.h" #include "base/bind.h" @@ -26,6 +27,10 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/app_context_menu_delegate.h" #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" +#include "chrome/browser/ui/app_list/app_list_model_updater.h" +#include "chrome/browser/ui/app_list/app_list_syncable_service.h" +#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" +#include "chrome/browser/ui/app_list/chrome_app_list_model_updater.h" #include "chrome/browser/ui/app_list/extension_app_utils.h" #include "chrome/browser/ui/ash/shelf/standalone_browser_extension_app_context_menu.h" #include "chrome/browser/ui/chrome_pages.h" @@ -40,6 +45,14 @@ namespace { +void RequestAppListSort(Profile* profile, ash::AppListSortOrder order) { + ChromeAppListModelUpdater* model_updater = + static_cast<ChromeAppListModelUpdater*>( + app_list::AppListSyncableServiceFactory::GetForProfile(profile) + ->GetModelUpdater()); + model_updater->RequestAppListSort(order); +} + bool MenuItemHasLauncherContext(const extensions::MenuItem* item) { return item->contexts().Contains(extensions::MenuItem::LAUNCHER); } @@ -80,9 +93,11 @@ app_list::AppContextMenuDelegate* delegate, Profile* profile, const std::string& app_id, - AppListControllerDelegate* controller) + AppListControllerDelegate* controller, + bool add_sort_options) : AppContextMenu(delegate, profile, app_id, controller), - proxy_(apps::AppServiceProxyFactory::GetForProfile(profile)) { + proxy_(apps::AppServiceProxyFactory::GetForProfile(profile)), + add_sort_options_(add_sort_options) { proxy_->AppRegistryCache().ForOneApp( app_id, [this](const apps::AppUpdate& update) { app_type_ = apps_util::IsInstalled(update.Readiness()) @@ -186,6 +201,15 @@ } break; + case ash::REORDER_BY_NAME_ALPHABETICAL: + RequestAppListSort(profile(), ash::AppListSortOrder::kNameAlphabetical); + break; + + case ash::REORDER_BY_NAME_REVERSE_ALPHABETICAL: + RequestAppListSort(profile(), + ash::AppListSortOrder::kNameReverseAlphabetical); + break; + default: if (command_id >= ash::USE_LAUNCH_TYPE_COMMAND_START && command_id < ash::USE_LAUNCH_TYPE_COMMAND_END) { @@ -327,6 +351,24 @@ } } + if (add_sort_options_) { + reorder_submenu_ = std::make_unique<ui::SimpleMenuModel>(this); + // As all the options below are only for tests and are expected to change in + // the future, the strings are directly written as the parameters. + // TODO(crbug.com/1269386): Change the testing strings to the strings we + // want when the feature is enabled by default and use string ids to + // interpret them. + reorder_submenu_->AddItem(ash::REORDER_BY_NAME_ALPHABETICAL, + u"Alphabetical"); + reorder_submenu_->AddItem(ash::REORDER_BY_NAME_REVERSE_ALPHABETICAL, + u"Reverse alphabetical"); + menu_model->AddSeparator(ui::NORMAL_SEPARATOR); + menu_model->AddSubMenuWithIcon( + ash::REORDER_SUBMENU, u"Reorder by name", reorder_submenu_.get(), + ui::ImageModel::FromVectorIcon( + GetMenuItemVectorIcon(ash::REORDER_SUBMENU, /*string_id=*/-1))); + } + std::move(callback).Run(std::move(menu_model)); }
diff --git a/chrome/browser/ui/app_list/app_service/app_service_context_menu.h b/chrome/browser/ui/app_list/app_service/app_service_context_menu.h index 07d83a7..80c0819 100644 --- a/chrome/browser/ui/app_list/app_service/app_service_context_menu.h +++ b/chrome/browser/ui/app_list/app_service/app_service_context_menu.h
@@ -29,7 +29,8 @@ AppServiceContextMenu(app_list::AppContextMenuDelegate* delegate, Profile* profile, const std::string& app_id, - AppListControllerDelegate* controller); + AppListControllerDelegate* controller, + bool add_sort_options); ~AppServiceContextMenu() override; AppServiceContextMenu(const AppServiceContextMenu&) = delete; @@ -59,6 +60,10 @@ // The SimpleMenuModel used to hold the submenu items. std::unique_ptr<ui::SimpleMenuModel> submenu_; + // The SimpleMenuModel that contains reorder options. Could be nullptr if + // sorting is not available. + std::unique_ptr<ui::SimpleMenuModel> reorder_submenu_; + std::unique_ptr<extensions::ContextMenuMatcher> extension_menu_items_; // This member holds all logic for context menus associated with standalone @@ -71,6 +76,9 @@ apps::AppServiceProxy* const proxy_; + // A flag that determines if sort options should be added to the context menu. + bool add_sort_options_ = false; + base::WeakPtrFactory<AppServiceContextMenu> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc index d0bbb7b..f9759ad 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -11,6 +11,7 @@ #include "ash/components/arc/arc_prefs.h" #include "ash/components/arc/arc_util.h" +#include "ash/components/arc/compat_mode/arc_resize_lock_manager.h" #include "ash/constants/ash_features.h" #include "ash/constants/ash_switches.h" #include "base/bind.h" @@ -41,7 +42,6 @@ #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" #include "chrome/common/chrome_features.h" #include "chrome/grit/generated_resources.h" -#include "components/arc/compat_mode/arc_resize_lock_manager.h" #include "components/arc/mojom/compatibility_mode.mojom.h" #include "components/arc/session/arc_bridge_service.h" #include "components/arc/session/arc_service_manager.h"
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 8ce4f31f..2eaeda80 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
@@ -14,6 +14,7 @@ #include <unordered_set> #include <vector> +#include "ash/components/arc/compat_mode/arc_resize_lock_pref_delegate.h" #include "base/callback.h" #include "base/files/file_path.h" #include "base/memory/scoped_refptr.h" @@ -25,7 +26,6 @@ #include "chrome/browser/ash/arc/policy/arc_policy_bridge.h" #include "chrome/browser/ash/arc/session/arc_session_manager_observer.h" #include "chrome/browser/ui/app_list/arc/arc_app_icon_descriptor.h" -#include "components/arc/compat_mode/arc_resize_lock_pref_delegate.h" #include "components/arc/mojom/app.mojom.h" #include "components/arc/mojom/compatibility_mode.mojom.h" #include "components/arc/session/connection_observer.h"
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc index 8c43d91..e239d2ce 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -73,13 +73,16 @@ #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" #include "chrome/browser/ui/ash/shelf/shelf_controller_helper.h" #include "chrome/browser/web_applications/test/fake_web_app_provider.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/chrome_paths.h" #include "chrome/test/base/testing_profile.h" #include "components/arc/mojom/app.mojom.h" #include "components/arc/mojom/compatibility_mode.mojom.h" #include "components/arc/session/arc_service_manager.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/app_update.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/cpp/intent_util.h" #include "components/services/app_service/public/cpp/stub_icon_loader.h" #include "components/services/app_service/public/mojom/types.mojom.h" @@ -2834,18 +2837,34 @@ apps::AppServiceProxyFactory::GetForProfile(profile_.get()); ASSERT_NE(nullptr, proxy); - proxy->LoadIcon( - apps::mojom::AppType::kArc, app_id, apps::mojom::IconType::kCompressed, - icon_size, false /*allow_placeholder_icon*/, - base::BindLambdaForTesting([&](apps::mojom::IconValuePtr icon_value) { - EXPECT_EQ(apps::mojom::IconType::kCompressed, icon_value->icon_type); - EXPECT_TRUE(icon_value->compressed); - std::vector<uint8_t> png_data = icon_value->compressed.value(); - std::string compressed(png_data.begin(), png_data.end()); - // Check that |compressed| starts with the 8-byte PNG magic string. - EXPECT_EQ(compressed.substr(0, 8), "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"); - quit.Run(); - })); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + proxy->LoadIcon( + apps::AppType::kArc, app_id, apps::IconType::kCompressed, icon_size, + false /*allow_placeholder_icon*/, + base::BindLambdaForTesting([&](apps::IconValuePtr icon_value) { + EXPECT_EQ(apps::IconType::kCompressed, icon_value->icon_type); + std::vector<uint8_t> png_data = icon_value->compressed; + std::string compressed(png_data.begin(), png_data.end()); + // Check that |compressed| starts with the 8-byte PNG magic string. + EXPECT_EQ(compressed.substr(0, 8), + "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"); + quit.Run(); + })); + } else { + proxy->LoadIcon( + apps::mojom::AppType::kArc, app_id, apps::mojom::IconType::kCompressed, + icon_size, false /*allow_placeholder_icon*/, + base::BindLambdaForTesting([&](apps::mojom::IconValuePtr icon_value) { + EXPECT_EQ(apps::mojom::IconType::kCompressed, icon_value->icon_type); + EXPECT_TRUE(icon_value->compressed); + std::vector<uint8_t> png_data = icon_value->compressed.value(); + std::string compressed(png_data.begin(), png_data.end()); + // Check that |compressed| starts with the 8-byte PNG magic string. + EXPECT_EQ(compressed.substr(0, 8), + "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a"); + quit.Run(); + })); + } run_loop.Run(); }
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.h b/chrome/browser/ui/app_list/arc/arc_app_utils.h index 5e62535..13cd0e0 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_utils.h +++ b/chrome/browser/ui/app_list/arc/arc_app_utils.h
@@ -45,7 +45,6 @@ extern const char kGoogleMapsAppId[]; extern const char kGooglePhotosAppId[]; extern const char kInfinitePainterAppId[]; -extern const char kLegacyCameraAppId[]; extern const char kLightRoomAppId[]; extern const char kPlayBooksAppId[]; extern const char kPlayGamesAppId[];
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item.cc b/chrome/browser/ui/app_list/chrome_app_list_item.cc index a45682c7..d64d5b7 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_item.cc +++ b/chrome/browser/ui/app_list/chrome_app_list_item.cc
@@ -98,7 +98,8 @@ return ""; } -void ChromeAppListItem::GetContextMenuModel(GetMenuModelCallback callback) { +void ChromeAppListItem::GetContextMenuModel(bool add_sort_options, + GetMenuModelCallback callback) { std::move(callback).Run(nullptr); }
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item.h b/chrome/browser/ui/app_list/chrome_app_list_item.h index 409b254d..19a6ea1 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_item.h +++ b/chrome/browser/ui/app_list/chrome_app_list_item.h
@@ -104,7 +104,8 @@ // takes the ownership of the returned menu model. using GetMenuModelCallback = base::OnceCallback<void(std::unique_ptr<ui::SimpleMenuModel>)>; - virtual void GetContextMenuModel(GetMenuModelCallback callback); + virtual void GetContextMenuModel(bool add_sort_options, + GetMenuModelCallback callback); // Returns true iff this item was badged because it's an extension app that // has its Android analog installed.
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc index 2fb4863..4fe7b5c 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -434,6 +434,7 @@ void ChromeAppListModelUpdater::GetContextMenuModel( const std::string& id, + bool add_sort_options, GetMenuModelCallback callback) { ChromeAppListItem* item = FindItem(id); // TODO(stevenjb/jennyz): Implement this for folder items. @@ -442,7 +443,7 @@ std::move(callback).Run(nullptr); return; } - item->GetContextMenuModel(std::move(callback)); + item->GetContextMenuModel(add_sort_options, std::move(callback)); } syncer::StringOrdinal ChromeAppListModelUpdater::CalculatePositionForNewItem(
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h index c3d9420..a2e598c9 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
@@ -89,6 +89,7 @@ void GetIdToAppListIndexMap(GetIdToAppListIndexMapCallback callback) override; size_t BadgedItemCount() override; void GetContextMenuModel(const std::string& id, + bool add_sort_options, GetMenuModelCallback callback) override; syncer::StringOrdinal CalculatePositionForNewItem( const ChromeAppListItem& new_item) override;
diff --git a/chrome/browser/ui/app_list/search/app_service_app_result.cc b/chrome/browser/ui/app_list/search/app_service_app_result.cc index f6673796..e612a9f7 100644 --- a/chrome/browser/ui/app_list/search/app_service_app_result.cc +++ b/chrome/browser/ui/app_list/search/app_service_app_result.cc
@@ -27,7 +27,9 @@ #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" #include "chrome/browser/web_applications/system_web_apps/system_web_app_manager.h" +#include "chrome/common/chrome_features.h" #include "components/favicon/core/large_icon_service.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/cpp/app_update.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "extensions/common/extension.h" @@ -115,7 +117,7 @@ } context_menu_ = std::make_unique<AppServiceContextMenu>( - this, profile(), app_id(), controller()); + this, profile(), app_id(), controller(), /*add_sort_options=*/false); context_menu_->GetMenuModel(std::move(callback)); } @@ -209,13 +211,17 @@ } void AppServiceAppResult::CallLoadIcon(bool chip, bool allow_placeholder_icon) { - if (icon_loader_) { - // If |icon_loader_releaser_| is non-null, assigning to it will signal to - // |icon_loader_| that the previous icon is no longer being used, as a hint - // that it could be flushed from any caches. - auto icon_type = apps::mojom::IconType::kStandard; + if (!icon_loader_) { + return; + } + + // If |icon_loader_releaser_| is non-null, assigning to it will signal to + // |icon_loader_| that the previous icon is no longer being used, as a hint + // that it could be flushed from any caches. + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { icon_loader_releaser_ = icon_loader_->LoadIcon( - app_type_, app_id(), icon_type, + apps::ConvertMojomAppTypToAppType(app_type_), app_id(), + apps::IconType::kStandard, chip ? ash::SharedAppListConfig::instance() .suggestion_chip_icon_dimension() : ash::SharedAppListConfig::instance().GetPreferredIconDimension( @@ -223,13 +229,22 @@ allow_placeholder_icon, base::BindOnce(&AppServiceAppResult::OnLoadIcon, weak_ptr_factory_.GetWeakPtr(), chip)); + } else { + icon_loader_releaser_ = icon_loader_->LoadIcon( + app_type_, app_id(), apps::mojom::IconType::kStandard, + chip ? ash::SharedAppListConfig::instance() + .suggestion_chip_icon_dimension() + : ash::SharedAppListConfig::instance().GetPreferredIconDimension( + display_type()), + allow_placeholder_icon, + apps::MojomIconValueToIconValueCallback( + base::BindOnce(&AppServiceAppResult::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr(), chip))); } } -void AppServiceAppResult::OnLoadIcon(bool chip, - apps::mojom::IconValuePtr icon_value) { - auto icon_type = apps::mojom::IconType::kStandard; - if (icon_value->icon_type != icon_type) { +void AppServiceAppResult::OnLoadIcon(bool chip, apps::IconValuePtr icon_value) { + if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) { return; }
diff --git a/chrome/browser/ui/app_list/search/app_service_app_result.h b/chrome/browser/ui/app_list/search/app_service_app_result.h index 63690e6..453186b 100644 --- a/chrome/browser/ui/app_list/search/app_service_app_result.h +++ b/chrome/browser/ui/app_list/search/app_service_app_result.h
@@ -13,6 +13,7 @@ #include "chrome/browser/ui/app_list/search/app_result.h" #include "components/favicon_base/favicon_types.h" #include "components/services/app_service/public/cpp/icon_cache.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/mojom/types.mojom-forward.h" #include "url/gurl.h" @@ -55,7 +56,7 @@ void Launch(int event_flags, apps::mojom::LaunchSource launch_source); void CallLoadIcon(bool chip, bool allow_placeholder_icon); - void OnLoadIcon(bool chip, apps::mojom::IconValuePtr icon_value); + void OnLoadIcon(bool chip, apps::IconValuePtr icon_value); void HandleSuggestionChip(Profile* profile);
diff --git a/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker.cc b/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker.cc index 7b4213b..6ee06004 100644 --- a/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker.cc +++ b/chrome/browser/ui/app_list/search/cros_action_history/cros_action_recorder_tab_tracker.cc
@@ -12,7 +12,9 @@ CrOSActionRecorderTabTracker::CrOSActionRecorderTabTracker( content::WebContents* web_contents) - : content::WebContentsObserver(web_contents) {} + : content::WebContentsObserver(web_contents), + content::WebContentsUserData<CrOSActionRecorderTabTracker>( + *web_contents) {} // A tab should be skipped if it is empty, blank or default page. bool CrOSActionRecorderTabTracker::ShouldSkip() {
diff --git a/chrome/browser/ui/app_list/search/help_app_provider.cc b/chrome/browser/ui/app_list/search/help_app_provider.cc index a7a8c7d..6c88fdb 100644 --- a/chrome/browser/ui/app_list/search/help_app_provider.cc +++ b/chrome/browser/ui/app_list/search/help_app_provider.cc
@@ -34,6 +34,7 @@ #include "chromeos/strings/grit/chromeos_strings.h" #include "components/prefs/pref_service.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "ui/base/l10n/l10n_util.h" #include "ui/gfx/image/image_skia.h" #include "url/gurl.h" @@ -336,22 +337,32 @@ Start(last_query_); } -void HelpAppProvider::OnLoadIcon(apps::mojom::IconValuePtr icon_value) { - auto icon_type = apps::mojom::IconType::kStandard; - if (icon_value->icon_type == icon_type) { +void HelpAppProvider::OnLoadIcon(apps::IconValuePtr icon_value) { + if (icon_value && icon_value->icon_type == apps::IconType::kStandard) { icon_ = icon_value->uncompressed; } } void HelpAppProvider::LoadIcon() { - auto icon_type = apps::mojom::IconType::kStandard; apps::mojom::AppType app_type = app_service_proxy_->AppRegistryCache().GetAppType(web_app::kHelpAppId); - app_service_proxy_->LoadIcon( - app_type, web_app::kHelpAppId, icon_type, - ash::SharedAppListConfig::instance().suggestion_chip_icon_dimension(), - /*allow_placeholder_icon=*/false, - base::BindOnce(&HelpAppProvider::OnLoadIcon, weak_factory_.GetWeakPtr())); + + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + app_service_proxy_->LoadIcon( + apps::ConvertMojomAppTypToAppType(app_type), web_app::kHelpAppId, + apps::IconType::kStandard, + ash::SharedAppListConfig::instance().suggestion_chip_icon_dimension(), + /*allow_placeholder_icon=*/false, + base::BindOnce(&HelpAppProvider::OnLoadIcon, + weak_factory_.GetWeakPtr())); + } else { + app_service_proxy_->LoadIcon( + app_type, web_app::kHelpAppId, apps::mojom::IconType::kStandard, + ash::SharedAppListConfig::instance().suggestion_chip_icon_dimension(), + /*allow_placeholder_icon=*/false, + apps::MojomIconValueToIconValueCallback(base::BindOnce( + &HelpAppProvider::OnLoadIcon, weak_factory_.GetWeakPtr()))); + } } } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/help_app_provider.h b/chrome/browser/ui/app_list/search/help_app_provider.h index 32f6fa2..3c11a0fa 100644 --- a/chrome/browser/ui/app_list/search/help_app_provider.h +++ b/chrome/browser/ui/app_list/search/help_app_provider.h
@@ -15,6 +15,7 @@ #include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/search_provider.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -93,7 +94,7 @@ const std::u16string& query, const base::TimeTicks& start_time, std::vector<ash::help_app::mojom::SearchResultPtr> results); - void OnLoadIcon(apps::mojom::IconValuePtr icon_value); + void OnLoadIcon(apps::IconValuePtr icon_value); void LoadIcon(); Profile* const profile_;
diff --git a/chrome/browser/ui/app_list/search/os_settings_provider.cc b/chrome/browser/ui/app_list/search/os_settings_provider.cc index bb7b1d90..13d84c1 100644 --- a/chrome/browser/ui/app_list/search/os_settings_provider.cc +++ b/chrome/browser/ui/app_list/search/os_settings_provider.cc
@@ -27,6 +27,7 @@ #include "chrome/browser/web_applications/web_app_id_constants.h" #include "chrome/common/chrome_features.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "ui/gfx/image/image_skia.h" #include "url/gurl.h" @@ -194,16 +195,26 @@ DCHECK(app_service_proxy_); Observe(&app_service_proxy_->AppRegistryCache()); - auto icon_type = apps::mojom::IconType::kStandard; apps::mojom::AppType app_type = app_service_proxy_->AppRegistryCache().GetAppType( web_app::kOsSettingsAppId); - app_service_proxy_->LoadIcon( - app_type, web_app::kOsSettingsAppId, icon_type, - ash::SharedAppListConfig::instance().search_list_icon_dimension(), - /*allow_placeholder_icon=*/false, - base::BindOnce(&OsSettingsProvider::OnLoadIcon, - weak_factory_.GetWeakPtr())); + + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + app_service_proxy_->LoadIcon( + apps::ConvertMojomAppTypToAppType(app_type), web_app::kOsSettingsAppId, + apps::IconType::kStandard, + ash::SharedAppListConfig::instance().search_list_icon_dimension(), + /*allow_placeholder_icon=*/false, + base::BindOnce(&OsSettingsProvider::OnLoadIcon, + weak_factory_.GetWeakPtr())); + } else { + app_service_proxy_->LoadIcon( + app_type, web_app::kOsSettingsAppId, apps::mojom::IconType::kStandard, + ash::SharedAppListConfig::instance().search_list_icon_dimension(), + /*allow_placeholder_icon=*/false, + apps::MojomIconValueToIconValueCallback(base::BindOnce( + &OsSettingsProvider::OnLoadIcon, weak_factory_.GetWeakPtr()))); + } // Set parameters from Finch. Reasonable defaults are set in the header. accept_alternate_matches_ = base::GetFieldTrialParamByFeatureAsBool( @@ -311,13 +322,24 @@ // Request the Settings app icon when either the readiness or the icon has // changed. if (update.ReadinessChanged() || update.IconKeyChanged()) { - auto icon_type = apps::mojom::IconType::kStandard; - app_service_proxy_->LoadIcon( - update.AppType(), web_app::kOsSettingsAppId, icon_type, - ash::SharedAppListConfig::instance().search_list_icon_dimension(), - /*allow_placeholder_icon=*/false, - base::BindOnce(&OsSettingsProvider::OnLoadIcon, - weak_factory_.GetWeakPtr())); + if (base::FeatureList::IsEnabled( + features::kAppServiceLoadIconWithoutMojom)) { + app_service_proxy_->LoadIcon( + apps::ConvertMojomAppTypToAppType(update.AppType()), + web_app::kOsSettingsAppId, apps::IconType::kStandard, + ash::SharedAppListConfig::instance().search_list_icon_dimension(), + /*allow_placeholder_icon=*/false, + base::BindOnce(&OsSettingsProvider::OnLoadIcon, + weak_factory_.GetWeakPtr())); + } else { + app_service_proxy_->LoadIcon( + update.AppType(), web_app::kOsSettingsAppId, + apps::mojom::IconType::kStandard, + ash::SharedAppListConfig::instance().search_list_icon_dimension(), + /*allow_placeholder_icon=*/false, + apps::MojomIconValueToIconValueCallback(base::BindOnce( + &OsSettingsProvider::OnLoadIcon, weak_factory_.GetWeakPtr()))); + } } } @@ -403,13 +425,10 @@ return clean_results; } -void OsSettingsProvider::OnLoadIcon(apps::mojom::IconValuePtr icon_value) { - if (icon_value.is_null()) - return; - - auto icon_type = apps::mojom::IconType::kStandard; - if (icon_value->icon_type == icon_type) { +void OsSettingsProvider::OnLoadIcon(apps::IconValuePtr icon_value) { + if (icon_value && icon_value->icon_type == apps::IconType::kStandard) { icon_ = icon_value->uncompressed; } } + } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/os_settings_provider.h b/chrome/browser/ui/app_list/search/os_settings_provider.h index 8f9691c..f3ff8aa 100644 --- a/chrome/browser/ui/app_list/search/os_settings_provider.h +++ b/chrome/browser/ui/app_list/search/os_settings_provider.h
@@ -15,6 +15,7 @@ #include "chrome/browser/ui/app_list/search/search_provider.h" #include "chrome/browser/ui/webui/settings/chromeos/search/search.mojom.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -110,7 +111,7 @@ const std::vector<chromeos::settings::mojom::SearchResultPtr>& results, const chromeos::settings::Hierarchy* hierarchy); - void OnLoadIcon(apps::mojom::IconValuePtr icon_value); + void OnLoadIcon(apps::IconValuePtr icon_value); // Scoring and filtering parameters controlled from Finch. bool accept_alternate_matches_ = false;
diff --git a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_event_logger.proto b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_event_logger.proto index 8d4651a..c0476d3 100644 --- a/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_event_logger.proto +++ b/chrome/browser/ui/app_list/search/search_result_ranker/app_launch_event_logger.proto
@@ -14,6 +14,7 @@ SUGGESTION_CHIP = 2; SHELF = 3; SEARCH_BOX = 4; + RECENT_APPS = 5; } // The component that the user launched the app from. optional LaunchedFrom launched_from = 1;
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc index ebe4bb03..c7c1f82 100644 --- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
@@ -168,6 +168,7 @@ void FakeAppListModelUpdater::GetContextMenuModel( const std::string& id, + bool add_sort_options, GetMenuModelCallback callback) { std::move(callback).Run(nullptr); }
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h index a9874a7..76fd34d 100644 --- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h +++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
@@ -60,6 +60,7 @@ void GetIdToAppListIndexMap(GetIdToAppListIndexMapCallback callback) override; syncer::StringOrdinal GetPositionBeforeFirstItem() const override; void GetContextMenuModel(const std::string& id, + bool add_sort_options, GetMenuModelCallback callback) override; syncer::StringOrdinal CalculatePositionForNewItem( const ChromeAppListItem& new_item) override;
diff --git a/chrome/browser/ui/ash/chrome_desks_templates_delegate.cc b/chrome/browser/ui/ash/chrome_desks_templates_delegate.cc index 95b9caa..a897110 100644 --- a/chrome/browser/ui/ash/chrome_desks_templates_delegate.cc +++ b/chrome/browser/ui/ash/chrome_desks_templates_delegate.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/ui/ash/desks_client.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/common/chrome_features.h" #include "components/app_restore/app_launch_info.h" #include "components/app_restore/app_restore_data.h" #include "components/app_restore/features.h" @@ -26,6 +27,7 @@ #include "components/app_restore/window_properties.h" #include "components/favicon/core/favicon_service.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "components/services/app_service/public/mojom/types.mojom.h" #include "components/user_manager/user_manager.h" #include "extensions/common/constants.h" @@ -152,19 +154,26 @@ void ChromeDesksTemplatesDelegate::GetIconForAppId( const std::string& app_id, int desired_icon_size, - base::OnceCallback<void(apps::mojom::IconValuePtr icon_value)> callback) - const { + base::OnceCallback<void(apps::IconValuePtr icon_value)> callback) const { auto* app_service_proxy = apps::AppServiceProxyFactory::GetForProfile( ProfileManager::GetActiveUserProfile()); if (!app_service_proxy) { - std::move(callback).Run(apps::mojom::IconValue::New()); + std::move(callback).Run(std::make_unique<apps::IconValue>()); return; } - app_service_proxy->LoadIcon( - app_service_proxy->AppRegistryCache().GetAppType(app_id), app_id, - apps::mojom::IconType::kStandard, desired_icon_size, - /*allow_placeholder_icon=*/false, std::move(callback)); + auto app_type = app_service_proxy->AppRegistryCache().GetAppType(app_id); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + app_service_proxy->LoadIcon( + apps::ConvertMojomAppTypToAppType(app_type), app_id, + apps::IconType::kStandard, desired_icon_size, + /*allow_placeholder_icon=*/false, std::move(callback)); + } else { + app_service_proxy->LoadIcon( + app_type, app_id, apps::mojom::IconType::kStandard, desired_icon_size, + /*allow_placeholder_icon=*/false, + apps::MojomIconValueToIconValueCallback(std::move(callback))); + } } void ChromeDesksTemplatesDelegate::LaunchAppsFromTemplate(
diff --git a/chrome/browser/ui/ash/chrome_desks_templates_delegate.h b/chrome/browser/ui/ash/chrome_desks_templates_delegate.h index 7bbf328..a0350c6 100644 --- a/chrome/browser/ui/ash/chrome_desks_templates_delegate.h +++ b/chrome/browser/ui/ash/chrome_desks_templates_delegate.h
@@ -10,7 +10,7 @@ #include "ash/public/cpp/desks_templates_delegate.h" #include "base/callback_forward.h" #include "components/favicon_base/favicon_callback.h" -#include "components/services/app_service/public/mojom/app_service.mojom.h" +#include "components/services/app_service/public/cpp/icon_types.h" namespace base { class CancelableTaskTracker; @@ -32,11 +32,10 @@ int desired_icon_size, favicon_base::FaviconRawBitmapCallback callback, base::CancelableTaskTracker* tracker) const override; - void GetIconForAppId( - const std::string& app_id, - int desired_icon_size, - base::OnceCallback<void(apps::mojom::IconValuePtr icon_value)> callback) - const override; + void GetIconForAppId(const std::string& app_id, + int desired_icon_size, + base::OnceCallback<void(apps::IconValuePtr icon_value)> + callback) const override; void LaunchAppsFromTemplate( std::unique_ptr<ash::DeskTemplate> desk_template) override; bool IsWindowSupportedForDeskTemplate(aura::Window* window) const override;
diff --git a/chrome/browser/ui/ash/chrome_new_window_client.cc b/chrome/browser/ui/ash/chrome_new_window_client.cc index 250cdf51..71c546fa 100644 --- a/chrome/browser/ui/ash/chrome_new_window_client.cc +++ b/chrome/browser/ui/ash/chrome_new_window_client.cc
@@ -593,7 +593,7 @@ // Add a flag to remember this tab originated in the ARC context. tab->SetUserData(&arc::ArcWebContentsData::kArcTransitionFlag, - std::make_unique<arc::ArcWebContentsData>()); + std::make_unique<arc::ArcWebContentsData>(tab)); apps::IntentHandlingMetrics::RecordOpenBrowserMetrics( apps::IntentHandlingMetrics::AppType::kArc);
diff --git a/chrome/browser/ui/ash/projector/projector_annotator_controller_browsertest.cc b/chrome/browser/ui/ash/projector/projector_annotator_controller_browsertest.cc deleted file mode 100644 index 36dd182..0000000 --- a/chrome/browser/ui/ash/projector/projector_annotator_controller_browsertest.cc +++ /dev/null
@@ -1,130 +0,0 @@ -// 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 <memory> -#include <vector> - -#include "ash/constants/ash_features.h" -#include "ash/public/cpp/projector/projector_annotator_controller.h" -#include "ash/public/cpp/projector/projector_controller.h" -#include "ash/public/cpp/test/mock_projector_controller.h" -#include "ash/webui/projector_app/annotator_tool.h" -#include "ash/webui/projector_app/public/cpp/projector_app_constants.h" -#include "base/run_loop.h" -#include "base/test/scoped_feature_list.h" -#include "chrome/browser/ui/ash/capture_mode/chrome_capture_mode_delegate.h" -#include "chrome/browser/ui/ash/capture_mode/recording_overlay_view_impl.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/base/ui_test_utils.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_ui.h" -#include "content/public/test/browser_test.h" -#include "content/public/test/test_navigation_observer.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/views/controls/webview/webview.h" -#include "url/gurl.h" - -namespace ash { - -class RecordingOverlayView; - -class ProjectorAnnotatorControllerTest : public InProcessBrowserTest { - public: - ProjectorAnnotatorControllerTest() { - scoped_feature_list_.InitWithFeatures( - /*enabled_features=*/{features::kProjector, - features::kProjectorAnnotator}, - /*disabled_features=*/{}); - } - ProjectorAnnotatorControllerTest(const ProjectorAnnotatorControllerTest&) = - delete; - ProjectorAnnotatorControllerTest& operator=( - const ProjectorAnnotatorControllerTest&) = delete; - ~ProjectorAnnotatorControllerTest() override = default; - - // InProcessBrowserTest: - void SetUpOnMainThread() override { - InProcessBrowserTest::SetUpOnMainThread(); - - scoped_resetter_ = - std::make_unique<ProjectorController::ScopedInstanceResetterForTest>(); - controller_ = std::make_unique<MockProjectorController>(); - - overlay_view_ = - ChromeCaptureModeDelegate::Get()->CreateRecordingOverlayView(); - content::WebContents* web_contents = - GetOverlayView()->GetWebViewForTest()->GetWebContents(); - EXPECT_EQ(web_contents->GetWebUI()->GetHandlersForTesting()->size(), 1u); - // Wait for the annotator contents view to load and the WebUI listeners to - // register. - content::TestNavigationObserver navigation_observer(web_contents); - navigation_observer.Wait(); - } - - void TearDownOnMainThread() override { - overlay_view_.reset(); - controller_.reset(); - scoped_resetter_.reset(); - InProcessBrowserTest::TearDownOnMainThread(); - } - - RecordingOverlayViewImpl* GetOverlayView() { - return static_cast<RecordingOverlayViewImpl*>(overlay_view_.get()); - } - - MockProjectorController* GetController() { return controller_.get(); } - - private: - base::test::ScopedFeatureList scoped_feature_list_; - std::unique_ptr<ProjectorController::ScopedInstanceResetterForTest> - scoped_resetter_; - std::unique_ptr<MockProjectorController> controller_; - std::unique_ptr<RecordingOverlayView> overlay_view_; -}; - -IN_PROC_BROWSER_TEST_F(ProjectorAnnotatorControllerTest, SetTool) { - AnnotatorTool expected_tool; - expected_tool.color = SK_ColorBLACK; - expected_tool.size = 5; - expected_tool.type = AnnotatorToolType::kPen; - - base::RunLoop run_loop; - base::RepeatingClosure quit_closure = run_loop.QuitClosure(); - EXPECT_CALL(*GetController(), OnToolSet(expected_tool)) - .WillOnce([&quit_closure] { quit_closure.Run(); }); - ProjectorAnnotatorController::Get()->SetTool(expected_tool); - run_loop.Run(); -} - -// This edge case can happen if the user navigates to -// chrome://projector/annotator/annotator_embedder.html while doing a screen -// capture with annotator tools enabled. -IN_PROC_BROWSER_TEST_F(ProjectorAnnotatorControllerTest, TwoAnnotators) { - AnnotatorTool expected_tool; - expected_tool.color = SK_ColorGREEN; - expected_tool.size = 6; - expected_tool.type = AnnotatorToolType::kMarker; - - ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), - GURL(kChromeUITrustedAnnotatorUrl))); - content::WebContents* tab = - browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_TRUE(tab); - - // We enforce only one AnnotatorMessageHandler at a time. The second annotator - // does not have a message handler. - EXPECT_TRUE(tab->GetWebUI()->GetHandlersForTesting()->empty()); - - base::RunLoop run_loop; - base::RepeatingClosure quit_closure = run_loop.QuitClosure(); - EXPECT_CALL(*GetController(), OnToolSet(expected_tool)) - .WillOnce([&quit_closure] { quit_closure.Run(); }); - ProjectorAnnotatorController::Get()->SetTool(expected_tool); - run_loop.Run(); -} - -} // namespace ash
diff --git a/chrome/browser/ui/ash/projector/projector_app_client_impl.cc b/chrome/browser/ui/ash/projector/projector_app_client_impl.cc index 2337135..7126836 100644 --- a/chrome/browser/ui/ash/projector/projector_app_client_impl.cc +++ b/chrome/browser/ui/ash/projector/projector_app_client_impl.cc
@@ -4,32 +4,61 @@ #include "chrome/browser/ui/ash/projector/projector_app_client_impl.h" +#include <string> + +#include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" +#include "ash/public/cpp/projector/projector_controller.h" +#include "base/bind.h" #include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/signin/public/identity_manager/identity_manager.h" +#include "components/soda/constants.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" +namespace { + +constexpr char kUsEnglishLocale[] = "en-US"; + +inline const std::string& GetLocale() { + return g_browser_process->GetApplicationLocale(); +} + +inline const speech::LanguageCode GetLocaleLanguageCode() { + return speech::GetLanguageCode(GetLocale()); +} + +} // namespace + // static void ProjectorAppClientImpl::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { registry->RegisterBooleanPref( ash::prefs::kProjectorCreationFlowEnabled, false, user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF); + registry->RegisterStringPref( + ash::prefs::kProjectorCreationFlowLanguage, kUsEnglishLocale, + user_prefs::PrefRegistrySyncable::SYNCABLE_OS_PREF); } -ProjectorAppClientImpl::ProjectorAppClientImpl() = default; +ProjectorAppClientImpl::ProjectorAppClientImpl() { + if (!base::FeatureList::IsEnabled( + ash::features::kOnDeviceSpeechRecognition)) { + return; + } + + soda_installation_controller_ = + std::make_unique<ProjectorSodaInstallationController>( + this, ash::ProjectorController::Get()); +} + ProjectorAppClientImpl::~ProjectorAppClientImpl() = default; -signin::IdentityManager* ProjectorAppClientImpl::GetIdentityManager() { - Profile* profile = ProfileManager::GetPrimaryUserProfile(); - DCHECK(chromeos::ProfileHelper::IsPrimaryProfile(profile)); - return IdentityManagerFactory::GetForProfile(profile); -} - void ProjectorAppClientImpl::AddObserver(Observer* observer) { observers_.AddObserver(observer); } @@ -38,6 +67,12 @@ observers_.RemoveObserver(observer); } +signin::IdentityManager* ProjectorAppClientImpl::GetIdentityManager() { + Profile* profile = ProfileManager::GetPrimaryUserProfile(); + DCHECK(chromeos::ProfileHelper::IsPrimaryProfile(profile)); + return IdentityManagerFactory::GetForProfile(profile); +} + network::mojom::URLLoaderFactory* ProjectorAppClientImpl::GetUrlLoaderFactory() { Profile* profile = ProfileManager::GetPrimaryUserProfile(); @@ -65,3 +100,36 @@ for (auto& observer : observers_) observer.OnScreencastsPendingStatusChanged(pending_screencast); } + +bool ProjectorAppClientImpl::ShouldDownloadSoda() { + return soda_installation_controller_ && + soda_installation_controller_->ShouldDownloadSoda( + GetLocaleLanguageCode()); +} + +void ProjectorAppClientImpl::InstallSoda() { + DCHECK(soda_installation_controller_); + + soda_installation_controller_->InstallSoda(GetLocale()); +} + +void ProjectorAppClientImpl::OnSodaInstallProgress(int combined_progress) { + for (auto& observer : observers_) + observer.OnSodaProgress(combined_progress); +} + +void ProjectorAppClientImpl::OnSodaInstallError() { + for (auto& observer : observers_) + observer.OnSodaError(); +} + +void ProjectorAppClientImpl::OnSodaInstalled() { + for (auto& observer : observers_) + observer.OnSodaInstalled(); +} + +bool ProjectorAppClientImpl::IsSpeechRecognitionAvailable() { + return soda_installation_controller_ && + soda_installation_controller_->IsSodaAvailable( + GetLocaleLanguageCode()); +}
diff --git a/chrome/browser/ui/ash/projector/projector_app_client_impl.h b/chrome/browser/ui/ash/projector/projector_app_client_impl.h index 6de89adb..53b0ef9f 100644 --- a/chrome/browser/ui/ash/projector/projector_app_client_impl.h +++ b/chrome/browser/ui/ash/projector/projector_app_client_impl.h
@@ -5,10 +5,13 @@ #ifndef CHROME_BROWSER_UI_ASH_PROJECTOR_PROJECTOR_APP_CLIENT_IMPL_H_ #define CHROME_BROWSER_UI_ASH_PROJECTOR_PROJECTOR_APP_CLIENT_IMPL_H_ +#include <memory> #include <set> #include "ash/webui/projector_app/projector_app_client.h" +#include "base/memory/weak_ptr.h" #include "base/observer_list.h" +#include "chrome/browser/ui/ash/projector/projector_soda_installation_controller.h" namespace network { namespace mojom { @@ -38,6 +41,12 @@ void OnNewScreencastPreconditionChanged(bool can_start) override; const std::set<ash::PendingScreencast>& GetPendingScreencasts() const override; + bool ShouldDownloadSoda() override; + bool IsSpeechRecognitionAvailable() override; + void InstallSoda() override; + void OnSodaInstallProgress(int combined_progress) override; + void OnSodaInstallError() override; + void OnSodaInstalled() override; private: void NotifyScreencastsPendingStatusChanged( @@ -47,6 +56,9 @@ // TODO(b/201468756): Create a PendingScreencastManager to own this set. std::set<ash::PendingScreencast> pending_screencasts_; + + std::unique_ptr<ProjectorSodaInstallationController> + soda_installation_controller_; }; #endif // CHROME_BROWSER_UI_ASH_PROJECTOR_PROJECTOR_APP_CLIENT_IMPL_H_
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl.cc b/chrome/browser/ui/ash/projector/projector_client_impl.cc index 1912646..3624068 100644 --- a/chrome/browser/ui/ash/projector/projector_client_impl.cc +++ b/chrome/browser/ui/ash/projector/projector_client_impl.cc
@@ -10,6 +10,7 @@ #include "ash/webui/projector_app/projector_app_client.h" #include "ash/webui/projector_app/public/cpp/projector_app_constants.h" #include "chrome/browser/ash/drive/drive_integration_service.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_prefs.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" @@ -30,8 +31,10 @@ #include "url/gurl.h" namespace { -// On-device speech recognition is only available in US English. -const char kEnglishLanguageCode[] = "en-US"; + +inline const std::string& GetLocale() { + return g_browser_process->GetApplicationLocale(); +} bool ShouldUseWebSpeechFallback() { return !base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption); @@ -51,19 +54,6 @@ ProjectorClientImpl::ProjectorClientImpl(ash::ProjectorController* controller) : controller_(controller) { controller_->SetClient(this); - if (ash::ProjectorController::AreExtendedProjectorFeaturesDisabled()) - return; - - bool recognition_available = - OnDeviceSpeechRecognizer::IsOnDeviceSpeechRecognizerAvailable( - kEnglishLanguageCode) || - ShouldUseWebSpeechFallback(); - - controller_->OnSpeechRecognitionAvailable(recognition_available); - if (!recognition_available && - base::FeatureList::IsEnabled(ash::features::kOnDeviceSpeechRecognition)) { - speech::SodaInstaller::GetInstance()->AddObserver(this); - } } ProjectorClientImpl::ProjectorClientImpl() @@ -76,13 +66,14 @@ // has been informed that recognition is available. // TODO(crbug.com/1165437): Dynamically determine language code. DCHECK(OnDeviceSpeechRecognizer::IsOnDeviceSpeechRecognizerAvailable( - kEnglishLanguageCode) || + GetLocale()) || ShouldUseWebSpeechFallback()); + DCHECK_EQ(speech_recognizer_.get(), nullptr); recognizer_status_ = SPEECH_RECOGNIZER_OFF; speech_recognizer_ = std::make_unique<OnDeviceSpeechRecognizer>( weak_ptr_factory_.GetWeakPtr(), ProfileManager::GetPrimaryUserProfile(), - kEnglishLanguageCode, /*recognition_mode_ime=*/false, + GetLocale(), /*recognition_mode_ime=*/false, /*enable_formatting=*/true); } @@ -130,13 +121,6 @@ recognizer_status_ = new_state; } -void ProjectorClientImpl::OnSodaInstalled() { - // OnDevice has been installed! Notify ProjectorController in ash. - DCHECK(OnDeviceSpeechRecognizer::IsOnDeviceSpeechRecognizerAvailable( - kEnglishLanguageCode)); - controller_->OnSpeechRecognitionAvailable(true); -} - bool ProjectorClientImpl::GetDriveFsMountPointPath( base::FilePath* result) const { if (!IsDriveFsMounted())
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl.h b/chrome/browser/ui/ash/projector/projector_client_impl.h index 1e737d4..a6e76a15 100644 --- a/chrome/browser/ui/ash/projector/projector_client_impl.h +++ b/chrome/browser/ui/ash/projector/projector_client_impl.h
@@ -25,8 +25,7 @@ // The client implementation for the ProjectorController in ash/. This client is // responsible for handling requests that have browser dependencies. class ProjectorClientImpl : public ash::ProjectorClient, - public SpeechRecognizerDelegate, - public speech::SodaInstaller::Observer { + public SpeechRecognizerDelegate { public: // RecordingOverlayViewImpl calls this function to initialize the annotator // tool. @@ -60,12 +59,6 @@ void OnSpeechRecognitionStateChanged( SpeechRecognizerStatus new_state) override; - // speech::SodaInstaller::Observer: - void OnSodaInstalled() override; - // We are not utilizing the following methods. Mark them as empty overrides. - void OnSodaError() override {} - void OnSodaProgress(int combined_progress) override {} - private: ash::ProjectorController* const controller_; SpeechRecognizerStatus recognizer_status_ =
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc b/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc index 1739864..1af572de6 100644 --- a/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc +++ b/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc
@@ -8,15 +8,11 @@ #include "ash/constants/ash_features.h" #include "ash/public/cpp/projector/projector_client.h" -#include "ash/public/cpp/projector/projector_controller.h" -#include "ash/public/cpp/test/mock_projector_controller.h" #include "ash/webui/projector_app/public/cpp/projector_app_constants.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/ash/drive/drive_integration_service.h" #include "chrome/browser/ash/drive/drivefs_test_support.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/speech/cros_speech_recognition_service_factory.h" -#include "chrome/browser/speech/fake_speech_recognition_service.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_applications/system_web_app_ui_utils.h" @@ -25,7 +21,6 @@ #include "chrome/browser/web_applications/web_app_provider.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/soda/soda_installer_impl_chromeos.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/web_contents.h" #include "content/public/common/page_type.h" @@ -36,13 +31,6 @@ namespace ash { -namespace { - -const char kFirstSpeechResult[] = "the brown fox"; -const char kSecondSpeechResult[] = "the brown fox jumped over the lazy dog"; - -} // namespace - class ProjectorClientTest : public InProcessBrowserTest { public: ProjectorClientTest() { @@ -64,52 +52,6 @@ &create_drive_integration_service_); } - void SetUpOnMainThread() override { - InProcessBrowserTest::SetUpOnMainThread(); - speech::SodaInstaller::GetInstance()->NotifySodaInstalledForTesting(); - - scoped_resetter_ = - std::make_unique<ProjectorController::ScopedInstanceResetterForTest>(); - controller_ = std::make_unique<ash::MockProjectorController>(); - client_ = std::make_unique<ProjectorClientImpl>(controller_.get()); - - CrosSpeechRecognitionServiceFactory::GetInstanceForTest() - ->SetTestingFactoryAndUse( - browser()->profile(), - base::BindRepeating( - &ProjectorClientTest::CreateTestSpeechRecognitionService, - base::Unretained(this))); - } - - void TearDownOnMainThread() override { - client_.reset(); - controller_.reset(); - scoped_resetter_.reset(); - } - - std::unique_ptr<KeyedService> CreateTestSpeechRecognitionService( - content::BrowserContext* context) { - std::unique_ptr<speech::FakeSpeechRecognitionService> fake_service = - std::make_unique<speech::FakeSpeechRecognitionService>(); - fake_service_ = fake_service.get(); - return std::move(fake_service); - } - - void SendSpeechResult(const char* result, bool is_final) { - EXPECT_TRUE(fake_service_->is_capturing_audio()); - base::RunLoop loop; - fake_service_->SendSpeechRecognitionResult( - media::SpeechRecognitionResult(result, is_final)); - loop.RunUntilIdle(); - } - - void SendTranscriptionError() { - EXPECT_TRUE(fake_service_->is_capturing_audio()); - base::RunLoop loop; - fake_service_->SendSpeechRecognitionError(); - loop.RunUntilIdle(); - } - // This test helper verifies that navigating to the |url| doesn't result in a // 404 error. void VerifyUrlValid(const char* url) { @@ -134,12 +76,9 @@ return integration_service; } - protected: - std::unique_ptr<ProjectorController::ScopedInstanceResetterForTest> - scoped_resetter_; - std::unique_ptr<ash::MockProjectorController> controller_; - std::unique_ptr<ProjectorClient> client_; - speech::FakeSpeechRecognitionService* fake_service_; + ProjectorClient* client() { return ProjectorClient::Get(); } + + private: drive::DriveIntegrationServiceFactory::FactoryCallback create_drive_integration_service_; std::unique_ptr<drive::DriveIntegrationServiceFactory::ScopedFactoryForTest> @@ -147,16 +86,15 @@ std::map<Profile*, std::unique_ptr<drive::FakeDriveFsHelper>> fake_drivefs_helpers_; - private: base::test::ScopedFeatureList scoped_feature_list_; }; IN_PROC_BROWSER_TEST_F(ProjectorClientTest, ShowOrCloseSelfieCamTest) { - EXPECT_FALSE(client_->IsSelfieCamVisible()); - client_->ShowSelfieCam(); - EXPECT_TRUE(client_->IsSelfieCamVisible()); - client_->CloseSelfieCam(); - EXPECT_FALSE(client_->IsSelfieCamVisible()); + EXPECT_FALSE(client()->IsSelfieCamVisible()); + client()->ShowSelfieCam(); + EXPECT_TRUE(client()->IsSelfieCamVisible()); + client()->CloseSelfieCam(); + EXPECT_FALSE(client()->IsSelfieCamVisible()); } // This test verifies that the selfie cam WebUI URL is valid. @@ -172,40 +110,13 @@ // TODO(crbug/1199396): Add a test to verify the selfie cam turns off when the // device goes inactive. -IN_PROC_BROWSER_TEST_F(ProjectorClientTest, SpeechRecognitionResults) { - client_->StartSpeechRecognition(); - fake_service_->WaitForRecognitionStarted(); - base::RunLoop().RunUntilIdle(); - - EXPECT_CALL(*controller_, OnTranscription(media::SpeechRecognitionResult( - kFirstSpeechResult, false))); - SendSpeechResult(kFirstSpeechResult, false /* is_final */); - base::RunLoop().RunUntilIdle(); - - EXPECT_CALL(*controller_, OnTranscription(media::SpeechRecognitionResult( - kSecondSpeechResult, false))); - SendSpeechResult(kSecondSpeechResult, false /* is_final */); - base::RunLoop().RunUntilIdle(); - - EXPECT_CALL(*controller_, OnTranscriptionError()); - SendTranscriptionError(); -} - -IN_PROC_BROWSER_TEST_F(ProjectorClientTest, GetDriveFsMountPointPath) { - ASSERT_TRUE(client_->IsDriveFsMounted()); - - base::FilePath mounted_path; - ASSERT_TRUE(client_->GetDriveFsMountPointPath(&mounted_path)); - ASSERT_EQ(browser()->profile()->GetPath().Append("drivefs"), mounted_path); -} - IN_PROC_BROWSER_TEST_F(ProjectorClientTest, OpenProjectorApp) { auto* profile = browser()->profile(); web_app::WebAppProvider::GetForTest(profile) ->system_web_app_manager() .InstallSystemAppsForTesting(); - client_->OpenProjectorApp(); + client()->OpenProjectorApp(); web_app::FlushSystemWebAppLaunchesForTesting(profile); // Verify that Projector App is opened. @@ -219,4 +130,12 @@ content::PAGE_TYPE_NORMAL); } +IN_PROC_BROWSER_TEST_F(ProjectorClientTest, GetDriveFsMountPointPath) { + ASSERT_TRUE(client()->IsDriveFsMounted()); + + base::FilePath mounted_path; + ASSERT_TRUE(client()->GetDriveFsMountPointPath(&mounted_path)); + ASSERT_EQ(browser()->profile()->GetPath().Append("drivefs"), mounted_path); +} + } // namespace ash
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl_unittest.cc b/chrome/browser/ui/ash/projector/projector_client_impl_unittest.cc new file mode 100644 index 0000000..cf67182 --- /dev/null +++ b/chrome/browser/ui/ash/projector/projector_client_impl_unittest.cc
@@ -0,0 +1,158 @@ +// 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/ui/ash/projector/projector_client_impl.h" + +#include <memory> + +#include "ash/constants/ash_features.h" +#include "ash/public/cpp/projector/projector_client.h" +#include "ash/public/cpp/projector/projector_controller.h" +#include "ash/public/cpp/test/mock_projector_controller.h" +#include "ash/webui/projector_app/public/cpp/projector_app_constants.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/speech/cros_speech_recognition_service_factory.h" +#include "chrome/browser/speech/fake_speech_recognition_service.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "chrome/test/base/ui_test_utils.h" +#include "components/prefs/pref_service.h" +#include "components/soda/soda_installer.h" +#include "components/soda/soda_installer_impl_chromeos.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace ash { + +namespace { + +const char kFirstSpeechResult[] = "the brown fox"; +const char kSecondSpeechResult[] = "the brown fox jumped over the lazy dog"; + +const char kEnglishLocale[] = "en-US"; + +inline const void SetLocale(const std::string& locale) { + g_browser_process->SetApplicationLocale(locale); +} + +// A mocked version instance of SodaInstaller for testing purposes. +class MockSodaInstaller : public speech::SodaInstaller { + public: + MockSodaInstaller() = default; + MockSodaInstaller(const MockSodaInstaller&) = delete; + MockSodaInstaller& operator=(const MockSodaInstaller&) = delete; + ~MockSodaInstaller() override = default; + + MOCK_CONST_METHOD0(GetSodaBinaryPath, base::FilePath()); + MOCK_CONST_METHOD1(GetLanguagePath, base::FilePath(const std::string&)); + MOCK_METHOD2(InstallLanguage, void(const std::string&, PrefService*)); + MOCK_CONST_METHOD0(GetAvailableLanguages, std::vector<std::string>()); + MOCK_METHOD1(InstallSoda, void(PrefService*)); + MOCK_METHOD1(UninstallSoda, void(PrefService*)); +}; + +} // namespace + +class ProjectorClientImplUnitTest : public testing::Test { + public: + ProjectorClientImplUnitTest() { + scoped_feature_list_.InitWithFeatures( + {features::kProjector, features::kOnDeviceSpeechRecognition}, {}); + } + + ProjectorClientImplUnitTest(const ProjectorClientImplUnitTest&) = delete; + ProjectorClientImplUnitTest& operator=(const ProjectorClientImplUnitTest&) = + delete; + ~ProjectorClientImplUnitTest() override = default; + + Profile* profile() { return testing_profile_; } + + MockProjectorController& projector_controller() { + return projector_controller_; + } + + ProjectorClient* client() { return projector_client_.get(); } + + // testing::Test: + void SetUp() override { + testing::Test::SetUp(); + ASSERT_TRUE(testing_profile_manager_.SetUp()); + testing_profile_ = ProfileManager::GetPrimaryUserProfile(); + ASSERT_TRUE(testing_profile_); + + CrosSpeechRecognitionServiceFactory::GetInstanceForTest() + ->SetTestingFactoryAndUse( + profile(), + base::BindRepeating(&ProjectorClientImplUnitTest:: + CreateTestSpeechRecognitionService, + base::Unretained(this))); + SetLocale(kEnglishLocale); + soda_installer_ = std::make_unique<MockSodaInstaller>(); + soda_installer_->NotifySodaInstalledForTesting(); + projector_client_ = + std::make_unique<ProjectorClientImpl>(&projector_controller_); + } + + std::unique_ptr<KeyedService> CreateTestSpeechRecognitionService( + content::BrowserContext* context) { + std::unique_ptr<speech::FakeSpeechRecognitionService> fake_service = + std::make_unique<speech::FakeSpeechRecognitionService>(); + fake_service_ = fake_service.get(); + return std::move(fake_service); + } + + void SendSpeechResult(const char* result, bool is_final) { + EXPECT_TRUE(fake_service_->is_capturing_audio()); + base::RunLoop loop; + fake_service_->SendSpeechRecognitionResult( + media::SpeechRecognitionResult(result, is_final)); + loop.RunUntilIdle(); + } + + void SendTranscriptionError() { + EXPECT_TRUE(fake_service_->is_capturing_audio()); + base::RunLoop loop; + fake_service_->SendSpeechRecognitionError(); + loop.RunUntilIdle(); + } + + protected: + content::BrowserTaskEnvironment task_environment_; + Profile* testing_profile_ = nullptr; + + TestingProfileManager testing_profile_manager_{ + TestingBrowserProcess::GetGlobal()}; + + MockProjectorController projector_controller_; + std::unique_ptr<ProjectorClient> projector_client_; + std::unique_ptr<MockSodaInstaller> soda_installer_; + speech::FakeSpeechRecognitionService* fake_service_; + + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(ProjectorClientImplUnitTest, SpeechRecognitionResults) { + client()->StartSpeechRecognition(); + fake_service_->WaitForRecognitionStarted(); + + EXPECT_CALL(projector_controller(), + OnTranscription( + media::SpeechRecognitionResult(kFirstSpeechResult, false))); + SendSpeechResult(kFirstSpeechResult, /*is_final=*/false); + + EXPECT_CALL(projector_controller(), + OnTranscription( + media::SpeechRecognitionResult(kSecondSpeechResult, false))); + SendSpeechResult(kSecondSpeechResult, /*is_final=*/false); + + EXPECT_CALL(projector_controller(), OnTranscriptionError()); + SendTranscriptionError(); +} + +} // namespace ash
diff --git a/chrome/browser/ui/ash/projector/projector_soda_installation_controller.cc b/chrome/browser/ui/ash/projector/projector_soda_installation_controller.cc new file mode 100644 index 0000000..dcb650e0 --- /dev/null +++ b/chrome/browser/ui/ash/projector/projector_soda_installation_controller.cc
@@ -0,0 +1,100 @@ +// 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/ui/ash/projector/projector_soda_installation_controller.h" + +#include "ash/constants/ash_features.h" +#include "ash/constants/ash_pref_names.h" +#include "ash/public/cpp/projector/projector_controller.h" +#include "ash/webui/projector_app/projector_app_client.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/speech/on_device_speech_recognizer.h" +#include "components/prefs/pref_service.h" +#include "components/soda/constants.h" +#include "components/soda/soda_installer.h" + +namespace { + +inline const std::string& GetLocale() { + return g_browser_process->GetApplicationLocale(); +} + +inline bool IsLanguageSupported(const speech::LanguageCode languageCode) { + auto* soda_installer = speech::SodaInstaller::GetInstance(); + for (auto const& language : soda_installer->GetAvailableLanguages()) { + if (speech::GetLanguageCode(language) == languageCode) + return true; + } + return false; +} + +} // namespace + +ProjectorSodaInstallationController::ProjectorSodaInstallationController( + ash::ProjectorAppClient* client, + ash::ProjectorController* projector_controller) + : app_client_(client), projector_controller_(projector_controller) { + speech::SodaInstaller::GetInstance()->AddObserver(this); + + bool recognition_available = + OnDeviceSpeechRecognizer::IsOnDeviceSpeechRecognizerAvailable( + GetLocale()); + + projector_controller_->OnSpeechRecognitionAvailable(recognition_available); +} + +ProjectorSodaInstallationController::~ProjectorSodaInstallationController() { + auto* installer = speech::SodaInstaller::GetInstance(); + if (installer) + installer->RemoveObserver(this); +} + +void ProjectorSodaInstallationController::InstallSoda( + const std::string& language) { + auto languageCode = speech::GetLanguageCode(language); + auto* soda_installer = speech::SodaInstaller::GetInstance(); + + // Initialization will trigger the installation of SODA and the language. + PrefService* pref_service = + ProfileManager::GetPrimaryUserProfile()->GetPrefs(); + pref_service->SetString(ash::prefs::kProjectorCreationFlowLanguage, language); + soda_installer->Init(pref_service, g_browser_process->local_state()); + + if (!soda_installer->IsSodaDownloading(languageCode)) + soda_installer->InstallLanguage(language, g_browser_process->local_state()); +} + +bool ProjectorSodaInstallationController::ShouldDownloadSoda( + speech::LanguageCode language_code) { + return base::FeatureList::IsEnabled( + ash::features::kOnDeviceSpeechRecognition) && + IsLanguageSupported(language_code) && !IsSodaAvailable(language_code); +} + +bool ProjectorSodaInstallationController::IsSodaAvailable( + speech::LanguageCode language_code) { + return speech::SodaInstaller::GetInstance()->IsSodaInstalled(language_code); +} + +void ProjectorSodaInstallationController::OnSodaInstalled() { + auto* soda_installer = speech::SodaInstaller::GetInstance(); + // Make sure that both SODA binary and the locale language are available + // before notifying that on device speech recognition is available. + if (!soda_installer->IsSodaInstalled(speech::GetLanguageCode(GetLocale()))) + return; + + projector_controller_->OnSpeechRecognitionAvailable(true); + app_client_->OnSodaInstalled(); +} + +void ProjectorSodaInstallationController::OnSodaError() { + app_client_->OnSodaInstallError(); +} + +void ProjectorSodaInstallationController::OnSodaProgress( + int combined_progress) { + app_client_->OnSodaInstallProgress(combined_progress); +}
diff --git a/chrome/browser/ui/ash/projector/projector_soda_installation_controller.h b/chrome/browser/ui/ash/projector/projector_soda_installation_controller.h new file mode 100644 index 0000000..4fe6a8b9 --- /dev/null +++ b/chrome/browser/ui/ash/projector/projector_soda_installation_controller.h
@@ -0,0 +1,63 @@ +// 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_UI_ASH_PROJECTOR_PROJECTOR_SODA_INSTALLATION_CONTROLLER_H_ +#define CHROME_BROWSER_UI_ASH_PROJECTOR_PROJECTOR_SODA_INSTALLATION_CONTROLLER_H_ + +#include <string> + +#include "components/soda/soda_installer.h" + +namespace ash { +class ProjectorAppClient; +class ProjectorController; +} // namespace ash + +namespace speech { +enum class LanguageCode; +} // namespace speech + +// Class owned by ProjectorAppClientImpl used to control the installation of +// SODA and the language pack requested by the user. +class ProjectorSodaInstallationController + : public speech::SodaInstaller::Observer { + public: + ProjectorSodaInstallationController(ash::ProjectorAppClient* app_client, + ash::ProjectorController* controller); + ProjectorSodaInstallationController( + const ProjectorSodaInstallationController&) = delete; + ProjectorSodaInstallationController& operator=( + const ProjectorSodaInstallationController&) = delete; + + ~ProjectorSodaInstallationController() override; + + // Installs the SODA binary and the the corresponding language if it is not + // present. + void InstallSoda(const std::string& language); + + // Checks if the device is eligible to install SODA and language pack for the + // `language` provided. + bool ShouldDownloadSoda(speech::LanguageCode language); + + // Checks if SODA binary and the requested `language` is downloaded and + // available on device. + bool IsSodaAvailable(speech::LanguageCode language); + + protected: + // speech::SodaInstaller::Observer: + void OnSodaInstalled() override; + void OnSodaLanguagePackInstalled( + speech::LanguageCode language_code) override {} + void OnSodaError() override; + void OnSodaLanguagePackError(speech::LanguageCode language_code) override {} + void OnSodaProgress(int combined_progress) override; + void OnSodaLanguagePackProgress(int language_progress, + speech::LanguageCode language_code) override { + } + + ash::ProjectorAppClient* const app_client_; + ash::ProjectorController* const projector_controller_; +}; + +#endif // CHROME_BROWSER_UI_ASH_PROJECTOR_PROJECTOR_SODA_INSTALLATION_CONTROLLER_H_
diff --git a/chrome/browser/ui/ash/projector/projector_soda_installation_controller_unittest.cc b/chrome/browser/ui/ash/projector/projector_soda_installation_controller_unittest.cc new file mode 100644 index 0000000..8822e69 --- /dev/null +++ b/chrome/browser/ui/ash/projector/projector_soda_installation_controller_unittest.cc
@@ -0,0 +1,172 @@ +// 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 "projector_soda_installation_controller.h" +#include "ash/constants/ash_features.h" +#include "ash/constants/ash_pref_names.h" +#include "ash/public/cpp/test/mock_projector_controller.h" +#include "ash/webui/projector_app/projector_app_client.h" +#include "ash/webui/projector_app/test/mock_app_client.h" +#include "base/bind.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile_manager.h" +#include "components/prefs/pref_service.h" +#include "components/soda/constants.h" +#include "components/soda/soda_installer.h" +#include "content/public/test/browser_task_environment.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +inline const std::string& GetLocale() { + return g_browser_process->GetApplicationLocale(); +} + +inline const void SetLocale(const std::string& locale) { + g_browser_process->SetApplicationLocale(locale); +} + +// A mocked version instance of SodaInstaller for testing purposes. +class MockSodaInstaller : public speech::SodaInstaller { + public: + MockSodaInstaller() = default; + MockSodaInstaller(const MockSodaInstaller&) = delete; + MockSodaInstaller& operator=(const MockSodaInstaller&) = delete; + ~MockSodaInstaller() override = default; + + MOCK_CONST_METHOD0(GetSodaBinaryPath, base::FilePath()); + MOCK_CONST_METHOD1(GetLanguagePath, base::FilePath(const std::string&)); + MOCK_METHOD2(InstallLanguage, void(const std::string&, PrefService*)); + MOCK_CONST_METHOD0(GetAvailableLanguages, std::vector<std::string>()); + MOCK_METHOD1(InstallSoda, void(PrefService*)); + MOCK_METHOD1(UninstallSoda, void(PrefService*)); +}; + +const char kEnglishLocale[] = "en-US"; + +} // namespace + +namespace ash { + +class ProjectorSodaInstallationControllerTest : public testing::Test { + public: + ProjectorSodaInstallationControllerTest() { + scoped_feature_list_.InitWithFeatures( + { + features::kOnDeviceSpeechRecognition, + features::kProjector, + }, + {}); + } + ProjectorSodaInstallationControllerTest( + const ProjectorSodaInstallationControllerTest&) = delete; + ProjectorSodaInstallationControllerTest& operator=( + const ProjectorSodaInstallationControllerTest&) = delete; + ~ProjectorSodaInstallationControllerTest() override = default; + + // InProcessBrowserTest: + void SetUp() override { + testing::Test::SetUp(); + ASSERT_TRUE(testing_profile_manager_.SetUp()); + testing_profile_ = ProfileManager::GetPrimaryUserProfile(); + + soda_installer_ = std::make_unique<MockSodaInstaller>(); + + mock_app_client_ = std::make_unique<MockAppClient>(); + + mock_projector_controller_ = std::make_unique<MockProjectorController>(); + + soda_installation_controller_ = + std::make_unique<ProjectorSodaInstallationController>( + mock_app_client_.get(), mock_projector_controller_.get()); + } + + void TearDown() override { + soda_installation_controller_.reset(); + mock_projector_controller_.reset(); + mock_app_client_.reset(); + soda_installer_.reset(); + } + + MockAppClient& app_client() { return *mock_app_client_; } + + ProjectorSodaInstallationController* soda_installation_controller() { + return soda_installation_controller_.get(); + } + + MockSodaInstaller* soda_installer() { return soda_installer_.get(); } + + private: + content::BrowserTaskEnvironment task_environment_; + Profile* testing_profile_ = nullptr; + + TestingProfileManager testing_profile_manager_{ + TestingBrowserProcess::GetGlobal()}; + + std::unique_ptr<MockSodaInstaller> soda_installer_; + std::unique_ptr<MockAppClient> mock_app_client_; + std::unique_ptr<MockProjectorController> mock_projector_controller_; + + std::unique_ptr<ProjectorSodaInstallationController> + soda_installation_controller_; + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(ProjectorSodaInstallationControllerTest, ShouldDownloadSoda) { + ON_CALL(*soda_installer(), GetAvailableLanguages) + .WillByDefault( + testing::Return(std::vector<std::string>({kEnglishLocale}))); + + EXPECT_TRUE(soda_installation_controller()->ShouldDownloadSoda( + speech::LanguageCode::kEnUs)); + + // Other languages other than English are not currently supported. + EXPECT_FALSE(soda_installation_controller()->ShouldDownloadSoda( + speech::LanguageCode::kFrFr)); +} + +TEST_F(ProjectorSodaInstallationControllerTest, IsSpeechRecognitionAvailable) { + SetLocale(kEnglishLocale); + EXPECT_FALSE(soda_installation_controller()->IsSodaAvailable( + speech::LanguageCode::kEnUs)); + + EXPECT_CALL(app_client(), OnSodaInstalled()).Times(1); + speech::SodaInstaller::GetInstance()->NotifySodaInstalledForTesting(); + EXPECT_TRUE(soda_installation_controller()->IsSodaAvailable( + speech::LanguageCode::kEnUs)); + EXPECT_FALSE(soda_installation_controller()->IsSodaAvailable( + speech::LanguageCode::kFrFr)); +} + +TEST_F(ProjectorSodaInstallationControllerTest, InstallSoda) { + SetLocale(kEnglishLocale); + ProfileManager::GetPrimaryUserProfile()->GetPrefs()->SetBoolean( + prefs::kProjectorCreationFlowEnabled, true); + + // Test case where SODA is already installed. + soda_installation_controller()->InstallSoda(kEnglishLocale); + + EXPECT_CALL(app_client(), OnSodaInstalled()).Times(1); + speech::SodaInstaller::GetInstance()->NotifySodaInstalledForTesting(); +} + +TEST_F(ProjectorSodaInstallationControllerTest, OnSodaInstallProgress) { + SetLocale(kEnglishLocale); + EXPECT_CALL(app_client(), OnSodaInstallProgress(50)).Times(1); + speech::SodaInstaller::GetInstance()->NotifySodaDownloadProgressForTesting( + 50); +} + +TEST_F(ProjectorSodaInstallationControllerTest, OnSodaInstallError) { + SetLocale(kEnglishLocale); + EXPECT_CALL(app_client(), OnSodaInstallError()).Times(1); + speech::SodaInstaller::GetInstance()->NotifySodaErrorForTesting(); +} + +} // namespace ash
diff --git a/chrome/browser/ui/ash/shelf/browser_app_shelf_item_controller.cc b/chrome/browser/ui/ash/shelf/browser_app_shelf_item_controller.cc index 71f0f06..b8b5f15b 100644 --- a/chrome/browser/ui/ash/shelf/browser_app_shelf_item_controller.cc +++ b/chrome/browser/ui/ash/shelf/browser_app_shelf_item_controller.cc
@@ -14,6 +14,9 @@ #include "chrome/browser/ash/crosapi/browser_util.h" #include "chrome/browser/ui/ash/shelf/chrome_shelf_controller.h" #include "chrome/browser/ui/ash/shelf/shelf_context_menu.h" +#include "chrome/common/chrome_features.h" +#include "components/services/app_service/public/cpp/app_types.h" +#include "components/services/app_service/public/mojom/types.mojom.h" #include "extensions/common/constants.h" #include "ui/aura/client/aura_constants.h" @@ -201,17 +204,31 @@ void BrowserAppShelfItemController::LoadAppMenuIcon() { const std::string& app_id = shelf_id().app_id; auto* proxy = apps::AppServiceProxyFactory::GetForProfile(profile_); - icon_loader_releaser_ = proxy->LoadIcon( - proxy->AppRegistryCache().GetAppType(app_id), app_id, - apps::mojom::IconType::kStandard, - // matches favicon size - /* size_hint_in_dip= */ extension_misc::EXTENSION_ICON_BITTY, - /* allow_placeholder_icon= */ false, - base::BindOnce(&BrowserAppShelfItemController::DidLoadAppMenuIcon, - weak_ptr_factory_.GetWeakPtr())); + auto app_type = proxy->AppRegistryCache().GetAppType(app_id); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + icon_loader_releaser_ = proxy->LoadIcon( + apps::ConvertMojomAppTypToAppType(app_type), app_id, + apps::IconType::kStandard, + // matches favicon size + /* size_hint_in_dip= */ extension_misc::EXTENSION_ICON_BITTY, + /* allow_placeholder_icon= */ false, + base::BindOnce(&BrowserAppShelfItemController::OnLoadAppMenuIcon, + weak_ptr_factory_.GetWeakPtr())); + } else { + icon_loader_releaser_ = proxy->LoadIcon( + app_type, app_id, apps::mojom::IconType::kStandard, + // matches favicon size + /* size_hint_in_dip= */ extension_misc::EXTENSION_ICON_BITTY, + /* allow_placeholder_icon= */ false, + apps::MojomIconValueToIconValueCallback( + base::BindOnce(&BrowserAppShelfItemController::OnLoadAppMenuIcon, + weak_ptr_factory_.GetWeakPtr()))); + } } -void BrowserAppShelfItemController::DidLoadAppMenuIcon( - apps::mojom::IconValuePtr icon_value) { - menu_icon_ = icon_value->uncompressed; +void BrowserAppShelfItemController::OnLoadAppMenuIcon( + apps::IconValuePtr icon_value) { + if (icon_value && icon_value->icon_type == apps::IconType::kStandard) { + menu_icon_ = icon_value->uncompressed; + } }
diff --git a/chrome/browser/ui/ash/shelf/browser_app_shelf_item_controller.h b/chrome/browser/ui/ash/shelf/browser_app_shelf_item_controller.h index 707cde49..4574027 100644 --- a/chrome/browser/ui/ash/shelf/browser_app_shelf_item_controller.h +++ b/chrome/browser/ui/ash/shelf/browser_app_shelf_item_controller.h
@@ -17,7 +17,7 @@ #include "chrome/browser/apps/app_service/browser_app_instance_observer.h" #include "chrome/browser/apps/app_service/browser_app_instance_registry.h" #include "components/services/app_service/public/cpp/icon_loader.h" -#include "components/services/app_service/public/mojom/types.mojom.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "ui/gfx/image/image_skia.h" namespace apps { @@ -72,7 +72,7 @@ int GetInstanceCommand(const base::UnguessableToken& id); void LoadAppMenuIcon(); - void DidLoadAppMenuIcon(apps::mojom::IconValuePtr icon_value); + void OnLoadAppMenuIcon(apps::IconValuePtr icon_value); Profile* profile_; apps::BrowserAppInstanceRegistry& registry_;
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc index ff6af9e..e8ca80a 100644 --- a/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc +++ b/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc
@@ -64,14 +64,6 @@ bool skip_pinned_apps_from_sync_for_test = false; -bool IsLegacyCameraAppId(const std::string& app_id) { - return app_id == - "ngmkobaiicipbagcngcmilfkhejlnfci" || // Migration Camera App. - app_id == "goamfaniemdfcajgcmmflhchgkmbngka" || // Google Camera App. - app_id == "obfofkigjfamlldmipdegnjlcpincibc" || // Legacy Camera App. - app_id == "iniodglblcgmngkgdipeiclkdjjpnlbn"; // Internal Camera App. -} - bool IsAppIdArcPackage(const std::string& app_id) { return app_id.find('.') != app_id.npos; }
diff --git a/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.cc b/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.cc index 6548819..0342d771 100644 --- a/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.cc +++ b/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.cc
@@ -43,7 +43,7 @@ apps::AppType::kStandaloneBrowserExtension, shelf_id.app_id, icon_key, icon_type, kIconSize, kAllowPlaceholderIcon, base::BindOnce( - &StandaloneBrowserExtensionAppShelfItemController::DidLoadIcon, + &StandaloneBrowserExtensionAppShelfItemController::OnLoadIcon, weak_factory_.GetWeakPtr())); } else { apps::mojom::IconKeyPtr icon_key = apps::mojom::IconKey::New(); @@ -51,9 +51,9 @@ icon_loader_releaser_ = proxy->LoadIconFromIconKey( apps::mojom::AppType::kStandaloneBrowserExtension, shelf_id.app_id, std::move(icon_key), icon_type, kIconSize, kAllowPlaceholderIcon, - base::BindOnce( - &StandaloneBrowserExtensionAppShelfItemController::DidLoadMojomIcon, - weak_factory_.GetWeakPtr())); + apps::MojomIconValueToIconValueCallback(base::BindOnce( + &StandaloneBrowserExtensionAppShelfItemController::OnLoadIcon, + weak_factory_.GetWeakPtr()))); } context_menu_ = std::make_unique<StandaloneBrowserExtensionAppContextMenu>( @@ -223,8 +223,11 @@ return windows_.size(); } -void StandaloneBrowserExtensionAppShelfItemController::DidLoadIcon( +void StandaloneBrowserExtensionAppShelfItemController::OnLoadIcon( apps::IconValuePtr icon_value) { + if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) + return; + icon_ = icon_value->uncompressed; if (ItemAddedToShelf()) { @@ -236,11 +239,6 @@ } } -void StandaloneBrowserExtensionAppShelfItemController::DidLoadMojomIcon( - apps::mojom::IconValuePtr icon_value) { - DidLoadIcon(apps::ConvertMojomIconValueToIconValue(std::move(icon_value))); -} - void StandaloneBrowserExtensionAppShelfItemController::OnWindowDestroying( aura::Window* window) { size_t erased = base::Erase(windows_, window);
diff --git a/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.h b/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.h index b9b288a..0f2fc6b 100644 --- a/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.h +++ b/chrome/browser/ui/ash/shelf/standalone_browser_extension_app_shelf_item_controller.h
@@ -83,11 +83,7 @@ using ShelfItem = ash::ShelfItem; // Called by AppServiceProxy once an icon has been loaded. - void DidLoadIcon(apps::IconValuePtr icon_value); - - // Called by AppServiceProxy once an icon has been loaded. - // TODO(crbug.com/1251501): Remove this mojom callback. - void DidLoadMojomIcon(apps::mojom::IconValuePtr icon_value); + void OnLoadIcon(apps::IconValuePtr icon_value); // aura::WindowObserver overrides: void OnWindowDestroying(aura::Window* window) override;
diff --git a/chrome/browser/ui/extensions/hosted_app_browser_controller.cc b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc index a3ee7bc..732592ce 100644 --- a/chrome/browser/ui/extensions/hosted_app_browser_controller.cc +++ b/chrome/browser/ui/extensions/hosted_app_browser_controller.cc
@@ -22,6 +22,8 @@ #include "chrome/common/extensions/api/url_handlers/url_handlers_parser.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "components/security_state/core/security_state.h" +#include "components/services/app_service/public/cpp/app_types.h" +#include "components/services/app_service/public/mojom/types.mojom-forward.h" #include "components/url_formatter/url_formatter.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_entry.h" @@ -231,17 +233,26 @@ void HostedAppBrowserController::LoadAppIcon( bool allow_placeholder_icon) const { - apps::AppServiceProxyFactory::GetForProfile(browser()->profile()) - ->LoadIcon(apps::mojom::AppType::kExtension, GetExtension()->id(), - apps::mojom::IconType::kStandard, - extension_misc::EXTENSION_ICON_SMALL, allow_placeholder_icon, - base::BindOnce(&HostedAppBrowserController::OnLoadIcon, - weak_ptr_factory_.GetWeakPtr())); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + apps::AppServiceProxyFactory::GetForProfile(browser()->profile()) + ->LoadIcon(apps::AppType::kExtension, GetExtension()->id(), + apps::IconType::kStandard, + extension_misc::EXTENSION_ICON_SMALL, allow_placeholder_icon, + base::BindOnce(&HostedAppBrowserController::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr())); + } else { + apps::AppServiceProxyFactory::GetForProfile(browser()->profile()) + ->LoadIcon(apps::mojom::AppType::kExtension, GetExtension()->id(), + apps::mojom::IconType::kStandard, + extension_misc::EXTENSION_ICON_SMALL, allow_placeholder_icon, + apps::MojomIconValueToIconValueCallback( + base::BindOnce(&HostedAppBrowserController::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr()))); + } } -void HostedAppBrowserController::OnLoadIcon( - apps::mojom::IconValuePtr icon_value) { - if (icon_value->icon_type != apps::mojom::IconType::kStandard) +void HostedAppBrowserController::OnLoadIcon(apps::IconValuePtr icon_value) { + if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) return; app_icon_ = icon_value->uncompressed;
diff --git a/chrome/browser/ui/extensions/hosted_app_browser_controller.h b/chrome/browser/ui/extensions/hosted_app_browser_controller.h index d61075e..58ca5611 100644 --- a/chrome/browser/ui/extensions/hosted_app_browser_controller.h +++ b/chrome/browser/ui/extensions/hosted_app_browser_controller.h
@@ -11,7 +11,7 @@ #include "chrome/browser/extensions/extension_uninstall_dialog.h" #include "chrome/browser/ui/tabs/tab_strip_model_observer.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" -#include "components/services/app_service/public/mojom/types.mojom-forward.h" +#include "components/services/app_service/public/cpp/icon_types.h" class Browser; @@ -67,7 +67,7 @@ // Helper function to call AppServiceProxy to load icon. void LoadAppIcon(bool allow_placeholder_icon) const; // Invoked when the icon is loaded. - void OnLoadIcon(apps::mojom::IconValuePtr icon_value); + void OnLoadIcon(apps::IconValuePtr icon_value); gfx::ImageSkia app_icon_;
diff --git a/chrome/browser/ui/intent_picker_tab_helper.cc b/chrome/browser/ui/intent_picker_tab_helper.cc index 6b7f14e..5602712 100644 --- a/chrome/browser/ui/intent_picker_tab_helper.cc +++ b/chrome/browser/ui/intent_picker_tab_helper.cc
@@ -15,6 +15,8 @@ #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/common/chrome_features.h" +#include "components/services/app_service/public/cpp/app_types.h" #include "content/public/browser/navigation_handle.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/models/image_model.h" @@ -93,9 +95,12 @@ std::vector<apps::IntentPickerAppInfo> apps, IntentPickerIconLoaderCallback callback, size_t index, - apps::mojom::IconValuePtr icon_value) { - apps[index].icon_model = - ui::ImageModel::FromImage(gfx::Image(icon_value->uncompressed)); + apps::IconValuePtr icon_value) { + gfx::Image image = + (icon_value && icon_value->icon_type == apps::IconType::kStandard) + ? gfx::Image(icon_value->uncompressed) + : gfx::Image(); + apps[index].icon_model = ui::ImageModel::FromImage(image); if (index == apps.size() - 1) std::move(callback).Run(std::move(apps)); @@ -119,12 +124,21 @@ Profile::FromBrowserContext(web_contents()->GetBrowserContext()); constexpr bool allow_placeholder_icon = false; - apps::AppServiceProxyFactory::GetForProfile(profile)->LoadIcon( - app_type, app_id, apps::mojom::IconType::kStandard, gfx::kFaviconSize, - allow_placeholder_icon, - base::BindOnce(&IntentPickerTabHelper::OnAppIconLoaded, - weak_factory_.GetWeakPtr(), std::move(apps), - std::move(callback), index)); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + apps::AppServiceProxyFactory::GetForProfile(profile)->LoadIcon( + apps::ConvertMojomAppTypToAppType(app_type), app_id, + apps::IconType::kStandard, gfx::kFaviconSize, allow_placeholder_icon, + base::BindOnce(&IntentPickerTabHelper::OnAppIconLoaded, + weak_factory_.GetWeakPtr(), std::move(apps), + std::move(callback), index)); + } else { + apps::AppServiceProxyFactory::GetForProfile(profile)->LoadIcon( + app_type, app_id, apps::mojom::IconType::kStandard, gfx::kFaviconSize, + allow_placeholder_icon, + apps::MojomIconValueToIconValueCallback(base::BindOnce( + &IntentPickerTabHelper::OnAppIconLoaded, weak_factory_.GetWeakPtr(), + std::move(apps), std::move(callback), index))); + } } void IntentPickerTabHelper::DidFinishNavigation(
diff --git a/chrome/browser/ui/intent_picker_tab_helper.h b/chrome/browser/ui/intent_picker_tab_helper.h index 74c2e69..8f96032 100644 --- a/chrome/browser/ui/intent_picker_tab_helper.h +++ b/chrome/browser/ui/intent_picker_tab_helper.h
@@ -13,6 +13,7 @@ #include "chrome/browser/apps/intent_helper/apps_navigation_types.h" #include "chrome/browser/web_applications/app_registrar_observer.h" #include "chrome/browser/web_applications/web_app_registrar.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "components/services/app_service/public/mojom/types.mojom-forward.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" @@ -51,7 +52,7 @@ void OnAppIconLoaded(std::vector<apps::IntentPickerAppInfo> apps, IntentPickerIconLoaderCallback callback, size_t index, - apps::mojom::IconValuePtr icon_value); + apps::IconValuePtr icon_value); void LoadAppIcon(std::vector<apps::IntentPickerAppInfo> apps, IntentPickerIconLoaderCallback callback,
diff --git a/chrome/browser/ui/profile_picker.h b/chrome/browser/ui/profile_picker.h index 7a12d78..5afcb219 100644 --- a/chrome/browser/ui/profile_picker.h +++ b/chrome/browser/ui/profile_picker.h
@@ -95,6 +95,9 @@ // for the signed-in flow. static void CancelSignedInFlow(); + // Returns the path of the default profile used for rendering the picker. + static base::FilePath GetPickerProfilePath(); + // Shows a dialog where the user can auth the profile or see the // auth error message. If a dialog is already shown, this destroys the current // dialog and creates a new one.
diff --git a/chrome/browser/ui/side_search/side_search_side_contents_helper.cc b/chrome/browser/ui/side_search/side_search_side_contents_helper.cc index bda56d8..d495b29 100644 --- a/chrome/browser/ui/side_search/side_search_side_contents_helper.cc +++ b/chrome/browser/ui/side_search/side_search_side_contents_helper.cc
@@ -187,7 +187,8 @@ SideSearchSideContentsHelper::SideSearchSideContentsHelper( content::WebContents* web_contents) - : webui_load_timer_(web_contents, + : content::WebContentsUserData<SideSearchSideContentsHelper>(*web_contents), + webui_load_timer_(web_contents, "SideSearch.LoadDocumentTime", "SideSearch.LoadCompletedTime") { Observe(web_contents);
diff --git a/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc b/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc index f68ed8a..3e74d94 100644 --- a/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc +++ b/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc
@@ -118,7 +118,9 @@ SideSearchTabContentsHelper::SideSearchTabContentsHelper( content::WebContents* web_contents) - : content::WebContentsObserver(web_contents) {} + : content::WebContentsObserver(web_contents), + content::WebContentsUserData<SideSearchTabContentsHelper>(*web_contents) { +} SideSearchSideContentsHelper* SideSearchTabContentsHelper::GetSideContentsHelper() {
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index 83fa513e..f57ab97 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -333,7 +333,7 @@ prerender::NoStatePrefetchTabHelper::CreateForWebContents(web_contents); RecentlyAudibleHelper::CreateForWebContents(web_contents); #if defined(OS_ANDROID) - if (base::FeatureList::IsEnabled(features::kRequestDesktopSiteGlobal)) { + if (base::FeatureList::IsEnabled(features::kRequestDesktopSiteExceptions)) { RequestDesktopSiteWebContentsObserverAndroid::CreateForWebContents( web_contents); }
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc index b395945..9242d25 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h" #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h" #include "chrome/browser/ui/views/exclusive_access_bubble_views.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/extensions/extension_constants.h" #include "chromeos/ui/base/chromeos_ui_constants.h" #include "chromeos/ui/base/window_properties.h" @@ -33,6 +34,8 @@ #include "chromeos/ui/frame/immersive/immersive_fullscreen_controller.h" #include "components/app_restore/app_restore_utils.h" #include "components/app_restore/window_properties.h" +#include "components/services/app_service/public/cpp/app_types.h" +#include "components/services/app_service/public/mojom/types.mojom-forward.h" #include "components/session_manager/core/session_manager.h" #include "extensions/browser/app_window/app_delegate.h" #include "extensions/common/constants.h" @@ -597,13 +600,24 @@ proxy->AppRegistryCache().GetAppType(app_window()->extension_id()); if (app_type != apps::mojom::AppType::kUnknown) { - proxy->LoadIcon( - app_type, app_window()->extension_id(), - apps::mojom::IconType::kStandard, - app_window()->app_delegate()->PreferredIconSize(), - allow_placeholder_icon, - base::BindOnce(&ChromeNativeAppWindowViewsAuraAsh::OnLoadIcon, - weak_ptr_factory_.GetWeakPtr())); + if (base::FeatureList::IsEnabled( + features::kAppServiceLoadIconWithoutMojom)) { + proxy->LoadIcon( + apps::ConvertMojomAppTypToAppType(app_type), + app_window()->extension_id(), apps::IconType::kStandard, + app_window()->app_delegate()->PreferredIconSize(), + allow_placeholder_icon, + base::BindOnce(&ChromeNativeAppWindowViewsAuraAsh::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr())); + } else { + proxy->LoadIcon(app_type, app_window()->extension_id(), + apps::mojom::IconType::kStandard, + app_window()->app_delegate()->PreferredIconSize(), + allow_placeholder_icon, + apps::MojomIconValueToIconValueCallback(base::BindOnce( + &ChromeNativeAppWindowViewsAuraAsh::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr()))); + } } } @@ -613,8 +627,8 @@ } void ChromeNativeAppWindowViewsAuraAsh::OnLoadIcon( - apps::mojom::IconValuePtr icon_value) { - if (icon_value->icon_type != apps::mojom::IconType::kStandard) + apps::IconValuePtr icon_value) { + if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) return; app_icon_image_skia_ = icon_value->uncompressed;
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h index 5b89ccf..e6104cc 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h
@@ -17,7 +17,7 @@ #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h" #include "chrome/browser/ui/views/apps/chrome_native_app_window_views_aura.h" #include "chrome/browser/ui/views/exclusive_access_bubble_views_context.h" -#include "components/services/app_service/public/mojom/types.mojom-forward.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "ui/aura/window.h" #include "ui/aura/window_observer.h" #include "ui/base/accelerators/accelerator.h" @@ -188,7 +188,7 @@ // Helper function to call AppServiceProxy to load icon. void LoadAppIcon(bool allow_placeholder_icon); // Invoked when the icon is loaded. - void OnLoadIcon(apps::mojom::IconValuePtr icon_value); + void OnLoadIcon(apps::IconValuePtr icon_value); gfx::ImageSkia app_icon_image_skia_;
diff --git a/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_browsertest.cc b/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_browsertest.cc index f1d0aac..c3882fd 100644 --- a/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_browsertest.cc +++ b/chrome/browser/ui/views/autofill/payments/offer_notification_bubble_views_browsertest.cc
@@ -107,12 +107,13 @@ EXPECT_FALSE(GetOfferNotificationBubbleViews()); } -#if defined(OS_LINUX) +#if defined(OS_LINUX) || defined(OS_MAC) #define MAYBE_BubbleNotShowingOnDuplicateTab \ DISABLED_BubbleNotShowingOnDuplicateTab #else #define MAYBE_BubbleNotShowingOnDuplicateTab BubbleNotShowingOnDuplicateTab #endif +// [Sheriff] (crbug.com/1271059) failing on Mac. // TODO(crbug.com/1270516): Disabled due to flakiness with linux-wayland-rel. // Tests that the offer notification bubble will not be shown if bubble has been // shown for kAutofillBubbleSurviveNavigationTime (5 seconds) and the user has
diff --git a/chrome/browser/ui/views/extensions/extensions_side_panel_controller.cc b/chrome/browser/ui/views/extensions/extensions_side_panel_controller.cc index 66cbd48..4d57b97 100644 --- a/chrome/browser/ui/views/extensions/extensions_side_panel_controller.cc +++ b/chrome/browser/ui/views/extensions/extensions_side_panel_controller.cc
@@ -10,7 +10,7 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/side_panel.h" +#include "chrome/browser/ui/views/side_panel/side_panel.h" #include "chrome/browser/ui/views/toolbar/toolbar_button.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/extensions/extensions_side_panel_controller_browsertest.cc b/chrome/browser/ui/views/extensions/extensions_side_panel_controller_browsertest.cc index 39e9d773..91aec8d 100644 --- a/chrome/browser/ui/views/extensions/extensions_side_panel_controller_browsertest.cc +++ b/chrome/browser/ui/views/extensions/extensions_side_panel_controller_browsertest.cc
@@ -12,7 +12,7 @@ #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/extensions/extensions_side_panel_controller.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/side_panel.h" +#include "chrome/browser/ui/views/side_panel/side_panel.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/browser_test.h"
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index de346c2b..720c109 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -125,7 +125,7 @@ #include "chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.h" #include "chrome/browser/ui/views/sharing_hub/sharing_hub_bubble_view_impl.h" #include "chrome/browser/ui/views/sharing_hub/sharing_hub_icon_view.h" -#include "chrome/browser/ui/views/side_panel.h" +#include "chrome/browser/ui/views/side_panel/side_panel.h" #include "chrome/browser/ui/views/status_bubble_views.h" #include "chrome/browser/ui/views/tab_contents/chrome_web_contents_view_focus_helper.h" #include "chrome/browser/ui/views/tab_search_bubble_host.h"
diff --git a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.cc b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.cc index 3e9d1e7..875a4f7 100644 --- a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.cc +++ b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.cc
@@ -21,6 +21,7 @@ #include "components/media_router/common/media_sink.h" #include "components/media_router/common/mojom/media_route_provider_id.mojom-shared.h" #include "components/media_router/common/mojom/media_router.mojom.h" +#include "components/vector_icons/vector_icons.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "media/audio/audio_device_description.h" @@ -28,12 +29,17 @@ #include "services/media_session/public/mojom/media_session.mojom.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/gfx/paint_vector_icon.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/animation/ink_drop.h" #include "ui/views/border.h" #include "ui/views/bubble/bubble_border.h" +#include "ui/views/controls/button/image_button.h" +#include "ui/views/controls/highlight_path_generator.h" #include "ui/views/layout/box_layout.h" +#include "components/media_router/common/mojom/media_route_provider_id.mojom.h" + using media_router::MediaRouterMetrics; using media_router::mojom::MediaRouteProviderId; @@ -44,6 +50,11 @@ constexpr gfx::Size kExpandButtonStripSize{400, 30}; constexpr gfx::Insets kExpandButtonBorderInsets{4, 8}; +// Constant for DropdownButton +const int kDropdownButtonIconSize = 15; +const int kDropdownButtonBackgroundRadius = 10; +constexpr gfx::Insets kDropdownButtonBorderInsets{4}; + // The maximum number of audio devices to count when recording the // Media.GlobalMediaControls.NumberOfAvailableAudioDevices histogram. 30 was // chosen because it would be very unlikely to see a user with 30+ audio @@ -88,15 +99,33 @@ class ExpandDeviceSelectorLabel : public views::Label { public: - ExpandDeviceSelectorLabel(); + explicit ExpandDeviceSelectorLabel( + global_media_controls::GlobalMediaControlsEntryPoint entry_point); ~ExpandDeviceSelectorLabel() override = default; void OnColorsChanged(SkColor foreground_color, SkColor background_color); }; -ExpandDeviceSelectorLabel::ExpandDeviceSelectorLabel() - : views::Label( - l10n_util::GetStringUTF16(IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL)) { +class ExpandDeviceSelectorButton : public views::ToggleImageButton { + public: + explicit ExpandDeviceSelectorButton(PressedCallback callback, + SkColor background_color); + ~ExpandDeviceSelectorButton() override = default; + + void OnColorsChanged(SkColor foreground_color); +}; + +} // namespace + +ExpandDeviceSelectorLabel::ExpandDeviceSelectorLabel( + global_media_controls::GlobalMediaControlsEntryPoint entry_point) { + if (entry_point == + global_media_controls::GlobalMediaControlsEntryPoint::kPresentation) { + SetText(l10n_util::GetStringUTF16( + IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL_WITH_COLON)); + } else { + SetText(l10n_util::GetStringUTF16(IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL)); + } auto size = GetPreferredSize(); size.set_height(kExpandButtonStripSize.height()); size.set_width(size.width() + kExpandButtonBorderInsets.width()); @@ -109,52 +138,36 @@ SetBackgroundColor(background_color); } -class ExpandDeviceSelectorButton : public IconLabelBubbleView { - public: - explicit ExpandDeviceSelectorButton(IconLabelBubbleView::Delegate* delegate); - ~ExpandDeviceSelectorButton() override = default; +ExpandDeviceSelectorButton::ExpandDeviceSelectorButton(PressedCallback callback, + SkColor foreground_color) + : ToggleImageButton(callback) { + SetFocusBehavior(views::View::FocusBehavior::ALWAYS); + SetBorder(views::CreateEmptyBorder(kDropdownButtonBorderInsets)); - void OnColorsChanged(); - - private: - bool ShouldShowSeparator() const override { return false; } - IconLabelBubbleView::Delegate* delegate_; -}; - -} // anonymous namespace - -ExpandDeviceSelectorButton::ExpandDeviceSelectorButton( - IconLabelBubbleView::Delegate* delegate) - : IconLabelBubbleView( - views::style::GetFont(views::style::TextContext::CONTEXT_BUTTON, - views::style::TextStyle::STYLE_PRIMARY), - delegate), - delegate_(delegate) { - SetLabel(l10n_util::GetStringUTF16( - IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_BUTTON_LABEL)); - views::InkDrop::Get(this)->SetMode(views::InkDropHost::InkDropMode::ON); SetHasInkDropActionOnClick(true); - SetFocusBehavior(FocusBehavior::ALWAYS); - views::InkDrop::Get(this)->GetInkDrop()->SetShowHighlightOnHover(true); + views::InstallFixedSizeCircleHighlightPathGenerator( + this, kDropdownButtonBackgroundRadius); + views::InkDrop::Get(this)->SetMode(views::InkDropHost::InkDropMode::ON); + views::InkDrop::Get(this)->SetBaseColor(foreground_color); - SetBorder(views::CreateRoundedRectBorder( - 1, kExpandButtonStripSize.height() / 2, gfx::Insets(), - delegate_->GetIconLabelBubbleSurroundingForegroundColor())); - - label()->SetBorder(views::CreateEmptyBorder(kExpandButtonBorderInsets)); - label()->SetHorizontalAlignment(gfx::ALIGN_CENTER); - - auto size = GetPreferredSize(); - size.set_height(kExpandButtonStripSize.height()); - size.set_width(size.width() + kExpandButtonBorderInsets.width()); - SetPreferredSize(size); + SetTooltipText( + l10n_util::GetStringUTF16(IDS_GLOBAL_MEDIA_CONTROLS_SHOW_DEVICE_LIST)); + SetToggledTooltipText( + l10n_util::GetStringUTF16(IDS_GLOBAL_MEDIA_CONTROLS_HIDE_DEVICE_LIST)); + OnColorsChanged(foreground_color); } -void ExpandDeviceSelectorButton::OnColorsChanged() { - UpdateLabelColors(); - SetBorder(views::CreateRoundedRectBorder( - 1, kExpandButtonStripSize.height() / 2, gfx::Insets(), - delegate_->GetIconLabelBubbleSurroundingForegroundColor())); +void ExpandDeviceSelectorButton::OnColorsChanged(SkColor foreground_color) { + // When the button is not toggled, the device list is collapsed and the arrow + // is pointing up. Otherwise, the device list is expanded and the arrow is + // pointing down. + SetImage(views::Button::STATE_NORMAL, + gfx::CreateVectorIcon(vector_icons::kCaretDownIcon, + kDropdownButtonIconSize, foreground_color)); + const auto caret_down_image = gfx::CreateVectorIcon( + vector_icons::kCaretUpIcon, kDropdownButtonIconSize, foreground_color); + SetToggledImage(views::Button::STATE_NORMAL, &caret_down_image); + views::InkDrop::Get(this)->SetBaseColor(foreground_color); } MediaItemUIDeviceSelectorView::MediaItemUIDeviceSelectorView( @@ -168,32 +181,7 @@ SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)); - expand_button_strip_ = AddChildView(std::make_unique<views::View>()); - auto* expand_button_strip_layout = - expand_button_strip_->SetLayoutManager(std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kHorizontal, - kExpandButtonStripInsets)); - expand_button_strip_layout->set_main_axis_alignment( - views::BoxLayout::MainAxisAlignment::kStart); - expand_button_strip_layout->set_cross_axis_alignment( - views::BoxLayout::CrossAxisAlignment::kCenter); - expand_button_strip_->SetPreferredSize(kExpandButtonStripSize); - - // Show a lebel if entry point is Cast SDK. Otherwise, show the expand button. - if (entry_point == - global_media_controls::GlobalMediaControlsEntryPoint::kPresentation) { - expand_label_ = expand_button_strip_->AddChildView( - std::make_unique<ExpandDeviceSelectorLabel>()); - } else { - expand_button_ = expand_button_strip_->AddChildView( - std::make_unique<ExpandDeviceSelectorButton>(this)); - expand_button_->SetCallback( - base::BindRepeating(&MediaItemUIDeviceSelectorView::ExpandButtonPressed, - base::Unretained(this))); - } - - if (!show_expand_button) - expand_button_strip_->SetVisible(false); + CreateExpandButtonStrip(show_expand_button); device_entry_views_container_ = AddChildView(std::make_unique<views::View>()); device_entry_views_container_->SetLayoutManager( @@ -309,11 +297,9 @@ it.second->OnColorsChanged(foreground_color_, background_color_); } - if (expand_label_) - expand_label_->OnColorsChanged(foreground_color_, background_color_); - if (expand_button_) - expand_button_->OnColorsChanged(); - + expand_label_->OnColorsChanged(foreground_color_, background_color_); + if (dropdown_button_) + dropdown_button_->OnColorsChanged(foreground_color_); SchedulePaint(); } @@ -328,32 +314,6 @@ return background_color_; } -views::Button* MediaItemUIDeviceSelectorView::GetExpandButtonForTesting() { - return expand_button_; -} - -std::string MediaItemUIDeviceSelectorView::GetEntryLabelForTesting( - views::View* entry_view) { - return GetDeviceEntryUI(entry_view)->device_name(); -} - -bool MediaItemUIDeviceSelectorView::GetEntryIsHighlightedForTesting( - views::View* entry_view) { - return GetDeviceEntryUI(entry_view) - ->GetEntryIsHighlightedForTesting(); // IN-TEST -} - -std::vector<media_router::CastDialogSinkButton*> -MediaItemUIDeviceSelectorView::GetCastSinkButtonsForTesting() { - std::vector<media_router::CastDialogSinkButton*> buttons; - for (auto* view : device_entry_views_container_->children()) { - if (GetDeviceEntryUI(view)->GetType() == DeviceEntryUIType::kCast) { - buttons.push_back(static_cast<media_router::CastDialogSinkButton*>(view)); - } - } - return buttons; -} - void MediaItemUIDeviceSelectorView::ShowDevices() { DCHECK(!is_expanded_); is_expanded_ = true; @@ -421,11 +381,45 @@ return device_entry_views_container_->children().size() > 2; } +void MediaItemUIDeviceSelectorView::CreateExpandButtonStrip( + bool show_expand_button) { + expand_button_strip_ = AddChildView(std::make_unique<views::View>()); + auto* expand_button_strip_layout = + expand_button_strip_->SetLayoutManager(std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, + kExpandButtonStripInsets)); + expand_button_strip_layout->set_main_axis_alignment( + views::BoxLayout::MainAxisAlignment::kStart); + expand_button_strip_layout->set_cross_axis_alignment( + views::BoxLayout::CrossAxisAlignment::kCenter); + expand_button_strip_->SetPreferredSize(kExpandButtonStripSize); + + expand_label_ = expand_button_strip_->AddChildView( + std::make_unique<ExpandDeviceSelectorLabel>(entry_point_)); + + // Show a button to show/hide the device list if dialog is opened from Cast + // SDK. + if (entry_point_ != + global_media_controls::GlobalMediaControlsEntryPoint::kPresentation) { + dropdown_button_ = expand_button_strip_->AddChildView( + std::make_unique<ExpandDeviceSelectorButton>( + base::BindRepeating( + &MediaItemUIDeviceSelectorView::ExpandButtonPressed, + base::Unretained(this)), + foreground_color_)); + } + + if (!show_expand_button) + expand_button_strip_->SetVisible(false); +} + void MediaItemUIDeviceSelectorView::ExpandButtonPressed() { - if (is_expanded_) + if (is_expanded_) { HideDevices(); - else + } else { ShowDevices(); + } + dropdown_button_->SetToggled(is_expanded_); if (media_item_ui_) media_item_ui_->OnDeviceSelectorViewSizeChanged(); @@ -518,6 +512,41 @@ observers_.AddObserver(observer); } +views::Label* +MediaItemUIDeviceSelectorView::GetExpandDeviceSelectorLabelForTesting() { + return expand_label_; +} + +views::Button* MediaItemUIDeviceSelectorView::GetDropdownButtonForTesting() { + return dropdown_button_; +} + +std::string MediaItemUIDeviceSelectorView::GetEntryLabelForTesting( + views::View* entry_view) { + return GetDeviceEntryUI(entry_view)->device_name(); +} + +bool MediaItemUIDeviceSelectorView::GetEntryIsHighlightedForTesting( + views::View* entry_view) { + return GetDeviceEntryUI(entry_view) + ->GetEntryIsHighlightedForTesting(); // IN-TEST +} + +bool MediaItemUIDeviceSelectorView::GetDeviceEntryViewVisibilityForTesting() { + return device_entry_views_container_->GetVisible(); +} + +std::vector<media_router::CastDialogSinkButton*> +MediaItemUIDeviceSelectorView::GetCastSinkButtonsForTesting() { + std::vector<media_router::CastDialogSinkButton*> buttons; + for (auto* view : device_entry_views_container_->children()) { + if (GetDeviceEntryUI(view)->GetType() == DeviceEntryUIType::kCast) { + buttons.push_back(static_cast<media_router::CastDialogSinkButton*>(view)); + } + } + return buttons; +} + void MediaItemUIDeviceSelectorView::StartCastSession( CastDeviceEntryView* entry) { if (!cast_controller_) @@ -550,6 +579,7 @@ } } } + void MediaItemUIDeviceSelectorView::DoStartCastSession( media_router::UIMediaSink sink) { DCHECK(base::Contains(sink.cast_modes,
diff --git a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.h b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.h index 60a69656..920a24f 100644 --- a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.h +++ b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view.h
@@ -21,6 +21,7 @@ namespace { class ExpandDeviceSelectorLabel; class ExpandDeviceSelectorButton; + const char kAudioDevicesCountHistogramName[] = "Media.GlobalMediaControls.NumberOfAvailableAudioDevices"; const char kCastDeviceCountHistogramName[] = @@ -38,6 +39,7 @@ namespace media_router { class CastDialogSinkButton; } + class MediaItemUIDeviceSelectorDelegate; class MediaItemUIDeviceSelectorObserver; @@ -86,9 +88,11 @@ void AddObserver(MediaItemUIDeviceSelectorObserver* observer); - views::Button* GetExpandButtonForTesting(); + views::Label* GetExpandDeviceSelectorLabelForTesting(); + views::Button* GetDropdownButtonForTesting(); std::string GetEntryLabelForTesting(views::View* entry_view); bool GetEntryIsHighlightedForTesting(views::View* entry_view); + bool GetDeviceEntryViewVisibilityForTesting(); std::vector<media_router::CastDialogSinkButton*> GetCastSinkButtonsForTesting(); @@ -96,12 +100,6 @@ FRIEND_TEST_ALL_PREFIXES(MediaItemUIDeviceSelectorViewTest, DeviceButtonsCreated); FRIEND_TEST_ALL_PREFIXES(MediaItemUIDeviceSelectorViewTest, - ExpandButtonOrLabelCreated); - FRIEND_TEST_ALL_PREFIXES(MediaItemUIDeviceSelectorViewTest, - ExpandButtonOpensEntryContainer); - FRIEND_TEST_ALL_PREFIXES(MediaItemUIDeviceSelectorViewTest, - DeviceEntryContainerVisibility); - FRIEND_TEST_ALL_PREFIXES(MediaItemUIDeviceSelectorViewTest, AudioDeviceButtonClickNotifiesContainer); FRIEND_TEST_ALL_PREFIXES(MediaItemUIDeviceSelectorViewTest, CurrentAudioDeviceHighlighted); @@ -120,6 +118,7 @@ void UpdateVisibility(); bool ShouldBeVisible() const; + void CreateExpandButtonStrip(bool show_expand_button); void ExpandButtonPressed(); void ShowDevices(); void HideDevices(); @@ -153,7 +152,7 @@ AudioDeviceEntryView* current_audio_device_entry_view_ = nullptr; views::View* expand_button_strip_ = nullptr; ExpandDeviceSelectorLabel* expand_label_ = nullptr; - ExpandDeviceSelectorButton* expand_button_ = nullptr; + ExpandDeviceSelectorButton* dropdown_button_ = nullptr; views::View* device_entry_views_container_ = nullptr; base::CallbackListSubscription audio_device_subscription_;
diff --git a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view_unittest.cc b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view_unittest.cc index 142e5dbb..f8c71f5f 100644 --- a/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view_unittest.cc +++ b/chrome/browser/ui/views/global_media_controls/media_item_ui_device_selector_view_unittest.cc
@@ -19,10 +19,12 @@ #include "chrome/browser/ui/global_media_controls/media_notification_device_provider.h" #include "chrome/browser/ui/global_media_controls/media_notification_service.h" #include "chrome/browser/ui/media_router/cast_dialog_model.h" +#include "chrome/grit/generated_resources.h" #include "chrome/test/views/chrome_views_test_base.h" #include "media/audio/audio_device_description.h" #include "media/base/media_switches.h" #include "testing/gmock/include/gmock/gmock.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/events/base_event_utils.h" #include "ui/gfx/color_palette.h" #include "ui/views/test/button_test_api.h" @@ -226,19 +228,22 @@ EXPECT_EQ(EntryLabelText(container_children.at(3)), kSinkFriendlyName); } -TEST_F(MediaItemUIDeviceSelectorViewTest, ExpandButtonOrLabelCreated) { +TEST_F(MediaItemUIDeviceSelectorViewTest, ExpandButtonAndLabelCreated) { NiceMock<MockMediaItemUIDeviceSelectorDelegate> delegate; AddAudioDevices(delegate); view_ = CreateDeviceSelectorView(&delegate); - EXPECT_TRUE(view_->expand_button_); - EXPECT_FALSE(view_->expand_label_); + EXPECT_EQ(view_->GetExpandDeviceSelectorLabelForTesting()->GetText(), + l10n_util::GetStringUTF16(IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL)); + EXPECT_TRUE(view_->GetDropdownButtonForTesting()); view_ = CreateDeviceSelectorView( &delegate, std::make_unique<NiceMock<MockCastDialogController>>(), "1", true, global_media_controls::GlobalMediaControlsEntryPoint::kPresentation); - EXPECT_TRUE(view_->expand_label_); - EXPECT_FALSE(view_->expand_button_); + EXPECT_EQ(view_->GetExpandDeviceSelectorLabelForTesting()->GetText(), + l10n_util::GetStringUTF16( + IDS_GLOBAL_MEDIA_CONTROLS_DEVICES_LABEL_WITH_COLON)); + EXPECT_FALSE(view_->GetDropdownButtonForTesting()); } TEST_F(MediaItemUIDeviceSelectorViewTest, ExpandButtonOpensEntryContainer) { @@ -246,10 +251,10 @@ AddAudioDevices(delegate); view_ = CreateDeviceSelectorView(&delegate); - ASSERT_TRUE(view_->expand_button_); - EXPECT_FALSE(view_->device_entry_views_container_->GetVisible()); - SimulateButtonClick(view_->GetExpandButtonForTesting()); - EXPECT_TRUE(view_->device_entry_views_container_->GetVisible()); + ASSERT_TRUE(view_->GetDropdownButtonForTesting()); + EXPECT_FALSE(view_->GetDeviceEntryViewVisibilityForTesting()); + SimulateButtonClick(view_->GetDropdownButtonForTesting()); + EXPECT_TRUE(view_->GetDeviceEntryViewVisibilityForTesting()); } TEST_F(MediaItemUIDeviceSelectorViewTest, DeviceEntryContainerVisibility) { @@ -259,7 +264,7 @@ // The device entry container should be collapsed if the media dialog is // opened from the toolbar or Chrome OS system tray. view_ = CreateDeviceSelectorView(&delegate); - EXPECT_FALSE(view_->device_entry_views_container_->GetVisible()); + EXPECT_FALSE(view_->GetDeviceEntryViewVisibilityForTesting()); // The device entry container should be expanded if the media dialog is opened // for a presentation request. @@ -267,7 +272,7 @@ &delegate, std::make_unique<NiceMock<MockCastDialogController>>(), "1", /* has_audio_output */ true, global_media_controls::GlobalMediaControlsEntryPoint::kPresentation); - EXPECT_TRUE(view_->device_entry_views_container_->GetVisible()); + EXPECT_TRUE(view_->GetDeviceEntryViewVisibilityForTesting()); } TEST_F(MediaItemUIDeviceSelectorViewTest,
diff --git a/chrome/browser/ui/views/lens/lens_side_panel_controller.cc b/chrome/browser/ui/views/lens/lens_side_panel_controller.cc index 65557d4..d1873898 100644 --- a/chrome/browser/ui/views/lens/lens_side_panel_controller.cc +++ b/chrome/browser/ui/views/lens/lens_side_panel_controller.cc
@@ -9,7 +9,7 @@ #include "base/metrics/user_metrics_action.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/lens/lens_side_panel_view.h" -#include "chrome/browser/ui/views/side_panel.h" +#include "chrome/browser/ui/views/side_panel/side_panel.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "components/lens/lens_entrypoints.h" #include "content/public/browser/navigation_handle.h"
diff --git a/chrome/browser/ui/views/lens/lens_side_panel_controller_unittest.cc b/chrome/browser/ui/views/lens/lens_side_panel_controller_unittest.cc index bb24f58..e3f91660 100644 --- a/chrome/browser/ui/views/lens/lens_side_panel_controller_unittest.cc +++ b/chrome/browser/ui/views/lens/lens_side_panel_controller_unittest.cc
@@ -8,7 +8,7 @@ #include "base/test/metrics/user_action_tester.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/test_with_browser_view.h" -#include "chrome/browser/ui/views/side_panel.h" +#include "chrome/browser/ui/views/side_panel/side_panel.h" #include "components/lens/lens_features.h" #include "components/reading_list/features/reading_list_switches.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc index 51bed94..740b61b 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -57,6 +57,7 @@ #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/flex_layout.h" #include "ui/views/layout/flex_layout_types.h" +#include "ui/views/layout/table_layout.h" #include "ui/views/view_class_properties.h" #if !BUILDFLAG(IS_CHROMEOS_ASH) @@ -980,16 +981,14 @@ scroll_view->ClipHeightTo(0, GetMaxHeight()); scroll_view->SetContents(std::move(components)); - // Create a grid layout to set the menu width. - views::GridLayout* layout = - SetLayoutManager(std::make_unique<views::GridLayout>()); - views::ColumnSet* columns = layout->AddColumnSet(0); - columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, - views::GridLayout::kFixedSize, - views::GridLayout::ColumnSize::kFixed, kMenuWidth, - kMenuWidth); - layout->StartRow(1.0f, 0); - layout->AddView(std::move(scroll_view)); + // Create a table layout to set the menu width. + SetLayoutManager(std::make_unique<views::TableLayout>()) + ->AddColumn( + views::LayoutAlignment::kStretch, views::LayoutAlignment::kStretch, + views::TableLayout::kFixedSize, + views::TableLayout::ColumnSize::kFixed, kMenuWidth, kMenuWidth) + .AddRows(1, 1.0f); + AddChildView(std::move(scroll_view)); } void ProfileMenuViewBase::FocusFirstProfileButton() {
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view.cc b/chrome/browser/ui/views/profiles/profile_picker_view.cc index c5633848..beac788 100644 --- a/chrome/browser/ui/views/profiles/profile_picker_view.cc +++ b/chrome/browser/ui/views/profiles/profile_picker_view.cc
@@ -194,6 +194,11 @@ } // static +base::FilePath ProfilePicker::GetPickerProfilePath() { + return ProfileManager::GetSystemProfilePath(); +} + +// static void ProfilePicker::ShowDialog(content::BrowserContext* browser_context, const GURL& url, const base::FilePath& profile_path) { @@ -505,7 +510,7 @@ BuildLayout(); g_browser_process->profile_manager()->CreateProfileAsync( - ProfileManager::GetSystemProfilePath(), + ProfilePicker::GetPickerProfilePath(), base::BindRepeating(&ProfilePickerView::OnSystemProfileCreated, weak_ptr_factory_.GetWeakPtr())); return;
diff --git a/chrome/browser/ui/views/side_panel.cc b/chrome/browser/ui/views/side_panel/side_panel.cc similarity index 98% rename from chrome/browser/ui/views/side_panel.cc rename to chrome/browser/ui/views/side_panel/side_panel.cc index 515be3d..9a8bd07 100644 --- a/chrome/browser/ui/views/side_panel.cc +++ b/chrome/browser/ui/views/side_panel/side_panel.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/views/side_panel.h" +#include "chrome/browser/ui/views/side_panel/side_panel.h" #include <memory>
diff --git a/chrome/browser/ui/views/side_panel.h b/chrome/browser/ui/views/side_panel/side_panel.h similarity index 84% rename from chrome/browser/ui/views/side_panel.h rename to chrome/browser/ui/views/side_panel/side_panel.h index 24afc3f..7c6c750 100644 --- a/chrome/browser/ui/views/side_panel.h +++ b/chrome/browser/ui/views/side_panel/side_panel.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_H_ -#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_H_ +#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_H_ +#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_H_ #include "ui/base/metadata/metadata_header_macros.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" @@ -35,4 +35,4 @@ View* const border_view_; }; -#endif // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_H_ +#endif // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_SIDE_PANEL_H_
diff --git a/chrome/browser/ui/views/side_search/side_search_browser_controller.cc b/chrome/browser/ui/views/side_search/side_search_browser_controller.cc index b2cc30aa..a5f5563 100644 --- a/chrome/browser/ui/views/side_search/side_search_browser_controller.cc +++ b/chrome/browser/ui/views/side_search/side_search_browser_controller.cc
@@ -14,7 +14,7 @@ #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/side_panel.h" +#include "chrome/browser/ui/views/side_panel/side_panel.h" #include "chrome/browser/ui/views/toolbar/toolbar_button.h" #include "chrome/browser/ui/views/user_education/feature_promo_controller_views.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/views/side_search/side_search_browser_controller_browsertest.cc b/chrome/browser/ui/views/side_search/side_search_browser_controller_browsertest.cc index c02f251b..a6d1b4b 100644 --- a/chrome/browser/ui/views/side_search/side_search_browser_controller_browsertest.cc +++ b/chrome/browser/ui/views/side_search/side_search_browser_controller_browsertest.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/ui/side_search/side_search_tab_contents_helper.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/side_panel.h" +#include "chrome/browser/ui/views/side_panel/side_panel.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/in_process_browser_test.h"
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.cc b/chrome/browser/ui/views/tabs/tab_style_views.cc index 612d564..97d1400 100644 --- a/chrome/browser/ui/views/tabs/tab_style_views.cc +++ b/chrome/browser/ui/views/tabs/tab_style_views.cc
@@ -724,10 +724,11 @@ // that most tabs will fall on the low end of the opacity range, but very // narrow tabs will still stand out on the high end. const float range_start = static_cast<float>(GetStandardWidth()); - const float range_end = static_cast<float>(GetMinimumInactiveWidth()); + constexpr float kWidthForMaxHoverOpacity = 32.0f; const float value_in_range = static_cast<float>(tab_->width()); const float t = base::clamp( - (value_in_range - range_start) / (range_end - range_start), 0.0f, 1.0f); + (value_in_range - range_start) / (kWidthForMaxHoverOpacity - range_start), + 0.0f, 1.0f); return tab_->controller()->GetHoverOpacityForTab(t * t); }
diff --git a/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc b/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc index 3fd663a..e1d2b7f 100644 --- a/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc
@@ -20,7 +20,7 @@ #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/chrome_view_class_properties.h" #include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/side_panel.h" +#include "chrome/browser/ui/views/side_panel/side_panel.h" #include "chrome/browser/ui/views/user_education/feature_promo_controller_views.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/generated_resources.h"
diff --git a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc index 68ef4295..1c9f9161 100644 --- a/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc +++ b/chrome/browser/ui/web_applications/system_web_app_ui_utils.cc
@@ -193,11 +193,15 @@ if (!provider) return nullptr; + auto* system_app = provider->system_web_app_manager().GetSystemApp(app_type); + +#if defined(OS_CHROMEOS) DCHECK(url.DeprecatedGetOriginAsURL() == provider->registrar() .GetAppLaunchUrl(params.app_id) - .DeprecatedGetOriginAsURL()); + .DeprecatedGetOriginAsURL() || + system_app && system_app->IsUrlInSystemAppScope(url)); +#endif - auto* system_app = provider->system_web_app_manager().GetSystemApp(app_type); if (!system_app) { LOG(ERROR) << "Can't find delegate for system app url: " << url << " Not launching.";
diff --git a/chrome/browser/ui/web_applications/web_app_browser_controller.cc b/chrome/browser/ui/web_applications/web_app_browser_controller.cc index c620f81..6c1e971 100644 --- a/chrome/browser/ui/web_applications/web_app_browser_controller.cc +++ b/chrome/browser/ui/web_applications/web_app_browser_controller.cc
@@ -28,6 +28,8 @@ #include "chrome/browser/web_applications/web_app_sync_bridge.h" #include "chrome/common/chrome_features.h" #include "components/services/app_service/public/cpp/app_registry_cache.h" +#include "components/services/app_service/public/cpp/app_types.h" +#include "components/services/app_service/public/mojom/types.mojom-forward.h" #include "components/webapps/browser/installable/installable_metrics.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h" @@ -362,15 +364,24 @@ void WebAppBrowserController::LoadAppIcon(bool allow_placeholder_icon) const { apps::AppServiceProxy* proxy = apps::AppServiceProxyFactory::GetForProfile(browser()->profile()); - proxy->LoadIcon(proxy->AppRegistryCache().GetAppType(app_id()), app_id(), - apps::mojom::IconType::kStandard, kWebAppIconSmall, - allow_placeholder_icon, - base::BindOnce(&WebAppBrowserController::OnLoadIcon, - weak_ptr_factory_.GetWeakPtr())); + auto app_type = proxy->AppRegistryCache().GetAppType(app_id()); + if (base::FeatureList::IsEnabled(features::kAppServiceLoadIconWithoutMojom)) { + proxy->LoadIcon(apps::ConvertMojomAppTypToAppType(app_type), app_id(), + apps::IconType::kStandard, kWebAppIconSmall, + allow_placeholder_icon, + base::BindOnce(&WebAppBrowserController::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr())); + } else { + proxy->LoadIcon(app_type, app_id(), apps::mojom::IconType::kStandard, + kWebAppIconSmall, allow_placeholder_icon, + apps::MojomIconValueToIconValueCallback( + base::BindOnce(&WebAppBrowserController::OnLoadIcon, + weak_ptr_factory_.GetWeakPtr()))); + } } -void WebAppBrowserController::OnLoadIcon(apps::mojom::IconValuePtr icon_value) { - if (icon_value->icon_type != apps::mojom::IconType::kStandard) +void WebAppBrowserController::OnLoadIcon(apps::IconValuePtr icon_value) { + if (!icon_value || icon_value->icon_type != apps::IconType::kStandard) return; app_icon_ = ui::ImageModel::FromImageSkia(icon_value->uncompressed);
diff --git a/chrome/browser/ui/web_applications/web_app_browser_controller.h b/chrome/browser/ui/web_applications/web_app_browser_controller.h index acacbd0a..7530659a 100644 --- a/chrome/browser/ui/web_applications/web_app_browser_controller.h +++ b/chrome/browser/ui/web_applications/web_app_browser_controller.h
@@ -16,7 +16,7 @@ #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_registrar.h" -#include "components/services/app_service/public/mojom/types.mojom-forward.h" +#include "components/services/app_service/public/cpp/icon_types.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/models/image_model.h" @@ -102,7 +102,7 @@ // Helper function to call AppServiceProxy to load icon. void LoadAppIcon(bool allow_placeholder_icon) const; // Invoked when the icon is loaded. - void OnLoadIcon(apps::mojom::IconValuePtr icon_value); + void OnLoadIcon(apps::IconValuePtr icon_value); void OnReadIcon(SkBitmap bitmap); void PerformDigitalAssetLinkVerification(Browser* browser);
diff --git a/chrome/browser/ui/web_applications/web_app_launch_manager.cc b/chrome/browser/ui/web_applications/web_app_launch_manager.cc index df2c401..09940448 100644 --- a/chrome/browser/ui/web_applications/web_app_launch_manager.cc +++ b/chrome/browser/ui/web_applications/web_app_launch_manager.cc
@@ -152,7 +152,14 @@ // is in a web app's extended scope at the moment. // Because URL Handlers is not implemented for Chrome OS we can perform this // DCHECK on the basic scope. - DCHECK(provider_.registrar().IsUrlInAppScope(launch_url, params_.app_id)); + DCHECK(provider_.registrar().IsUrlInAppScope(launch_url, params_.app_id) || + GetSystemWebAppTypeForAppId(&profile_, params_.app_id) && + provider_.system_web_app_manager().GetSystemApp( + *GetSystemWebAppTypeForAppId(&profile_, params_.app_id)) && + provider_.system_web_app_manager() + .GetSystemApp( + *GetSystemWebAppTypeForAppId(&profile_, params_.app_id)) + ->IsUrlInSystemAppScope(launch_url)); #endif // System Web Apps have their own launch code path.
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index 0ff89f60..092569b6 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -255,6 +255,11 @@ #include "mojo/public/cpp/bindings/pending_receiver.h" #endif +#if defined(OS_CHROMEOS) +#include "chromeos/crosapi/cpp/gurl_os_handler_utils.h" +#include "url/url_util.h" +#endif + #if BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OFFICIAL_BUILD) #include "ash/webui/demo_mode_app_ui/demo_mode_app_ui.h" #include "ash/webui/demo_mode_app_ui/url_constants.h" @@ -1350,3 +1355,93 @@ return nullptr; } + +#if defined(OS_CHROMEOS) +std::vector<GURL> ChromeWebUIControllerFactory::GetListOfAcceptableURLs() { + // TODO(crbug/1234594): Need to refactor this entire class to generate the + // list automatically - which will be a giant CL touching lots of files. + // This will be done as a follow up to keep the CL small. + // If links are added in the interims: Please sort according to the order in + // go/lacros-url-redirect-links (alphabetically sorted according to link). +#if BUILDFLAG(IS_CHROMEOS_ASH) + return std::vector<GURL>{ + GURL(chrome::kChromeUIUntrustedCroshURL), + GURL(chrome::kChromeUIOsCroshAppURL), GURL(chrome::kOsUICroshURL), + GURL(ash::file_manager::kChromeUIFileManagerUntrustedURL), + GURL(chrome::kChromeUIUntrustedTerminalURL), + GURL(chrome::kOsUITerminalURL), + GURL(chrome::kChromeUIAccountManagerErrorURL), + GURL(chrome::kOsUIAccountManagerErrorURL), + GURL(chrome::kChromeUIAccountManagerWelcomeURL), + GURL(chrome::kOsUIAccountManagerWelcomeURL), + GURL(chrome::kChromeUIAccountMigrationWelcomeURL), + GURL(chrome::kOsUIAccountMigrationWelcomeURL), + GURL(chrome::kChromeUIAddSupervisionURL), + GURL(chrome::kOsUIAddSupervisionURL), + GURL(chrome::kChromeUIAppDisabledURL), GURL(chrome::kOsUIAppDisabledURL), + GURL(chrome::kOsUIArcGraphicsTracingURL), + GURL(chrome::kOsUIArcOverviewTracingURL), + GURL(chrome::kOsUIArcPowerControlURL), + GURL(chrome::kOsUIAssistantOptInURL), + GURL(chrome::kOsUIBluetoothPairingURL), GURL(chrome::kOsUIComponentsUrl), + GURL(chrome::kChromeUICrashesUrl), GURL(chrome::kOsUICrashesUrl), + GURL(chrome::kOsUICreditsURL), GURL(chrome::kOsUICrostiniCreditsURL), + GURL(chrome::kOsUICrostiniInstallerUrl), + GURL(chrome::kOsUICrostiniUpgraderUrl), GURL(chrome::kOsUICryptohomeURL), + GURL(chrome::kOsUIDeviceLogUrl), GURL(chrome::kOsUIDiagnosticsAppURL), + GURL(chrome::kChromeUIDriveInternalsUrl), + GURL(chrome::kOsUIDriveInternalsUrl), + GURL(chrome::kChromeUIEmojiPickerURL), GURL(chrome::kOsUIEmojiPickerURL), + GURL(ash::file_manager::kChromeUIFileManagerURL), + GURL(chrome::kOsUIFileManagerURL), GURL(chrome::kChromeUIFlagsURL), + GURL(chrome::kOsUIFlagsURL), GURL(chrome::kOsUIGpuURL), + GURL(chrome::kOsUIHistogramsURL), + GURL(chrome::kOsUIIntenetConfigDialogURL), + GURL(chrome::kOsUIIntenetDetailDialogURL), + GURL(chrome::kOsUIInvalidationsUrl), + GURL(chrome::kChromeUILockScreenNetworkURL), + GURL(chrome::kOsUILockScreenStartReauthURL), + GURL(chrome::kChromeUILockScreenNetworkURL), + GURL(chrome::kOsUILockScreenStartReauthURL), + GURL(chrome::kOsUIMobileSetupURL), GURL(chrome::kOsUIMultiDeviceSetupUrl), + GURL(chrome::kChromeUINetworkUrl), GURL(chrome::kOsUINetworkUrl), + GURL(chrome::kOsUIOSCreditsURL), GURL(chrome::kOsUIOSSettingsURL), + GURL(chrome::kOsUIPowerUrl), GURL(chrome::kOsUIPrintManagementUrl), + GURL(chrome::kOsUIRestartURL), GURL(chrome::kChromeUIScanningAppURL), + GURL(chrome::kOsUIScanningAppURL), GURL(chrome::kOsUISetTimeURL), + GURL(chrome::kChromeUISettingsURL), GURL(chrome::kOsUISettingsURL), + GURL(chrome::kOsUISignInInternalsUrl), GURL(chrome::kOsUISlowURL), + GURL(chrome::kOsUISmbCredentialsURL), GURL(chrome::kOsUISmbShareURL), + GURL(chrome::kOsUISyncInternalsUrl), GURL(chrome::kOsUISysInternalsUrl), + GURL(chrome::kOsUIUserImageURL), GURL(chrome::kOsUIVersionURL), + GURL(chrome::kOsUIVmUrl), + // The CL to land this didn't land yet. Once landed they need to be moved + // to Lacros. However - as the refactor might precede this, there is no + // TODO for it. + GURL(chrome::kChromeUICertificateManagerDialogURL)}; +#elif BUILDFLAG(IS_CHROMEOS_LACROS) + return std::vector<GURL>{GURL(chrome::kChromeUIAboutURL), + GURL(chrome::kChromeUIComponentsUrl), + GURL(chrome::kChromeUICreditsURL), + GURL(chrome::kChromeUIDeviceLogUrl), + GURL(chrome::kChromeUIFlagsURL), + GURL(chrome::kChromeUIGpuURL), + GURL(chrome::kChromeUIHistogramsURL), + GURL(chrome::kChromeUIInvalidationsUrl), + GURL(chrome::kChromeUIManagementURL), + GURL(chrome::kChromeUIOSSettingsURL), + GURL(chrome::kChromeUIPolicyURL), + GURL(chrome::kChromeUIRestartURL), + GURL(chrome::kChromeUISettingsURL), + GURL(chrome::kChromeUISignInInternalsUrl), + GURL(chrome::kChromeUISyncInternalsUrl), + GURL(chrome::kChromeUIVersionURL)}; +#endif +} + +bool ChromeWebUIControllerFactory::CanHandleUrl(const GURL& url) { + return crosapi::gurl_os_handler_utils::IsUrlInList(url, + GetListOfAcceptableURLs()); +} + +#endif
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.h b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.h index 783998aa..afdc1317 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.h +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.h
@@ -55,6 +55,17 @@ const std::vector<int>& desired_sizes_in_pixel, favicon_base::FaviconResultsCallback callback) const; +#if defined(OS_CHROMEOS) + // Called to retrieve a list of URLs which can be handled by this browser. + // For Ash this means that they are shown in an SWA application and for + // Lacros it means that Lacros will handle them themselves. + std::vector<GURL> GetListOfAcceptableURLs(); + + // Determines if the given URL can be handled by any known handler. + // Note that the provided |url| needs to be sanitized. + bool CanHandleUrl(const GURL& url); +#endif + protected: ChromeWebUIControllerFactory(); ~ChromeWebUIControllerFactory() override;
diff --git a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc index 6a13a61..6abfc21b 100644 --- a/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc +++ b/chrome/browser/ui/webui/settings/chromeos/privacy_section.cc
@@ -256,10 +256,17 @@ {"privacyPageTitle", IDS_SETTINGS_PRIVACY_V2}, {"smartPrivacyTitle", IDS_OS_SETTINGS_SMART_PRIVACY_TITLE}, {"smartPrivacySubtext", IDS_OS_SETTINGS_SMART_PRIVACY_SUBTEXT}, + {"smartPrivacyDesc", IDS_OS_SETTINGS_SMART_PRIVACY_DESC}, + {"smartPrivacyScreenLockTitle", + IDS_OS_SETTINGS_SMART_PRIVACY_SCREEN_LOCK_TITLE}, + {"smartPrivacyScreenLockSubtext", + IDS_OS_SETTINGS_SMART_PRIVACY_SCREEN_LOCK_SUBTEXT}, {"smartPrivacySnoopingTitle", IDS_OS_SETTINGS_SMART_PRIVACY_SNOOPING_TITLE}, {"smartPrivacySnoopingSubtext", IDS_OS_SETTINGS_SMART_PRIVACY_SNOOPING_SUBTEXT}, + {"smartPrivacySnoopingIcon", IDS_OS_SETTINGS_SMART_PRIVACY_SNOOPING_ICON}, + {"smartPrivacySnoopingDim", IDS_OS_SETTINGS_SMART_PRIVACY_SNOOPING_DIM}, }; html_source->AddLocalizedStrings(kLocalizedStrings);
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.cc b/chrome/browser/ui/webui/signin/profile_picker_handler.cc index 92ebc5f..e0364c0d 100644 --- a/chrome/browser/ui/webui/signin/profile_picker_handler.cc +++ b/chrome/browser/ui/webui/signin/profile_picker_handler.cc
@@ -50,6 +50,7 @@ #include "components/signin/public/identity_manager/account_info.h" #include "components/startup_metric_utils/browser/startup_metric_utils.h" #include "content/public/browser/url_data_source.h" +#include "content/public/browser/web_ui.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/webui/web_ui_util.h" @@ -57,7 +58,10 @@ #include "ui/gfx/image/image.h" #if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/lacros/account_manager/account_manager_util.h" +#include "chrome/browser/lacros/account_manager/account_profile_mapper.h" #include "chrome/browser/ui/webui/signin/profile_picker_lacros_sign_in_provider.h" +#include "components/account_manager_core/account.h" #endif namespace { @@ -208,6 +212,34 @@ return profile_entry; } +#if BUILDFLAG(IS_CHROMEOS_LACROS) +base::FilePath GetCurrentProfilePath(content::WebUI* web_ui) { + DCHECK(web_ui); + return web_ui->GetWebContents()->GetBrowserContext()->GetPath(); +} + +bool IsSelectingSecondaryAccount(content::WebUI* web_ui) { + // If this WebUI page is rendered in a user profile (and not the default + // picker profile), this means the page should show accounts that are + // available as secondary for this specific profile. + return GetCurrentProfilePath(web_ui) != ProfilePicker::GetPickerProfilePath(); +} + +SkBitmap GetAvailableAccountBitmap(const gfx::Image& gaia_image, + bool dark_mode) { + if (!gaia_image.IsEmpty()) + return gaia_image.AsBitmap(); + + // Return a default avatar. + const int kAccountPictureSize = 128; + ProfileThemeColors colors = GetDefaultProfileThemeColors(dark_mode); + gfx::Image default_image = profiles::GetPlaceholderAvatarIconWithColors( + colors.default_avatar_fill_color, colors.default_avatar_stroke_color, + kAccountPictureSize); + return default_image.AsBitmap(); +} +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + } // namespace ProfilePickerHandler::ProfilePickerHandler() = default; @@ -711,6 +743,26 @@ #if BUILDFLAG(IS_CHROMEOS_LACROS) if (base::FeatureList::IsEnabled(kMultiProfileAccountConsistency)) { + if (IsSelectingSecondaryAccount(web_ui())) { + AccountProfileMapper* mapper = + g_browser_process->profile_manager()->GetAccountProfileMapper(); + const std::string& gaia_id = args->GetList()[1].GetString(); + if (gaia_id.empty()) { + mapper->ShowAddAccountDialog( + GetCurrentProfilePath(web_ui()), + account_manager::AccountManagerFacade::AccountAdditionSource:: + kOgbAddAccount, + AccountProfileMapper::AddAccountCallback()); + } else { + mapper->AddAccount(GetCurrentProfilePath(web_ui()), + account_manager::AccountKey( + gaia_id, account_manager::AccountType::kGaia), + AccountProfileMapper::AddAccountCallback()); + } + ProfilePicker::Hide(); + return; + } + DCHECK(!lacros_sign_in_provider_); lacros_sign_in_provider_ = std::make_unique<ProfilePickerLacrosSignInProvider>(); @@ -970,9 +1022,59 @@ void ProfilePickerHandler::HandleGetUnassignedAccounts( const base::ListValue* args) { AllowJavascript(); + AccountProfileMapper* mapper = + g_browser_process->profile_manager()->GetAccountProfileMapper(); + + if (IsSelectingSecondaryAccount(web_ui())) { + GetAccountsAvailableAsSecondary( + mapper, GetCurrentProfilePath(web_ui()), + base::BindOnce(&ProfilePickerHandler::GetAvailableAccountsInfo, + weak_factory_.GetWeakPtr())); + return; + } + GetAccountsAvailableAsPrimary( + mapper, + &g_browser_process->profile_manager()->GetProfileAttributesStorage(), + base::BindOnce(&ProfilePickerHandler::GetAvailableAccountsInfo, + weak_factory_.GetWeakPtr())); +} + +void ProfilePickerHandler::GetAvailableAccountsInfo( + const std::vector<account_manager::Account>& accounts) { + // If there's a request in flight, it deletes the current helper and starts a + // new request. + lacros_account_info_helper_ = std::make_unique<GetAccountInformationHelper>(); + + std::vector<std::string> gaia_ids; + for (const account_manager::Account& account : accounts) + gaia_ids.push_back(account.key.id()); + lacros_account_info_helper_->Start( + gaia_ids, base::BindOnce(&ProfilePickerHandler::SendAvailableAccounts, + weak_factory_.GetWeakPtr())); +} + +void ProfilePickerHandler::SendAvailableAccounts( + std::vector<GetAccountInformationHelper::GetAccountInformationResult> + accounts) { base::Value accounts_list(base::Value::Type::LIST); - // TODO(https://crbug/1226050): Add actual account info to the list, and - // listen for account changes. + for (const GetAccountInformationHelper::GetAccountInformationResult& account : + accounts) { + // TODO(https://crbug/1226050): Filter out items with no email as items + // without an email are impossible to use. The email should be always + // available, unless the mojo connection fails. This requires more robust + // unit-tests. + base::Value account_dict(base::Value::Type::DICTIONARY); + account_dict.SetStringKey("gaiaId", account.gaia); + account_dict.SetStringKey("email", account.email); + account_dict.SetStringKey("name", account.full_name); + SkBitmap account_bitmap = GetAvailableAccountBitmap( + account.account_image, webui::GetNativeTheme(web_ui()->GetWebContents()) + ->ShouldUseDarkColors()); + account_dict.SetStringKey("accountImageUrl", + webui::GetBitmapDataUrl(account_bitmap)); + accounts_list.Append(std::move(account_dict)); + } + // TODO(https://crbug/1226050): Listen for account changes. FireWebUIListener("unassigned-accounts-changed", std::move(accounts_list)); }
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler.h b/chrome/browser/ui/webui/signin/profile_picker_handler.h index 88936c10..60c0d8a2 100644 --- a/chrome/browser/ui/webui/signin/profile_picker_handler.h +++ b/chrome/browser/ui/webui/signin/profile_picker_handler.h
@@ -22,7 +22,13 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/lacros/account_manager/get_account_information_helper.h" + class ProfilePickerLacrosSignInProvider; + +namespace account_manager { +struct Account; +} #endif // The handler for Javascript messages related to the profile picker main view. @@ -127,10 +133,19 @@ void SetProfilesOrder(const std::vector<ProfileAttributesEntry*>& entries); #if BUILDFLAG(IS_CHROMEOS_LACROS) - // List of usnassigned accounts used by the profile choice and the account + // List of unassigned accounts used by the profile choice and the account // selection screens. + // TODO(crbug.com/1226050): Rename this concept in code to available accounts. void HandleGetUnassignedAccounts(const base::ListValue* args); + // Loads extended info for accounts from Ash. + void GetAvailableAccountsInfo( + const std::vector<account_manager::Account>& accounts); + // Sends extended info for accounts to the WebUI page. + void SendAvailableAccounts( + std::vector<GetAccountInformationHelper::GetAccountInformationResult> + accounts); + // Called when a new Lacros signed-in profile is created. The profile is // omitted, ephemeral, and has a primary kSignin account. void OnLacrosSignedInProfileCreated(absl::optional<SkColor> profile_color, @@ -149,6 +164,9 @@ #if BUILDFLAG(IS_CHROMEOS_LACROS) // Takes care of getting a signed-in profile. std::unique_ptr<ProfilePickerLacrosSignInProvider> lacros_sign_in_provider_; + + // Retrieves extended info for available accounts from Ash. + std::unique_ptr<GetAccountInformationHelper> lacros_account_info_helper_; #endif // BUILDFLAG(IS_CHROMEOS_LACROS) // The order of the profiles when the picker was first shown. This is used
diff --git a/chrome/browser/ui/webui/signin/profile_picker_handler_unittest.cc b/chrome/browser/ui/webui/signin/profile_picker_handler_unittest.cc index 650f43f..a1b85ac 100644 --- a/chrome/browser/ui/webui/signin/profile_picker_handler_unittest.cc +++ b/chrome/browser/ui/webui/signin/profile_picker_handler_unittest.cc
@@ -81,13 +81,17 @@ profile_manager()->profile_attributes_storage())); #endif - system_profile_ = profile_manager()->CreateSystemProfile(); + web_ui_profile_ = GetWebUIProfile(); web_ui_.set_web_contents( - web_contents_factory_.CreateWebContents(system_profile_)); + web_contents_factory_.CreateWebContents(web_ui_profile_)); handler_.set_web_ui(&web_ui_); handler_.RegisterMessages(); } + virtual Profile* GetWebUIProfile() { + return profile_manager()->CreateSystemProfile(); + } + void VerifyProfileListWasPushed( const std::vector<ProfileAttributesEntry*>& ordered_profile_entries) { ASSERT_TRUE(!web_ui()->call_data().empty()); @@ -147,7 +151,8 @@ #if BUILDFLAG(IS_CHROMEOS_LACROS) base::test::ScopedFeatureList scoped_feature_list_{ kMultiProfileAccountConsistency}; - account_manager::MockAccountManagerFacade mock_account_manager_facade_; + testing::NiceMock<account_manager::MockAccountManagerFacade> + mock_account_manager_facade_; // Callback to configure the accounts in the facade. base::OnceCallback<void(const std::vector<account_manager::Account>&)> @@ -157,7 +162,7 @@ content::BrowserTaskEnvironment task_environment_; TestingProfileManager profile_manager_; content::TestWebContentsFactory web_contents_factory_; - Profile* system_profile_ = nullptr; + Profile* web_ui_profile_ = nullptr; content::TestWebUI web_ui_; ProfilePickerHandler handler_; }; @@ -294,14 +299,15 @@ #if BUILDFLAG(IS_CHROMEOS_LACROS) -TEST_F(ProfilePickerHandlerTest, HandleGetUnassignedAccounts) { +// Tests that accounts available as primary are returned. +TEST_F(ProfilePickerHandlerTest, HandleGetUnassignedAccounts_Empty) { + CompleteFacadeGetAccounts({}); + // Send message to the handler. base::ListValue empty_args; web_ui()->HandleReceivedMessage("getUnassignedAccounts", &empty_args); // Check that the handler replied. - // TODO(https://crbug/1226050): Update the test once this is fully - // implemented. ASSERT_TRUE(!web_ui()->call_data().empty()); const content::TestWebUI::CallData& data = *web_ui()->call_data().back(); EXPECT_EQ("cr.webUIListenerCallback", data.function_name()); @@ -309,6 +315,57 @@ EXPECT_TRUE(data.arg2()->GetList().empty()); } +TEST_F(ProfilePickerHandlerTest, HandleGetUnassignedAccounts_Available) { + // AccountProfileMapper only allows unassigned accounts if there are + // multiple profiles. + CreateTestingProfile("Primary"); + ProfileAttributesEntry* secondary = CreateTestingProfile("Secondary"); + + // Add an available account into the facade + const std::string kGaiaId1 = "some_gaia_id1"; + const std::string kGaiaId2 = "some_gaia_id2"; + const std::string kEmail2 = "example2@gmail.com"; + CompleteFacadeGetAccounts( + {account_manager::Account{ + account_manager::AccountKey{kGaiaId1, + account_manager::AccountType::kGaia}, + "example1@gmail.com"}, + account_manager::Account{ + account_manager::AccountKey{kGaiaId2, + account_manager::AccountType::kGaia}, + kEmail2}}); + + // ****** No accounts syncing in any profile: return all. + // Send message to the handler. + base::ListValue empty_args; + web_ui()->HandleReceivedMessage("getUnassignedAccounts", &empty_args); + + // Check that the handler replied. + ASSERT_TRUE(!web_ui()->call_data().empty()); + const content::TestWebUI::CallData& data1 = *web_ui()->call_data().back(); + EXPECT_EQ("cr.webUIListenerCallback", data1.function_name()); + EXPECT_EQ("unassigned-accounts-changed", data1.arg1()->GetString()); + EXPECT_EQ(data1.arg2()->GetList().size(), 2u); + + // ****** Account 1 syncing in Secondary profile: return account 2. + secondary->SetAuthInfo(kGaiaId1, u"example1@gmail.com", + /*is_consented_primary_account=*/true); + // Send message to the handler. + web_ui()->HandleReceivedMessage("getUnassignedAccounts", &empty_args); + + // Check that the handler replied. + ASSERT_TRUE(!web_ui()->call_data().empty()); + const content::TestWebUI::CallData& data2 = *web_ui()->call_data().back(); + EXPECT_EQ("cr.webUIListenerCallback", data2.function_name()); + EXPECT_EQ("unassigned-accounts-changed", data2.arg1()->GetString()); + EXPECT_EQ(data2.arg2()->GetList().size(), 1u); + const std::string* gaia_id = + data2.arg2()->GetList()[0].FindStringPath("gaiaId"); + EXPECT_NE(gaia_id, nullptr); + EXPECT_EQ(*gaia_id, kGaiaId2); + // TODO(https://crbug/1226050): Test all other fields. +} + TEST_F(ProfilePickerHandlerTest, CreateProfileExistingAccount) { // Lacros always expects a default profile. CreateTestingProfile("Default"); @@ -406,4 +463,91 @@ EXPECT_TRUE(success); } +class ProfilePickerHandlerInUserProfileTest : public ProfilePickerHandlerTest { + public: + ProfilePickerHandlerInUserProfileTest() = default; + + void SetUp() override { + ProfilePickerHandlerTest::SetUp(); + // AccountProfileMapper only allows unassigned accounts if there are + // multiple profiles (another profile, named "Secondary", is created below). + CreateTestingProfile("Primary"); + } + + Profile* GetWebUIProfile() override { + Profile* profile = profile_manager()->CreateTestingProfile("Secondary"); + secondary_profile_entry_ = + profile_manager() + ->profile_attributes_storage() + ->GetProfileAttributesWithPath(profile->GetPath()); + return profile; + } + + protected: + ProfileAttributesEntry* secondary_profile_entry_ = nullptr; +}; + +// Tests that accounts available as secondary are returned. +TEST_F(ProfilePickerHandlerInUserProfileTest, + HandleGetUnassignedAccounts_Empty) { + CompleteFacadeGetAccounts({}); + + // Send message to the handler. + base::ListValue empty_args; + web_ui()->HandleReceivedMessage("getUnassignedAccounts", &empty_args); + + // Check that the handler replied. + ASSERT_TRUE(!web_ui()->call_data().empty()); + const content::TestWebUI::CallData& data = *web_ui()->call_data().back(); + EXPECT_EQ("cr.webUIListenerCallback", data.function_name()); + EXPECT_EQ("unassigned-accounts-changed", data.arg1()->GetString()); + EXPECT_TRUE(data.arg2()->GetList().empty()); +} + +TEST_F(ProfilePickerHandlerInUserProfileTest, + HandleGetUnassignedAccounts_Available) { + // Add an available account into the facade + const std::string kGaiaId1 = "some_gaia_id1"; + const std::string kGaiaId2 = "some_gaia_id2"; + const std::string kEmail2 = "example2@gmail.com"; + CompleteFacadeGetAccounts( + {account_manager::Account{ + account_manager::AccountKey{kGaiaId1, + account_manager::AccountType::kGaia}, + "example1@gmail.com"}, + account_manager::Account{ + account_manager::AccountKey{kGaiaId2, + account_manager::AccountType::kGaia}, + kEmail2}}); + + // ****** No accounts assigned to "Secondary": return all. + // Send message to the handler. + base::ListValue empty_args; + web_ui()->HandleReceivedMessage("getUnassignedAccounts", &empty_args); + + // Check that the handler replied. + ASSERT_TRUE(!web_ui()->call_data().empty()); + const content::TestWebUI::CallData& data1 = *web_ui()->call_data().back(); + EXPECT_EQ("cr.webUIListenerCallback", data1.function_name()); + EXPECT_EQ("unassigned-accounts-changed", data1.arg1()->GetString()); + EXPECT_EQ(data1.arg2()->GetList().size(), 2u); + + // ****** Account 1 is assigned to "Secondary": return account 2. + secondary_profile_entry_->SetGaiaIds({kGaiaId1}); + // Send message to the handler. + web_ui()->HandleReceivedMessage("getUnassignedAccounts", &empty_args); + + // Check that the handler replied. + ASSERT_TRUE(!web_ui()->call_data().empty()); + const content::TestWebUI::CallData& data2 = *web_ui()->call_data().back(); + EXPECT_EQ("cr.webUIListenerCallback", data2.function_name()); + EXPECT_EQ("unassigned-accounts-changed", data2.arg1()->GetString()); + EXPECT_EQ(data2.arg2()->GetList().size(), 1u); + const std::string* gaia_id = + data2.arg2()->GetList()[0].FindStringPath("gaiaId"); + EXPECT_NE(gaia_id, nullptr); + EXPECT_EQ(*gaia_id, kGaiaId2); + // TODO(https://crbug/1226050): Test all other fields. +} + #endif // BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc index 32fa850..3218f89c 100644 --- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc +++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.cc
@@ -734,7 +734,7 @@ // Add a flag to remember this tab originated in the ARC context. web_contents->SetUserData( &arc::ArcWebContentsData::kArcTransitionFlag, - std::make_unique<arc::ArcWebContentsData>()); + std::make_unique<arc::ArcWebContentsData>(web_contents)); } #endif std::move(success_callback).Run(/*success=*/!!web_contents);
diff --git a/chrome/browser/web_applications/app_service/web_apps.cc b/chrome/browser/web_applications/app_service/web_apps.cc index 951b4c4..4bc26104 100644 --- a/chrome/browser/web_applications/app_service/web_apps.cc +++ b/chrome/browser/web_applications/app_service/web_apps.cc
@@ -143,6 +143,13 @@ std::move(callback)); } +void WebApps::LaunchAppWithParams(apps::AppLaunchParams&& params, + apps::LaunchCallback callback) { + publisher_helper().LaunchAppWithParams(std::move(params)); + // TODO(crbug.com/1244506): Add launch return value. + std::move(callback).Run(apps::LaunchResult()); +} + void WebApps::Connect( mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote, apps::mojom::ConnectOptionsPtr opts) {
diff --git a/chrome/browser/web_applications/app_service/web_apps.h b/chrome/browser/web_applications/app_service/web_apps.h index 9cef38a..b5545f2 100644 --- a/chrome/browser/web_applications/app_service/web_apps.h +++ b/chrome/browser/web_applications/app_service/web_apps.h
@@ -35,6 +35,7 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) namespace apps { class InstanceRegistry; +struct AppLaunchParams; } #endif @@ -86,6 +87,8 @@ int32_t size_hint_in_dip, bool allow_placeholder_icon, apps::LoadIconCallback callback) override; + void LaunchAppWithParams(apps::AppLaunchParams&& params, + apps::LaunchCallback callback) override; // apps::mojom::Publisher overrides. void Connect(mojo::PendingRemote<apps::mojom::Subscriber> subscriber_remote,
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_browsertest.cc b/chrome/browser/web_applications/extensions/bookmark_app_browsertest.cc deleted file mode 100644 index 03a66a23..0000000 --- a/chrome/browser/web_applications/extensions/bookmark_app_browsertest.cc +++ /dev/null
@@ -1,38 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> - -#include "base/threading/thread_restrictions.h" -#include "chrome/browser/extensions/extension_browsertest.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/web_applications/web_app_helpers.h" -#include "content/public/test/browser_test.h" -#include "extensions/common/extension.h" -#include "extensions/common/file_util.h" -#include "extensions/common/mojom/manifest.mojom.h" -#include "ui/gfx/geometry/rect.h" - -namespace extensions { - -using BookmarkAppBrowserTest = ExtensionBrowserTest; - -IN_PROC_BROWSER_TEST_F(BookmarkAppBrowserTest, NoAppBrowserController) { - const Extension* extension = InstallExtensionWithSourceAndFlags( - test_data_dir_.AppendASCII("app"), - /*expected_change=*/1, extensions::mojom::ManifestLocation::kUnpacked, - Extension::FROM_BOOKMARK); - ASSERT_TRUE(extension->is_hosted_app()); - ASSERT_TRUE(extension->from_bookmark()); - - const std::string app_name = - web_app::GenerateApplicationNameFromAppId(extension->id()); - Browser::CreateParams browser_params = Browser::CreateParams::CreateForApp( - app_name, /*trusted_source=*/true, gfx::Rect(), profile(), - /*user_gesture=*/true); - Browser* app_browser = Browser::Create(browser_params); - EXPECT_FALSE(app_browser->app_controller()); -} - -} // namespace extensions
diff --git a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc index 7f67138..01530e39 100644 --- a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc +++ b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
@@ -42,9 +42,12 @@ #if BUILDFLAG(IS_CHROMEOS_ASH) #include "ash/constants/ash_features.h" +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if defined(OS_CHROMEOS) #include "chrome/browser/policy/system_features_disable_list_policy_handler.h" #include "components/policy/core/common/policy_pref_names.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // defined(OS_CHROMEOS) using sync_preferences::TestingPrefServiceSyncable; @@ -919,7 +922,7 @@ } } -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) TEST_P(WebAppPolicyManagerTest, DisableWebApps) { policy_manager().Start(); base::RunLoop().RunUntilIdle(); @@ -951,7 +954,7 @@ base::RunLoop().RunUntilIdle(); EXPECT_TRUE(policy_manager().IsDisabledAppsModeHidden()); } -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // defined(OS_CHROMEOS) TEST_P(WebAppPolicyManagerTest, WebAppSettingsDynamicRefresh) { if (ShouldSkipPWASpecificTest())
diff --git a/chrome/browser/web_applications/file_handlers_permission_helper.cc b/chrome/browser/web_applications/file_handlers_permission_helper.cc index 029ef77..7fb6970 100644 --- a/chrome/browser/web_applications/file_handlers_permission_helper.cc +++ b/chrome/browser/web_applications/file_handlers_permission_helper.cc
@@ -191,7 +191,6 @@ return; } - ScopedRegistryUpdate update(&finalizer_->sync_bridge()); for (const AppId& app_id : finalizer_->registrar().GetAppIds()) { const WebApp* app = finalizer_->GetWebAppRegistrar().GetAppById(app_id); if (!app || !app->is_locally_installed()) @@ -205,8 +204,11 @@ if (permission_blocked == app->file_handler_permission_blocked()) continue; - WebApp* app_to_update = update->UpdateApp(app_id); - app_to_update->SetFileHandlerPermissionBlocked(permission_blocked); + { + ScopedRegistryUpdate update(&finalizer_->sync_bridge()); + update->UpdateApp(app_id)->SetFileHandlerPermissionBlocked( + permission_blocked); + } FileHandlerUpdateAction file_handlers_need_os_update = permission_blocked ? FileHandlerUpdateAction::kRemove : FileHandlerUpdateAction::kUpdate;
diff --git a/chrome/browser/web_applications/os_integration_manager.cc b/chrome/browser/web_applications/os_integration_manager.cc index e61dc77..4a10300 100644 --- a/chrome/browser/web_applications/os_integration_manager.cc +++ b/chrome/browser/web_applications/os_integration_manager.cc
@@ -100,12 +100,15 @@ OsIntegrationManager::~OsIntegrationManager() = default; -void OsIntegrationManager::SetSubsystems(WebAppRegistrar* registrar, +void OsIntegrationManager::SetSubsystems(WebAppSyncBridge* sync_bridge, + WebAppRegistrar* registrar, WebAppUiManager* ui_manager, WebAppIconManager* icon_manager) { + // TODO(estade): fetch the registrar from `sync_bridge` instead of passing + // both as arguments. registrar_ = registrar; ui_manager_ = ui_manager; - file_handler_manager_->SetSubsystems(registrar); + file_handler_manager_->SetSubsystems(sync_bridge); shortcut_manager_->SetSubsystems(icon_manager, registrar); if (protocol_handler_manager_) protocol_handler_manager_->SetSubsystems(registrar); @@ -117,6 +120,8 @@ DCHECK(registrar_); DCHECK(file_handler_manager_); + registrar_observation_.Observe(registrar_); + #if defined(OS_MAC) // Ensure that all installed apps are included in the AppShimRegistry when the // profile is loaded. This is redundant, because apps are registered when they @@ -708,6 +713,10 @@ UnregisterProtocolHandlers(app_id, std::move(unregister_callback)); } +void OsIntegrationManager::OnWebAppProfileWillBeDeleted(const AppId& app_id) { + UninstallAllOsHooks(app_id, base::DoNothing()); +} + std::unique_ptr<ShortcutInfo> OsIntegrationManager::BuildShortcutInfo( const AppId& app_id) { DCHECK(shortcut_manager_);
diff --git a/chrome/browser/web_applications/os_integration_manager.h b/chrome/browser/web_applications/os_integration_manager.h index 743a30a..b6b5fd2 100644 --- a/chrome/browser/web_applications/os_integration_manager.h +++ b/chrome/browser/web_applications/os_integration_manager.h
@@ -12,7 +12,9 @@ #include "base/auto_reset.h" #include "base/callback_forward.h" #include "base/memory/weak_ptr.h" +#include "base/scoped_observation.h" #include "base/strings/string_piece_forward.h" +#include "chrome/browser/web_applications/app_registrar_observer.h" #include "chrome/browser/web_applications/url_handler_manager.h" #include "chrome/browser/web_applications/web_app_constants.h" #include "chrome/browser/web_applications/web_app_file_handler_manager.h" @@ -32,6 +34,7 @@ class FakeOsIntegrationManager; class WebAppIconManager; class WebAppRegistrar; +class WebAppSyncBridge; class WebAppUiManager; // OsHooksErrors contains the result of all Os hook deployments. @@ -74,7 +77,7 @@ // all OS hooks during Web App lifecycle. // It contains individual OS integration managers and takes // care of inter-dependencies among them. -class OsIntegrationManager { +class OsIntegrationManager : public AppRegistrarObserver { public: explicit OsIntegrationManager( Profile* profile, @@ -82,9 +85,10 @@ std::unique_ptr<WebAppFileHandlerManager> file_handler_manager, std::unique_ptr<WebAppProtocolHandlerManager> protocol_handler_manager, std::unique_ptr<UrlHandlerManager> url_handler_manager); - virtual ~OsIntegrationManager(); + ~OsIntegrationManager() override; - void SetSubsystems(WebAppRegistrar* registrar, + void SetSubsystems(WebAppSyncBridge* sync_bridge, + WebAppRegistrar* registrar, WebAppUiManager* ui_manager, WebAppIconManager* icon_manager); @@ -184,6 +188,9 @@ bool force_shortcut_updates_if_needed, base::OnceClosure callback); + // AppRegistrarObserver: + void OnWebAppProfileWillBeDeleted(const AppId& app_id) override; + protected: WebAppShortcutManager* shortcut_manager() { return shortcut_manager_.get(); } WebAppFileHandlerManager* file_handler_manager() { @@ -296,6 +303,9 @@ std::unique_ptr<WebAppProtocolHandlerManager> protocol_handler_manager_; std::unique_ptr<UrlHandlerManager> url_handler_manager_; + base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver> + registrar_observation_{this}; + base::WeakPtrFactory<OsIntegrationManager> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager.cc b/chrome/browser/web_applications/policy/web_app_policy_manager.cc index 3c7eab63..f10e28d 100644 --- a/chrome/browser/web_applications/policy/web_app_policy_manager.cc +++ b/chrome/browser/web_applications/policy/web_app_policy_manager.cc
@@ -171,7 +171,7 @@ } bool WebAppPolicyManager::IsDisabledAppsModeHidden() const { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) PrefService* const local_state = g_browser_process->local_state(); if (!local_state) // Sometimes it's not available in tests. return false; @@ -180,7 +180,7 @@ local_state->GetString(policy::policy_prefs::kSystemFeaturesDisableMode); if (disabled_mode == policy::kHiddenDisableMode) return true; -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // defined(OS_CHROMEOS) return false; } @@ -521,9 +521,9 @@ } void WebAppPolicyManager::OnDisableModePolicyChanged() { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) sync_bridge_->UpdateAppsDisableMode(); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // defined(OS_CHROMEOS) } void WebAppPolicyManager::PopulateDisabledWebAppsIdsLists() {
diff --git a/chrome/browser/web_applications/proto/web_app.proto b/chrome/browser/web_applications/proto/web_app.proto index 8ea62f2c..c25612dd 100644 --- a/chrome/browser/web_applications/proto/web_app.proto +++ b/chrome/browser/web_applications/proto/web_app.proto
@@ -255,7 +255,7 @@ // For apps installed via the SubApp API, ID of the parent app that installed // the Sub-app. optional string parent_app_id = 43; - + // A background color to be used when the app is opened in dark mode. optional uint32 dark_mode_background_color = 44; @@ -263,4 +263,14 @@ // startup, it's assumed there was a crash or other error during // uninstallation, and the uninstallation will be tried again. optional bool is_uninstalling = 45; + + // Should be kept in sync with `OsIntegrationState` in web_app_constants.h. + enum OsIntegrationState { + ENABLED = 0; + DISABLED = 1; + } + + // Whether the file handling abilities of the app should be registered with + // the OS. + optional OsIntegrationState file_handler_os_integration_state = 46; }
diff --git a/chrome/browser/web_applications/test/fake_web_app_registry_controller.cc b/chrome/browser/web_applications/test/fake_web_app_registry_controller.cc index 2e11d45..38fe8fe 100644 --- a/chrome/browser/web_applications/test/fake_web_app_registry_controller.cc +++ b/chrome/browser/web_applications/test/fake_web_app_registry_controller.cc
@@ -31,8 +31,6 @@ /*protocol_handler_manager=*/nullptr, /*url_handler_manager=*/nullptr); - mutable_registrar_->SetSubsystems(os_integration_manager_.get()); - sync_bridge_ = std::make_unique<WebAppSyncBridge>( database_factory_.get(), mutable_registrar_.get(), this, mock_processor_.CreateForwardingProcessor());
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc index 4b252664..32b18d7 100644 --- a/chrome/browser/web_applications/web_app.cc +++ b/chrome/browser/web_applications/web_app.cc
@@ -42,6 +42,15 @@ } } +std::string OsIntegrationStateToString(OsIntegrationState state) { + switch (state) { + case OsIntegrationState::kEnabled: + return "kEnabled"; + case OsIntegrationState::kDisabled: + return "kDisabled"; + } +} + } // namespace WebApp::WebApp(const AppId& app_id) @@ -264,6 +273,10 @@ file_handler_approval_state_ = approval_state; } +void WebApp::SetFileHandlerOsIntegrationState(OsIntegrationState state) { + file_handler_os_integration_state_ = state; +} + void WebApp::SetShareTarget(absl::optional<apps::ShareTarget> share_target) { share_target_ = std::move(share_target); } @@ -459,6 +472,7 @@ app.client_data_.system_web_app_data, app.file_handler_permission_blocked_, app.file_handler_approval_state_, + app.file_handler_os_integration_state_, app.window_controls_overlay_enabled_, app.is_storage_isolated_, app.launch_handler_, @@ -567,6 +581,10 @@ root.SetStringKey("file_handler_approval_state", ApiApprovalStateToString(file_handler_approval_state_)); + root.SetStringKey( + "file_handler_os_integration_state", + OsIntegrationStateToString(file_handler_os_integration_state_)); + root.SetKey("file_handlers", ConvertDebugValueList(file_handlers_)); root.SetKey("manifest_icons", ConvertDebugValueList(manifest_icons_));
diff --git a/chrome/browser/web_applications/web_app.h b/chrome/browser/web_applications/web_app.h index 744dc7f9..7e94461 100644 --- a/chrome/browser/web_applications/web_app.h +++ b/chrome/browser/web_applications/web_app.h
@@ -149,6 +149,10 @@ return file_handler_approval_state_; } + OsIntegrationState file_handler_os_integration_state() const { + return file_handler_os_integration_state_; + } + const absl::optional<apps::ShareTarget>& share_target() const { return share_target_; } @@ -284,6 +288,8 @@ void SetDownloadedShortcutsMenuIconsSizes(std::vector<IconSizes> icon_sizes); void SetFileHandlers(apps::FileHandlers file_handlers); void SetFileHandlerApprovalState(ApiApprovalState approval_state); + void SetFileHandlerOsIntegrationState( + OsIntegrationState os_integration_state); void SetShareTarget(absl::optional<apps::ShareTarget> share_target); void SetAdditionalSearchTerms( std::vector<std::string> additional_search_terms); @@ -384,6 +390,11 @@ // (used when DesktopPWAsFileHandlingSettingsGated is enabled). ApiApprovalState file_handler_approval_state_ = ApiApprovalState::kRequiresPrompt; + // Tracks whether file handling has been or should be enabled at the OS level. + // This might go out of sync with actual OS integration status, as Chrome does + // not actively monitor OS registries. + OsIntegrationState file_handler_os_integration_state_ = + OsIntegrationState::kDisabled; bool window_controls_overlay_enabled_ = false; bool is_storage_isolated_ = false; absl::optional<LaunchHandler> launch_handler_;
diff --git a/chrome/browser/web_applications/web_app_constants.h b/chrome/browser/web_applications/web_app_constants.h index 0d1bb6f..126f984 100644 --- a/chrome/browser/web_applications/web_app_constants.h +++ b/chrome/browser/web_applications/web_app_constants.h
@@ -281,12 +281,22 @@ kNoUpdate = 2, }; +// Reflects the user's decision to allow or disallow an API such as File +// Handling. APIs should generally start off as kRequiresPrompt. enum class ApiApprovalState { kRequiresPrompt = 0, kAllowed = 1, kDisallowed = 2, }; +// State concerning whether a particular feature has been enabled at the OS +// level. For example, with File Handling, this indicates whether an app should +// be/has been registered with the OS to handle opening certain file types. +enum class OsIntegrationState { + kEnabled = 0, + kDisabled = 1, +}; + using LaunchHandler = blink::Manifest::LaunchHandler; // A result how `WebAppIconDownloader` processed the list of icon urls.
diff --git a/chrome/browser/web_applications/web_app_database.cc b/chrome/browser/web_applications/web_app_database.cc index 72289b9..4f9643d 100644 --- a/chrome/browser/web_applications/web_app_database.cc +++ b/chrome/browser/web_applications/web_app_database.cc
@@ -177,6 +177,26 @@ } } +OsIntegrationState ProtoToOsIntegrationState( + WebAppProto::OsIntegrationState state) { + switch (state) { + case WebAppProto_OsIntegrationState_ENABLED: + return OsIntegrationState::kEnabled; + case WebAppProto_OsIntegrationState_DISABLED: + return OsIntegrationState::kDisabled; + } +} + +WebAppProto::OsIntegrationState OsIntegrationStateToProto( + OsIntegrationState state) { + switch (state) { + case OsIntegrationState::kEnabled: + return WebAppProto_OsIntegrationState_ENABLED; + case OsIntegrationState::kDisabled: + return WebAppProto_OsIntegrationState_DISABLED; + } +} + } // anonymous namespace WebAppDatabase::WebAppDatabase(AbstractWebAppDatabaseFactory* database_factory, @@ -502,6 +522,9 @@ local_data->set_file_handler_approval_state( ApiApprovalStateToProto(web_app.file_handler_approval_state())); + local_data->set_file_handler_os_integration_state( + OsIntegrationStateToProto(web_app.file_handler_os_integration_state())); + local_data->set_window_controls_overlay_enabled( web_app.window_controls_overlay_enabled()); @@ -995,6 +1018,11 @@ ProtoToApiApprovalState(local_data.file_handler_approval_state())); } + if (local_data.has_file_handler_os_integration_state()) { + web_app->SetFileHandlerOsIntegrationState(ProtoToOsIntegrationState( + local_data.file_handler_os_integration_state())); + } + if (local_data.has_window_controls_overlay_enabled()) { web_app->SetWindowControlsOverlayEnabled( local_data.window_controls_overlay_enabled());
diff --git a/chrome/browser/web_applications/web_app_file_handler_manager.cc b/chrome/browser/web_applications/web_app_file_handler_manager.cc index 629ba65..ca8d68f 100644 --- a/chrome/browser/web_applications/web_app_file_handler_manager.cc +++ b/chrome/browser/web_applications/web_app_file_handler_manager.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/check.h" +#include "base/compiler_specific.h" #include "base/containers/contains.h" #include "base/feature_list.h" #include "base/time/time.h" @@ -14,15 +15,14 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_file_handler_registration.h" -#include "chrome/browser/web_applications/web_app_prefs_utils.h" #include "chrome/browser/web_applications/web_app_registrar.h" +#include "chrome/browser/web_applications/web_app_registry_update.h" +#include "chrome/browser/web_applications/web_app_sync_bridge.h" #include "chrome/common/chrome_features.h" #include "components/services/app_service/public/cpp/file_handler.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" -#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/features.h" -#include "third_party/blink/public/mojom/web_launch/file_handling_expiry.mojom.h" namespace web_app { @@ -41,12 +41,12 @@ WebAppFileHandlerManager::~WebAppFileHandlerManager() = default; -void WebAppFileHandlerManager::SetSubsystems(WebAppRegistrar* registrar) { - registrar_ = registrar; +void WebAppFileHandlerManager::SetSubsystems(WebAppSyncBridge* sync_bridge) { + sync_bridge_ = sync_bridge; } void WebAppFileHandlerManager::Start() { - DCHECK(registrar_); + DCHECK(sync_bridge_); if (!g_disable_automatic_file_handler_cleanup_for_testing) { content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT}) @@ -76,23 +76,24 @@ if (!IsFileHandlingAPIAvailable(app_id)) return; - UpdateBoolWebAppPref(profile_->GetPrefs(), app_id, kFileHandlersEnabled, - /*value=*/true); + SetOsIntegrationState(app_id, OsIntegrationState::kEnabled); if (!ShouldRegisterFileHandlersWithOs() || disable_os_integration_for_testing_) { return; } -// File handler registration is done via shortcuts creation on MacOS, -// WebAppShortcutManager::BuildShortcutInfoForWebApp collects file handler -// information to shortcut_info->file_handler_extensions, then used by MacOS -// implementation of |internals::CreatePlatformShortcuts|. So we avoid creating -// shortcuts twice here. -#if !defined(OS_MAC) +#if defined(OS_MAC) + // File handler registration is done via shortcuts creation on MacOS, + // WebAppShortcutManager::BuildShortcutInfoForWebApp collects file handler + // information to shortcut_info->file_handler_extensions, then used by MacOS + // implementation of |internals::CreatePlatformShortcuts|. So we avoid + // creating shortcuts twice here. + ALLOW_UNUSED_LOCAL(profile_); +#else const apps::FileHandlers* file_handlers = GetEnabledFileHandlers(app_id); if (file_handlers) { - RegisterFileHandlersWithOs(app_id, registrar_->GetAppShortName(app_id), + RegisterFileHandlersWithOs(app_id, GetRegistrar()->GetAppShortName(app_id), profile_, *file_handlers); } #endif @@ -101,10 +102,8 @@ void WebAppFileHandlerManager::DisableAndUnregisterOsFileHandlers( const AppId& app_id, ResultCallback callback) { - // Updating prefs must be done on the UI Thread. DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - UpdateBoolWebAppPref(profile_->GetPrefs(), app_id, kFileHandlersEnabled, - /*value=*/false); + SetOsIntegrationState(app_id, OsIntegrationState::kDisabled); // Temporarily allow file handlers unregistration only if an app has them. // TODO(crbug.com/1088434, crbug.com/1076688): Do not start async @@ -136,8 +135,9 @@ const apps::FileHandlers* WebAppFileHandlerManager::GetEnabledFileHandlers( const AppId& app_id) { - if (AreFileHandlersEnabled(app_id) && IsFileHandlingAPIAvailable(app_id) && - !registrar_->IsAppFileHandlerPermissionBlocked(app_id)) { + if (ShouldOsIntegrationBeEnabled(app_id) && + IsFileHandlingAPIAvailable(app_id) && + !GetRegistrar()->IsAppFileHandlerPermissionBlocked(app_id)) { return GetAllFileHandlers(app_id); } @@ -149,19 +149,14 @@ return true; // May be null in unit tests. - if (registrar_) { - const WebApp* web_app = registrar_->GetAppById(app_id); + if (GetRegistrar()) { + const WebApp* web_app = GetRegistrar()->GetAppById(app_id); return web_app && web_app->IsSystemApp(); } return false; } -bool WebAppFileHandlerManager::AreFileHandlersEnabled( - const AppId& app_id) const { - return GetBoolWebAppPref(profile_->GetPrefs(), app_id, kFileHandlersEnabled); -} - // static bool WebAppFileHandlerManager::IconsEnabled() { return g_icons_supported_by_os_override.value_or( @@ -175,8 +170,8 @@ int WebAppFileHandlerManager::CleanupAfterOriginTrials() { int cleaned_up_count = 0; - for (const AppId& app_id : registrar_->GetAppIds()) { - if (!AreFileHandlersEnabled(app_id)) + for (const AppId& app_id : GetRegistrar()->GetAppIds()) { + if (!ShouldOsIntegrationBeEnabled(app_id)) continue; if (IsFileHandlingAPIAvailable(app_id)) @@ -192,7 +187,7 @@ const apps::FileHandlers* WebAppFileHandlerManager::GetAllFileHandlers( const AppId& app_id) { - const WebApp* web_app = registrar_->GetAppById(app_id); + const WebApp* web_app = GetRegistrar()->GetAppById(app_id); return web_app && !web_app->file_handlers().empty() ? &web_app->file_handlers() : nullptr; @@ -202,7 +197,7 @@ const AppId& app_id, const std::vector<base::FilePath>& launch_files) { if (!IsFileHandlingAPIAvailable(app_id) || launch_files.empty() || - registrar_->IsAppFileHandlerPermissionBlocked(app_id)) { + GetRegistrar()->IsAppFileHandlerPermissionBlocked(app_id)) { return absl::nullopt; } @@ -237,4 +232,25 @@ return absl::nullopt; } +void WebAppFileHandlerManager::SetOsIntegrationState( + const AppId& app_id, + OsIntegrationState os_state) { + ScopedRegistryUpdate update(sync_bridge_); + update->UpdateApp(app_id)->SetFileHandlerOsIntegrationState(os_state); +} + +bool WebAppFileHandlerManager::ShouldOsIntegrationBeEnabled( + const AppId& app_id) const { + if (!GetRegistrar()) + return false; + + const WebApp* web_app = GetRegistrar()->GetAppById(app_id); + return web_app && web_app->file_handler_os_integration_state() == + OsIntegrationState::kEnabled; +} + +const WebAppRegistrar* WebAppFileHandlerManager::GetRegistrar() const { + return sync_bridge_ ? &sync_bridge_->registrar() : nullptr; +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_file_handler_manager.h b/chrome/browser/web_applications/web_app_file_handler_manager.h index a0baf81..6b0aead 100644 --- a/chrome/browser/web_applications/web_app_file_handler_manager.h +++ b/chrome/browser/web_applications/web_app_file_handler_manager.h
@@ -21,6 +21,7 @@ namespace web_app { class WebAppRegistrar; +class WebAppSyncBridge; class WebAppFileHandlerManager { public: @@ -29,8 +30,7 @@ WebAppFileHandlerManager& operator=(const WebAppFileHandlerManager&) = delete; virtual ~WebAppFileHandlerManager(); - // |registrar| is used to observe OnWebAppInstalled/Uninstalled events. - void SetSubsystems(WebAppRegistrar* registrar); + void SetSubsystems(WebAppSyncBridge* sync_bridge); void Start(); // Disables OS integrations, such as shortcut creation on Linux or modifying @@ -80,9 +80,6 @@ // FileHandlingAPI flag is enabled. bool IsFileHandlingAPIAvailable(const AppId& app_id); - // Indicates whether file handlers have been registered for an app. - bool AreFileHandlersEnabled(const AppId& app_id) const; - // Returns true when the system supports file type association icons. static bool IconsEnabled(); @@ -99,11 +96,24 @@ // handlers unregistered, for use in tests. int CleanupAfterOriginTrials(); + // Sets whether `app_id` should have its File Handling abilities surfaces in + // the OS. In theory, this should match the actual OS integration state (e.g. + // the contents of the .desktop file on Linux), however, that's only enforced + // on a best-effort basis. + void SetOsIntegrationState(const AppId& app_id, OsIntegrationState os_state); + + // Indicates whether file handlers should be OS-registered for an app. As with + // `SetOsIntegrationState()`, there may be a mismatch with the actual OS + // registry. + bool ShouldOsIntegrationBeEnabled(const AppId& app_id) const; + + const WebAppRegistrar* GetRegistrar() const; + static bool disable_automatic_file_handler_cleanup_for_testing_; bool disable_os_integration_for_testing_ = false; Profile* const profile_; - WebAppRegistrar* registrar_ = nullptr; + WebAppSyncBridge* sync_bridge_ = nullptr; base::WeakPtrFactory<WebAppFileHandlerManager> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/web_applications/web_app_file_handler_manager_unittest.cc b/chrome/browser/web_applications/web_app_file_handler_manager_unittest.cc index 2db4607..b0b399e 100644 --- a/chrome/browser/web_applications/web_app_file_handler_manager_unittest.cc +++ b/chrome/browser/web_applications/web_app_file_handler_manager_unittest.cc
@@ -13,7 +13,7 @@ #include "chrome/browser/web_applications/test/fake_web_app_file_handler_manager.h" #include "chrome/browser/web_applications/test/fake_web_app_registry_controller.h" #include "chrome/browser/web_applications/test/web_app_test.h" -#include "chrome/browser/web_applications/web_app_registrar.h" +#include "chrome/browser/web_applications/test/web_app_test_utils.h" #include "components/services/app_service/public/cpp/file_handler.h" #include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gtest/include/gtest/gtest.h" @@ -171,9 +171,13 @@ file_handler_manager_ = std::make_unique<FakeWebAppFileHandlerManager>(profile()); - file_handler_manager_->SetSubsystems(&app_registrar()); + file_handler_manager_->SetSubsystems(&controller().sync_bridge()); controller().Init(); + + auto web_app = test::CreateWebApp(); + app_id_ = web_app->app_id(); + controller().RegisterApp(std::move(web_app)); } FakeWebAppFileHandlerManager& file_handler_manager() { @@ -184,24 +188,23 @@ return *fake_registry_controller_; } - WebAppRegistrar& app_registrar() { return controller().registrar(); } + const AppId& app_id() const { return app_id_; } private: std::unique_ptr<FakeWebAppRegistryController> fake_registry_controller_; std::unique_ptr<FakeWebAppFileHandlerManager> file_handler_manager_; base::test::ScopedFeatureList features_; + AppId app_id_; }; TEST_F(WebAppFileHandlerManagerTest, FileHandlersAreNotAvailableUnlessEnabled) { - const AppId app_id = "app-id"; - - file_handler_manager().InstallFileHandler(app_id, + file_handler_manager().InstallFileHandler(app_id(), GURL("https://app.site/handle-foo"), {{"application/foo", {".foo"}}}, /*enable=*/false); - file_handler_manager().InstallFileHandler(app_id, + file_handler_manager().InstallFileHandler(app_id(), GURL("https://app.site/handle-bar"), {{"application/bar", {".bar"}}}, /*enable=*/false); @@ -209,147 +212,136 @@ // File handlers are disabled by default. { const auto* handlers = - file_handler_manager().GetEnabledFileHandlers(app_id); + file_handler_manager().GetEnabledFileHandlers(app_id()); EXPECT_EQ(nullptr, handlers); } // Ensure they can be enabled. - file_handler_manager().EnableAndRegisterOsFileHandlers(app_id); + file_handler_manager().EnableAndRegisterOsFileHandlers(app_id()); { const auto* handlers = - file_handler_manager().GetEnabledFileHandlers(app_id); + file_handler_manager().GetEnabledFileHandlers(app_id()); EXPECT_EQ(2u, handlers->size()); } // Ensure they can be disabled. - file_handler_manager().DisableAndUnregisterOsFileHandlers(app_id, + file_handler_manager().DisableAndUnregisterOsFileHandlers(app_id(), base::DoNothing()); { const auto* handlers = - file_handler_manager().GetEnabledFileHandlers(app_id); + file_handler_manager().GetEnabledFileHandlers(app_id()); EXPECT_EQ(nullptr, handlers); } } TEST_F(WebAppFileHandlerManagerTest, NoHandlersRegistered) { - const AppId app_id = "app-id"; - // Returns nullopt when no file handlers are registered. const base::FilePath path(FILE_PATH_LITERAL("file.foo")); EXPECT_EQ(absl::nullopt, - file_handler_manager().GetMatchingFileHandlerURL(app_id, {path})); + file_handler_manager().GetMatchingFileHandlerURL(app_id(), {path})); } TEST_F(WebAppFileHandlerManagerTest, NoLaunchFilesPassed) { - const AppId app_id = "app-id"; - - file_handler_manager().InstallFileHandler(app_id, + file_handler_manager().InstallFileHandler(app_id(), GURL("https://app.site/handle-foo"), {{"application/foo", {".foo"}}}); // Returns nullopt when no launch files are passed. EXPECT_EQ(absl::nullopt, - file_handler_manager().GetMatchingFileHandlerURL(app_id, {})); + file_handler_manager().GetMatchingFileHandlerURL(app_id(), {})); } TEST_F(WebAppFileHandlerManagerTest, SingleValidExtensionSingleExtensionHandler) { - const AppId app_id = "app-id"; const GURL url("https://app.site/handle-foo"); - file_handler_manager().InstallFileHandler(app_id, url, + file_handler_manager().InstallFileHandler(app_id(), url, {{"application/foo", {".foo"}}}); // Matches on single valid extension. const base::FilePath path(FILE_PATH_LITERAL("file.foo")); EXPECT_EQ(url, - file_handler_manager().GetMatchingFileHandlerURL(app_id, {path})); + file_handler_manager().GetMatchingFileHandlerURL(app_id(), {path})); } TEST_F(WebAppFileHandlerManagerTest, SingleInvalidExtensionSingleExtensionHandler) { - const AppId app_id = "app-id"; const GURL url("https://app.site/handle-foo"); - file_handler_manager().InstallFileHandler(app_id, url, + file_handler_manager().InstallFileHandler(app_id(), url, {{"application/foo", {".foo"}}}); // Returns nullopt on single invalid extension. const base::FilePath path(FILE_PATH_LITERAL("file.bar")); EXPECT_EQ(absl::nullopt, - file_handler_manager().GetMatchingFileHandlerURL(app_id, {path})); + file_handler_manager().GetMatchingFileHandlerURL(app_id(), {path})); } TEST_F(WebAppFileHandlerManagerTest, SingleValidExtensionMultiExtensionHandler) { - const AppId app_id = "app-id"; const GURL url("https://app.site/handle-foo"); file_handler_manager().InstallFileHandler( - app_id, GURL("https://app.site/handle-foo"), + app_id(), GURL("https://app.site/handle-foo"), {{"application/foo", {".foo"}}, {"application/bar", {".bar"}}}); // Matches on single valid extension for multi-extension handler. const base::FilePath path(FILE_PATH_LITERAL("file.foo")); EXPECT_EQ(url, - file_handler_manager().GetMatchingFileHandlerURL(app_id, {path})); + file_handler_manager().GetMatchingFileHandlerURL(app_id(), {path})); } TEST_F(WebAppFileHandlerManagerTest, MultipleValidExtensions) { - const AppId app_id = "app-id"; const GURL url("https://app.site/handle-foo"); file_handler_manager().InstallFileHandler( - app_id, GURL("https://app.site/handle-foo"), + app_id(), GURL("https://app.site/handle-foo"), {{"application/foo", {".foo"}}, {"application/bar", {".bar"}}}); // Matches on multiple valid extensions for multi-extension handler. const base::FilePath path1(FILE_PATH_LITERAL("file.foo")); const base::FilePath path2(FILE_PATH_LITERAL("file.bar")); EXPECT_EQ(url, file_handler_manager().GetMatchingFileHandlerURL( - app_id, {path1, path2})); + app_id(), {path1, path2})); } TEST_F(WebAppFileHandlerManagerTest, PartialExtensionMatch) { - const AppId app_id = "app-id"; const GURL url("https://app.site/handle-foo"); - file_handler_manager().InstallFileHandler(app_id, url, + file_handler_manager().InstallFileHandler(app_id(), url, {{"application/foo", {".foo"}}}); // Returns nullopt on partial extension match. const base::FilePath path1(FILE_PATH_LITERAL("file.foo")); const base::FilePath path2(FILE_PATH_LITERAL("file.bar")); EXPECT_EQ(absl::nullopt, file_handler_manager().GetMatchingFileHandlerURL( - app_id, {path1, path2})); + app_id(), {path1, path2})); } TEST_F(WebAppFileHandlerManagerTest, SingleFileWithoutExtension) { - const AppId app_id = "app-id"; const GURL url("https://app.site/handle-foo"); - file_handler_manager().InstallFileHandler(app_id, url, + file_handler_manager().InstallFileHandler(app_id(), url, {{"application/foo", {".foo"}}}); // Returns nullopt where a file has no extension. const base::FilePath path(FILE_PATH_LITERAL("file")); EXPECT_EQ(absl::nullopt, - file_handler_manager().GetMatchingFileHandlerURL(app_id, {path})); + file_handler_manager().GetMatchingFileHandlerURL(app_id(), {path})); } TEST_F(WebAppFileHandlerManagerTest, FileWithoutExtensionAmongMultipleFiles) { - const AppId app_id = "app-id"; const GURL url("https://app.site/handle-foo"); - file_handler_manager().InstallFileHandler(app_id, url, + file_handler_manager().InstallFileHandler(app_id(), url, {{"application/foo", {".foo"}}}); // Returns nullopt where one file has no extension while others do. const base::FilePath path1(FILE_PATH_LITERAL("file")); const base::FilePath path2(FILE_PATH_LITERAL("file.foo")); EXPECT_EQ(absl::nullopt, file_handler_manager().GetMatchingFileHandlerURL( - app_id, {path1, path2})); + app_id(), {path1, path2})); } } // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_prefs_utils.cc b/chrome/browser/web_applications/web_app_prefs_utils.cc index 62e3ede..dbcfee0 100644 --- a/chrome/browser/web_applications/web_app_prefs_utils.cc +++ b/chrome/browser/web_applications/web_app_prefs_utils.cc
@@ -66,11 +66,9 @@ // "web_app_ids": { // "<app_id_1>": { // "was_external_app_uninstalled_by_user": true, -// "file_handlers_enabled": true, // A double representing the number of seconds since epoch, in local time. // Convert from/to using base::Time::FromDoubleT() and // base::Time::ToDoubleT(). -// "file_handling_origin_trial_expiry_time": 1580475600000, // "IPH_num_of_consecutive_ignore": 2, // A string-flavored base::value representing the int64_t number of // microseconds since the Windows epoch, using base::TimeToValue(). @@ -78,8 +76,6 @@ // }, // "<app_id_N>": { // "was_external_app_uninstalled_by_user": false, -// "file_handlers_enabled": false, -// "file_handling_origin_trial_expiry_time": 0 // } // }, // "app_agnostic_iph_state": { @@ -99,11 +95,6 @@ const char kWasExternalAppUninstalledByUser[] = "was_external_app_uninstalled_by_user"; -const char kFileHandlersEnabled[] = "file_handlers_enabled"; - -const char kFileHandlingOriginTrialExpiryTime[] = - "file_handling_origin_trial_expiry_time"; - const char kLatestWebAppInstallSource[] = "latest_web_app_install_source"; const char kIphIgnoreCount[] = "IPH_num_of_consecutive_ignore";
diff --git a/chrome/browser/web_applications/web_app_prefs_utils.h b/chrome/browser/web_applications/web_app_prefs_utils.h index 965e69c..ec7445f 100644 --- a/chrome/browser/web_applications/web_app_prefs_utils.h +++ b/chrome/browser/web_applications/web_app_prefs_utils.h
@@ -20,10 +20,6 @@ extern const char kWasExternalAppUninstalledByUser[]; -extern const char kFileHandlingOriginTrialExpiryTime[]; - -extern const char kFileHandlersEnabled[]; - extern const char kLatestWebAppInstallSource[]; extern const char kIphIgnoreCount[];
diff --git a/chrome/browser/web_applications/web_app_provider.cc b/chrome/browser/web_applications/web_app_provider.cc index 8f77051..7c3c5462 100644 --- a/chrome/browser/web_applications/web_app_provider.cc +++ b/chrome/browser/web_applications/web_app_provider.cc
@@ -321,9 +321,9 @@ system_web_app_manager_.get(), os_integration_manager_.get()); ui_manager_->SetSubsystems(sync_bridge_.get(), os_integration_manager_.get()); - os_integration_manager_->SetSubsystems(registrar_.get(), ui_manager_.get(), + os_integration_manager_->SetSubsystems(sync_bridge_.get(), registrar_.get(), + ui_manager_.get(), icon_manager_.get()); - registrar_->SetSubsystems(os_integration_manager_.get()); connected_ = true; }
diff --git a/chrome/browser/web_applications/web_app_registrar.cc b/chrome/browser/web_applications/web_app_registrar.cc index 49cbb8d9..bda7469f3 100644 --- a/chrome/browser/web_applications/web_app_registrar.cc +++ b/chrome/browser/web_applications/web_app_registrar.cc
@@ -21,7 +21,6 @@ #include "chrome/browser/web_applications/app_registrar_observer.h" #include "chrome/browser/web_applications/externally_installed_web_app_prefs.h" #include "chrome/browser/web_applications/install_bounce_metric.h" -#include "chrome/browser/web_applications/os_integration_manager.h" #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_prefs_utils.h" @@ -55,11 +54,6 @@ observer.OnAppRegistrarDestroyed(); } -void WebAppRegistrar::SetSubsystems( - OsIntegrationManager* os_integration_manager) { - os_integration_manager_ = os_integration_manager; -} - bool WebAppRegistrar::IsLocallyInstalled(const GURL& start_url) const { return IsLocallyInstalled( GenerateAppId(/*manifest_id=*/absl::nullopt, start_url)); @@ -706,12 +700,7 @@ } std::vector<AppId> WebAppRegistrar::GetAppIds() const { - std::vector<AppId> app_ids; - - for (const WebApp& app : GetApps()) - app_ids.push_back(app.app_id()); - - return app_ids; + return GetAppIdsForAppSet(GetApps()); } RunOnOsLoginMode WebAppRegistrar::GetAppRunOnOsLoginMode( @@ -731,10 +720,8 @@ if (profile() != profile_to_be_deleted) return; - for (const auto& app : GetAppsIncludingStubs()) { - NotifyWebAppProfileWillBeDeleted(app.app_id()); - os_integration_manager().UninstallAllOsHooks(app.app_id(), - base::DoNothing()); + for (const AppId& app_id : GetAppIdsForAppSet(GetAppsIncludingStubs())) { + NotifyWebAppProfileWillBeDeleted(app_id); } // We can't do registry_.clear() here because it makes in-memory registry // diverged from the sync server registry and from the on-disk registry @@ -862,4 +849,14 @@ return true; } +std::vector<AppId> WebAppRegistrar::GetAppIdsForAppSet( + const AppSet& app_set) const { + std::vector<AppId> app_ids; + + for (const WebApp& app : app_set) + app_ids.push_back(app.app_id()); + + return app_ids; +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_registrar.h b/chrome/browser/web_applications/web_app_registrar.h index 796da4c..234804779 100644 --- a/chrome/browser/web_applications/web_app_registrar.h +++ b/chrome/browser/web_applications/web_app_registrar.h
@@ -30,7 +30,6 @@ class AppRegistrarObserver; class WebApp; -class OsIntegrationManager; using Registry = std::map<AppId, std::unique_ptr<WebApp>>; @@ -186,10 +185,9 @@ bool GetWindowControlsOverlayEnabled(const AppId& app_id) const; + // Gets the IDs for all apps in `GetApps()`. std::vector<AppId> GetAppIds() const; - void SetSubsystems(OsIntegrationManager* os_integration_manager); - // Returns the "scope" field from the app manifest, or infers a scope from the // "start_url" field if unavailable. Returns an invalid GURL iff the |app_id| // does not refer to an installed web app. @@ -356,9 +354,6 @@ protected: Profile* profile() const { return profile_; } - OsIntegrationManager& os_integration_manager() { - return *os_integration_manager_; - } void NotifyWebAppProfileWillBeDeleted(const AppId& app_id); void NotifyAppRegistrarShutdown(); @@ -370,13 +365,15 @@ void CountMutation(); + // Gets the IDs for all apps in `app_set`. + std::vector<AppId> GetAppIdsForAppSet(const AppSet& app_set) const; + bool registry_profile_being_deleted_ = false; private: Profile* const profile_; base::ObserverList<AppRegistrarObserver, /*check_empty=*/true> observers_; - OsIntegrationManager* os_integration_manager_ = nullptr; Registry registry_; #if DCHECK_IS_ON()
diff --git a/chrome/browser/web_applications/web_app_unittest.cc b/chrome/browser/web_applications/web_app_unittest.cc index b28fd5f..4f9a7ba 100644 --- a/chrome/browser/web_applications/web_app_unittest.cc +++ b/chrome/browser/web_applications/web_app_unittest.cc
@@ -177,6 +177,7 @@ }, "downloaded_shortcuts_menu_icons_sizes": [ ], "file_handler_approval_state": "kRequiresPrompt", + "file_handler_os_integration_state": "kDisabled", "file_handler_permission_blocked": false, "file_handlers": [ ], "manifest_icons": [ ], @@ -265,6 +266,7 @@ "index": 2 } ], "file_handler_approval_state": "kRequiresPrompt", + "file_handler_os_integration_state": "kDisabled", "file_handler_permission_blocked": false, "file_handlers": [ { "accept": [ {
diff --git a/chrome/browser/webapps/android/java/res/layout/pwa_install_bottom_sheet_content.xml b/chrome/browser/webapps/android/java/res/layout/pwa_install_bottom_sheet_content.xml index e7142c8..a0fe749 100644 --- a/chrome/browser/webapps/android/java/res/layout/pwa_install_bottom_sheet_content.xml +++ b/chrome/browser/webapps/android/java/res/layout/pwa_install_bottom_sheet_content.xml
@@ -11,7 +11,7 @@ <View style="@style/HorizontalDivider" android:layout_width="match_parent" - android:background="@color/divider_line_bg_color" + android:background="@macro/divider_line_bg_color" android:layout_marginTop="70dp" android:importantForAccessibility="no" />
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 7510e95f3e..998b805 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1637063387-2975184b243a95e39ddab06ffd4fa5dc400be18f.profdata +chrome-linux-main-1637125894-8e44059925c47c7147c8c1f75c9ef64c0f9c6dba.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index cf2f301..2202eec 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1637063387-c42cbee909f6b34253c40acdf4c6eeaa1a1b3e13.profdata +chrome-mac-main-1637125894-14fe3dc732aac13b9a199d86bfc9d82ae270fe8f.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 00ab96d..ce9c3773 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1637074636-8db46d7eb2f5b89ae853edea2cb192612c5f0167.profdata +chrome-win32-main-1637125894-1c7f7d1d6b41d0722150a391d89b93aaa1fc3242.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 24eed31..924b9b9e 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1637074636-6b915636f94693ceb768b371d55ad5f5ed05a90d.profdata +chrome-win64-main-1637106848-f053e72fa2e633bee04a471f279c84cccb477197.profdata
diff --git a/chrome/common/extensions/api/scripting.idl b/chrome/common/extensions/api/scripting.idl index 3b7abceb..172d2a30 100644 --- a/chrome/common/extensions/api/scripting.idl +++ b/chrome/common/extensions/api/scripting.idl
@@ -161,7 +161,9 @@ interface Functions { // Injects a script into a target context. The script will be run at - // <code>document_idle</code>. + // <code>document_idle</code>. If the script evaluates to a promise, + // the browser will wait for the promise to settle and return the + // resulting value. // |injection|: The details of the script which to inject. // |callback|: Invoked upon completion of the injection. The resulting // array contains the result of execution for each frame where the
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index 0b3a80b..508f4ca 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc
@@ -115,7 +115,6 @@ const char kGoogleSpeechSynthesisExtensionId[] = "gjjabgpgjpampikjhjpfhneeoapjbjaf"; const char kWallpaperManagerId[] = "obklkkbkpaoaejdabbfldmcfplpdgolj"; -const char kCameraAppPath[] = "chromeos/camera"; #endif // BUILDFLAG(IS_CHROMEOS_ASH) const char kAppStateNotInstalled[] = "not_installed";
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index 3ae7cb2..81e5b43 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h
@@ -219,8 +219,6 @@ extern const char kEspeakSpeechSynthesisExtensionId[]; // The extension id of the wallpaper manager application. extern const char kWallpaperManagerId[]; -// Path to preinstalled Chrome camera app. -extern const char kCameraAppPath[]; #endif // What causes an extension to be installed? Used in histograms, so don't
diff --git a/chrome/common/extensions/extension_unittest.cc b/chrome/common/extensions/extension_unittest.cc index c9ee69cc..4037baa 100644 --- a/chrome/common/extensions/extension_unittest.cc +++ b/chrome/common/extensions/extension_unittest.cc
@@ -439,11 +439,7 @@ LoadManifest("app", "manifest.json", Extension::FROM_WEBSTORE); EXPECT_TRUE(extension->from_webstore()); - extension = LoadManifest("app", "manifest.json", Extension::FROM_BOOKMARK); - EXPECT_TRUE(extension->from_bookmark()); - extension = LoadManifest("app", "manifest.json", Extension::NO_FLAGS); - EXPECT_FALSE(extension->from_bookmark()); EXPECT_FALSE(extension->from_webstore()); }
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 27fd89f7..68f00f7 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -40,12 +40,14 @@ const char kChromeUIChromeURLsHost[] = "chrome-urls"; const char kChromeUIChromeURLsURL[] = "chrome://chrome-urls/"; const char kChromeUIComponentsHost[] = "components"; +const char kChromeUIComponentsUrl[] = "chrome://components"; const char kChromeUIConflictsHost[] = "conflicts"; const char kChromeUIConstrainedHTMLTestURL[] = "chrome://constrained-test/"; const char kChromeUIContentSettingsURL[] = "chrome://settings/content"; const char kChromeUICookieSettingsURL[] = "chrome://settings/cookies"; const char kChromeUICrashHost[] = "crash"; const char kChromeUICrashesHost[] = "crashes"; +const char kChromeUICrashesUrl[] = "chrome://crashes"; const char kChromeUICreditsHost[] = "credits"; const char kChromeUICreditsURL[] = "chrome://credits/"; const char kChromeUIDefaultHost[] = "version"; @@ -58,6 +60,7 @@ const char kChromeUIDevToolsURL[] = "devtools://devtools/bundled/inspector.html"; const char kChromeUIDeviceLogHost[] = "device-log"; +const char kChromeUIDeviceLogUrl[] = "chrome://device-log"; const char kChromeUIDevUiLoaderURL[] = "chrome://dev-ui-loader/"; const char kChromeUIDiceWebSigninInterceptHost[] = "signin-dice-web-intercept"; const char kChromeUIDiceWebSigninInterceptURL[] = @@ -68,6 +71,7 @@ const char kChromeUIDownloadsHost[] = "downloads"; const char kChromeUIDownloadsURL[] = "chrome://downloads/"; const char kChromeUIDriveInternalsHost[] = "drive-internals"; +const char kChromeUIDriveInternalsUrl[] = "chrome://drive-internals"; const char kChromeUIEDUCoexistenceLoginURLV2[] = "chrome://chrome-signin/edu-coexistence"; const char kChromeUIEnterpriseCastingHost[] = "enterprise-casting"; @@ -110,6 +114,7 @@ const char kChromeUIInterstitialHost[] = "interstitials"; const char kChromeUIInterstitialURL[] = "chrome://interstitials/"; const char kChromeUIInvalidationsHost[] = "invalidations"; +const char kChromeUIInvalidationsUrl[] = "chrome://invalidations"; const char kChromeUIKillHost[] = "kill"; const char kChromeUILauncherInternalsHost[] = "launcher-internals"; const char kChromeUILocalStateHost[] = "local-state"; @@ -162,6 +167,7 @@ const char kChromeUISettingsHost[] = "settings"; const char kChromeUISettingsURL[] = "chrome://settings/"; const char kChromeUISignInInternalsHost[] = "signin-internals"; +const char kChromeUISignInInternalsUrl[] = "chrome://signin-internals"; const char kChromeUISigninEmailConfirmationHost[] = "signin-email-confirmation"; const char kChromeUISigninEmailConfirmationURL[] = "chrome://signin-email-confirmation"; @@ -182,6 +188,7 @@ const char kChromeUISyncFileSystemInternalsHost[] = "syncfs-internals"; const char kChromeUISyncHost[] = "sync"; const char kChromeUISyncInternalsHost[] = "sync-internals"; +const char kChromeUISyncInternalsUrl[] = "chrome://sync-internals"; const char kChromeUISystemInfoHost[] = "system"; const char kChromeUITermsHost[] = "terms"; const char kChromeUITermsURL[] = "chrome://terms/"; @@ -233,6 +240,11 @@ const char kCfmNetworkSettingsURL[] = "chrome://cfm-network-settings"; #endif // BUILDFLAG(PLATFORM_CFM) +#if defined(OS_CHROMEOS) +const char kChromeUIGpuURL[] = "chrome://gpu"; +const char kChromeUIHistogramsURL[] = "chrome://histograms"; +#endif + #if BUILDFLAG(IS_CHROMEOS_ASH) // Keep alphabetized. const char kChromeUIAccountManagerErrorHost[] = "account-manager-error"; @@ -269,6 +281,7 @@ const char kChromeUICrostiniUpgraderHost[] = "crostini-upgrader"; const char kChromeUICrostiniUpgraderUrl[] = "chrome://crostini-upgrader"; const char kChromeUICryptohomeHost[] = "cryptohome"; +const char kChromeUICryptohomeURL[] = "chrome://cryptohome"; const char kChromeUIDeviceEmulatorHost[] = "device-emulator"; const char kChromeUIDiagnosticsAppURL[] = "chrome://diagnostics"; const char kChromeUIIntenetConfigDialogURL[] = @@ -289,6 +302,7 @@ const char kChromeUIMultiDeviceSetupHost[] = "multidevice-setup"; const char kChromeUIMultiDeviceSetupUrl[] = "chrome://multidevice-setup"; const char kChromeUINetworkHost[] = "network"; +const char kChromeUINetworkUrl[] = "chrome://network"; const char kChromeUIOSCreditsHost[] = "os-credits"; const char kChromeUIOSCreditsURL[] = "chrome://os-credits/"; const char kChromeUIOobeHost[] = "oobe"; @@ -299,6 +313,7 @@ const char kChromeUIPasswordChangeUrl[] = "chrome://password-change"; const char kChromeUIPrintManagementUrl[] = "chrome://print-management"; const char kChromeUIPowerHost[] = "power"; +const char kChromeUIPowerUrl[] = "chrome://power"; const char kChromeUIProjectorHost[] = "projector"; const char kChromeUIProjectorURL[] = "chrome://projector/"; const char kChromeUIScanningAppURL[] = "chrome://scanning"; @@ -314,12 +329,14 @@ const char kChromeUISmbCredentialsHost[] = "smb-credentials-dialog"; const char kChromeUISmbCredentialsURL[] = "chrome://smb-credentials-dialog/"; const char kChromeUISysInternalsHost[] = "sys-internals"; +const char kChromeUISysInternalsUrl[] = "chrome://sys-internals"; const char kChromeUIUntrustedCroshURL[] = "chrome-untrusted://crosh/"; const char kChromeUIUntrustedTerminalHost[] = "terminal"; const char kChromeUIUntrustedTerminalURL[] = "chrome-untrusted://terminal/"; const char kChromeUIUserImageHost[] = "userimage"; const char kChromeUIUserImageURL[] = "chrome://userimage/"; const char kChromeUIVmHost[] = "vm"; +const char kChromeUIVmUrl[] = "chrome://vm"; const char kChromeUIEmojiPickerURL[] = "chrome://emoji-picker/"; const char kChromeUIEmojiPickerHost[] = "emoji-picker"; @@ -327,6 +344,60 @@ "urgent-password-expiry-notification"; const char kChromeUIUrgentPasswordExpiryNotificationUrl[] = "chrome://urgent-password-expiry-notification/"; + +const char kOsUICroshURL[] = "os://crosh"; +const char kOsUIFileManagerURL[] = "os://file-manager"; +const char kOsUITerminalURL[] = "os://terminal"; +const char kOsUIAccountManagerErrorURL[] = "os://account-manager-error"; +const char kOsUIAccountManagerWelcomeURL[] = "os://account-manager-welcome"; +const char kOsUIAccountMigrationWelcomeURL[] = "os://account-migration-welcome"; +const char kOsUIAddSupervisionURL[] = "os://add-supervision"; +const char kOsUIAppDisabledURL[] = "os://app-disabled"; +const char kOsUIArcGraphicsTracingURL[] = "os://arc-graphics-tracing"; +const char kOsUIArcOverviewTracingURL[] = "os://arc-overview-tracing"; +const char kOsUIArcPowerControlURL[] = "os://arc-power-control"; +const char kOsUIAssistantOptInURL[] = "os://assistant-optin"; +const char kOsUIBluetoothPairingURL[] = "os://bluetooth-pairing"; +const char kOsUIComponentsUrl[] = "os://components"; +const char kOsUICrashesUrl[] = "os://crashes"; +const char kOsUICreditsURL[] = "os://credits"; +const char kOsUICrostiniCreditsURL[] = "os://crostini-credits"; +const char kOsUICrostiniInstallerUrl[] = "os://crostini-installer"; +const char kOsUICrostiniUpgraderUrl[] = "os://crostini-upgrader"; +const char kOsUICryptohomeURL[] = "os://cryptohome"; +const char kOsUIDeviceLogUrl[] = "os://device-log"; +const char kOsUIDiagnosticsAppURL[] = "os://diagnostics"; +const char kOsUIDriveInternalsUrl[] = "os://drive-internals"; +const char kOsUIEmojiPickerURL[] = "os://emoji-picker"; +const char kOsUIFlagsURL[] = "os://flags"; +const char kOsUIGpuURL[] = "os://gpu"; +const char kOsUIHistogramsURL[] = "os://histograms"; +const char kOsUIIntenetConfigDialogURL[] = "os://internet-config-dialog"; +const char kOsUIIntenetDetailDialogURL[] = "os://internet-detail-dialog"; +const char kOsUIInvalidationsUrl[] = "os://invalidations"; +const char kOsUILockScreenNetworkURL[] = "os://lock-network"; +const char kOsUILockScreenStartReauthURL[] = "os://lock-reauth"; +const char kOsUIMobileSetupURL[] = "os://mobilesetup"; +const char kOsUIMultiDeviceSetupUrl[] = "os://multidevice-setup"; +const char kOsUINetworkUrl[] = "os://network"; +const char kOsUIOSCreditsURL[] = "os://os-credits"; +const char kOsUIOSSettingsURL[] = "os://os-settings"; +const char kOsUIPowerUrl[] = "os://power"; +const char kOsUIPrintManagementUrl[] = "os://print-management"; +const char kOsUIRestartURL[] = "os://restart"; +const char kOsUIScanningAppURL[] = "os://scanning"; +const char kOsUISetTimeURL[] = "os://set-time"; +const char kOsUISettingsURL[] = "os://settings"; +const char kOsUISignInInternalsUrl[] = "os://signin-internals"; +const char kOsUISlowURL[] = "os://slow"; +const char kOsUISmbCredentialsURL[] = "os://smb-credentials-dialog"; +const char kOsUISmbShareURL[] = "os://smb-share-dialog"; +const char kOsUISyncInternalsUrl[] = "os://sync-internals"; +const char kOsUISysInternalsUrl[] = "os://sys-internals"; +const char kOsUIUserImageURL[] = "os://userimage"; +const char kOsUIVersionURL[] = "os://version"; +const char kOsUIVmUrl[] = "os://vm"; + // Keep alphabetized. bool IsSystemWebUIHost(base::StringPiece host) {
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index def804a..ef37bcd 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -47,11 +47,13 @@ extern const char kChromeUIChromeURLsHost[]; extern const char kChromeUIChromeURLsURL[]; extern const char kChromeUIComponentsHost[]; +extern const char kChromeUIComponentsUrl[]; extern const char kChromeUIConflictsHost[]; extern const char kChromeUIConstrainedHTMLTestURL[]; extern const char kChromeUIContentSettingsURL[]; extern const char kChromeUICookieSettingsURL[]; extern const char kChromeUICrashHost[]; +extern const char kChromeUICrashesUrl[]; extern const char kChromeUICrashesHost[]; extern const char kChromeUICreditsHost[]; extern const char kChromeUICreditsURL[]; @@ -64,6 +66,7 @@ extern const char kChromeUIDevToolsRemotePath[]; extern const char kChromeUIDevToolsURL[]; extern const char kChromeUIDeviceLogHost[]; +extern const char kChromeUIDeviceLogUrl[]; extern const char kChromeUIDevUiLoaderURL[]; extern const char kChromeUIDiceWebSigninInterceptHost[]; extern const char kChromeUIDiceWebSigninInterceptURL[]; @@ -72,6 +75,7 @@ extern const char kChromeUIDownloadsHost[]; extern const char kChromeUIDownloadsURL[]; extern const char kChromeUIDriveInternalsHost[]; +extern const char kChromeUIDriveInternalsUrl[]; extern const char kChromeUIEDUCoexistenceLoginURLV2[]; extern const char kChromeUIEnterpriseCastingHost[]; extern const char kChromeUIEnterpriseCastingURL[]; @@ -112,6 +116,7 @@ extern const char kChromeUIInterstitialHost[]; extern const char kChromeUIInterstitialURL[]; extern const char kChromeUIInvalidationsHost[]; +extern const char kChromeUIInvalidationsUrl[]; extern const char kChromeUIKillHost[]; extern const char kChromeUILauncherInternalsHost[]; extern const char kChromeUILocalStateHost[]; @@ -163,6 +168,7 @@ extern const char kChromeUISettingsHost[]; extern const char kChromeUISettingsURL[]; extern const char kChromeUISignInInternalsHost[]; +extern const char kChromeUISignInInternalsUrl[]; extern const char kChromeUISigninEmailConfirmationHost[]; extern const char kChromeUISigninEmailConfirmationURL[]; extern const char kChromeUISigninErrorHost[]; @@ -180,6 +186,7 @@ extern const char kChromeUISyncFileSystemInternalsHost[]; extern const char kChromeUISyncHost[]; extern const char kChromeUISyncInternalsHost[]; +extern const char kChromeUISyncInternalsUrl[]; extern const char kChromeUISystemInfoHost[]; extern const char kChromeUITermsHost[]; extern const char kChromeUITermsURL[]; @@ -223,6 +230,11 @@ extern const char kChromeUIWebAppInternalsHost[]; #endif // defined(OS_ANDROID) +#if defined(OS_CHROMEOS) +extern const char kChromeUIGpuURL[]; +extern const char kChromeUIHistogramsURL[]; +#endif + #if BUILDFLAG(IS_CHROMEOS_ASH) // NOTE: If you add a URL/host please check if it should be added to // IsSystemWebUIHost(). @@ -257,6 +269,7 @@ extern const char kChromeUICrostiniUpgraderHost[]; extern const char kChromeUICrostiniUpgraderUrl[]; extern const char kChromeUICryptohomeHost[]; +extern const char kChromeUICryptohomeURL[]; extern const char kChromeUIDeviceEmulatorHost[]; extern const char kChromeUIDiagnosticsAppURL[]; extern const char kChromeUIEmojiPickerURL[]; @@ -277,6 +290,7 @@ extern const char kChromeUIMultiDeviceSetupHost[]; extern const char kChromeUIMultiDeviceSetupUrl[]; extern const char kChromeUINetworkHost[]; +extern const char kChromeUINetworkUrl[]; extern const char kChromeUIOSCreditsHost[]; extern const char kChromeUIOSCreditsURL[]; extern const char kChromeUIOobeHost[]; @@ -287,6 +301,7 @@ extern const char kChromeUIPasswordChangeUrl[]; extern const char kChromeUIPrintManagementUrl[]; extern const char kChromeUIPowerHost[]; +extern const char kChromeUIPowerUrl[]; extern const char kChromeUIProjectorHost[]; extern const char kChromeUIProjectorURL[]; extern const char kChromeUIScanningAppURL[]; @@ -302,6 +317,7 @@ extern const char kChromeUISmbShareHost[]; extern const char kChromeUISmbShareURL[]; extern const char kChromeUISysInternalsHost[]; +extern const char kChromeUISysInternalsUrl[]; extern const char kChromeUIUntrustedCroshURL[]; extern const char kChromeUIUntrustedTerminalHost[]; extern const char kChromeUIUntrustedTerminalURL[]; @@ -310,6 +326,60 @@ extern const char kChromeUIUserImageHost[]; extern const char kChromeUIUserImageURL[]; extern const char kChromeUIVmHost[]; +extern const char kChromeUIVmUrl[]; + +extern const char kOsUICroshURL[]; +extern const char kOsUIFileManagerURL[]; +extern const char kOsUITerminalURL[]; +extern const char kOsUIAccountManagerErrorURL[]; +extern const char kOsUIAccountManagerWelcomeURL[]; +extern const char kOsUIAccountMigrationWelcomeURL[]; +extern const char kOsUIAddSupervisionURL[]; +extern const char kOsUIAppDisabledURL[]; +extern const char kOsUIArcGraphicsTracingURL[]; +extern const char kOsUIArcOverviewTracingURL[]; +extern const char kOsUIArcPowerControlURL[]; +extern const char kOsUIAssistantOptInURL[]; +extern const char kOsUIBluetoothPairingURL[]; +extern const char kOsUIComponentsUrl[]; +extern const char kOsUICrashesUrl[]; +extern const char kOsUICreditsURL[]; +extern const char kOsUICrostiniCreditsURL[]; +extern const char kOsUICrostiniInstallerUrl[]; +extern const char kOsUICrostiniUpgraderUrl[]; +extern const char kOsUICryptohomeURL[]; +extern const char kOsUIDeviceLogUrl[]; +extern const char kOsUIDiagnosticsAppURL[]; +extern const char kOsUIDriveInternalsUrl[]; +extern const char kOsUIEmojiPickerURL[]; +extern const char kOsUIFlagsURL[]; +extern const char kOsUIGpuURL[]; +extern const char kOsUIHistogramsURL[]; +extern const char kOsUIIntenetConfigDialogURL[]; +extern const char kOsUIIntenetDetailDialogURL[]; +extern const char kOsUIInvalidationsUrl[]; +extern const char kOsUILockScreenNetworkURL[]; +extern const char kOsUILockScreenStartReauthURL[]; +extern const char kOsUIMobileSetupURL[]; +extern const char kOsUIMultiDeviceSetupUrl[]; +extern const char kOsUINetworkUrl[]; +extern const char kOsUIOSCreditsURL[]; +extern const char kOsUIOSSettingsURL[]; +extern const char kOsUIPowerUrl[]; +extern const char kOsUIPrintManagementUrl[]; +extern const char kOsUIRestartURL[]; +extern const char kOsUIScanningAppURL[]; +extern const char kOsUISetTimeURL[]; +extern const char kOsUISettingsURL[]; +extern const char kOsUISignInInternalsUrl[]; +extern const char kOsUISlowURL[]; +extern const char kOsUISmbCredentialsURL[]; +extern const char kOsUISmbShareURL[]; +extern const char kOsUISyncInternalsUrl[]; +extern const char kOsUISysInternalsUrl[]; +extern const char kOsUIUserImageURL[]; +extern const char kOsUIVersionURL[]; +extern const char kOsUIVmUrl[]; // Returns true if this web UI is part of the "system UI". Generally this is // UI that opens in a window (not a browser tab) and that on other operating
diff --git a/chrome/renderer/autofill/form_autofill_browsertest.cc b/chrome/renderer/autofill/form_autofill_browsertest.cc index 56f0b78..119fd4a 100644 --- a/chrome/renderer/autofill/form_autofill_browsertest.cc +++ b/chrome/renderer/autofill/form_autofill_browsertest.cc
@@ -5570,8 +5570,8 @@ EXPECT_EQ(u"firstname", fields[0].name); EXPECT_EQ(u"firstname", field.name); - frame->ExecuteScript( - WebString("document.getElementById('firstname').remove();")); + frame->ExecuteScript(blink::WebScriptSource( + WebString("document.getElementById('firstname').remove();"))); form = {}; EXPECT_FALSE(WebFormElementToFormData(web_form, control_element, nullptr, EXTRACT_NONE, &form, &field));
diff --git a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc index c16d885..017ff78f 100644 --- a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc +++ b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
@@ -216,8 +216,8 @@ void RemoveIframe() { blink::WebLocalFrame* main_frame = GetMainFrame(); ASSERT_TRUE(main_frame); - main_frame->ExecuteScript(blink::WebString( - "document.body.removeChild(document.getElementById('frame1'));")); + main_frame->ExecuteScript(blink::WebScriptSource(blink::WebString( + "document.body.removeChild(document.getElementById('frame1'));"))); } bool success_;
diff --git a/chrome/services/sharing/nearby/platform/bluetooth_socket.cc b/chrome/services/sharing/nearby/platform/bluetooth_socket.cc index 6a77278..b20be02 100644 --- a/chrome/services/sharing/nearby/platform/bluetooth_socket.cc +++ b/chrome/services/sharing/nearby/platform/bluetooth_socket.cc
@@ -56,10 +56,8 @@ } Exception BluetoothSocket::Close() { - if (socket_) { - socket_->Disconnect(); - socket_.reset(); - } + CloseMojoSocketIfNecessary(); + return bidirectional_stream_.Close(); } @@ -67,6 +65,22 @@ return &remote_device_ref_; } +void BluetoothSocket::CloseMojoSocketIfNecessary() { + base::AutoLock lock(lock_); + + if (!socket_) + return; + + // TODO(https://crbug.com/1270499): Remove CHECKs when crash fix is verified. + // If not for the lock--or if thread safety is violated in some unexpected + // way--these CHECKs would be triggered when Close() is called simultaneously + // from multiple threads. + CHECK(socket_); + socket_->Disconnect(); + CHECK(socket_); + socket_.reset(); +} + } // namespace chrome } // namespace nearby } // namespace location
diff --git a/chrome/services/sharing/nearby/platform/bluetooth_socket.h b/chrome/services/sharing/nearby/platform/bluetooth_socket.h index d4223d1..6f2741e 100644 --- a/chrome/services/sharing/nearby/platform/bluetooth_socket.h +++ b/chrome/services/sharing/nearby/platform/bluetooth_socket.h
@@ -6,6 +6,7 @@ #define CHROME_SERVICES_SHARING_NEARBY_PLATFORM_BLUETOOTH_SOCKET_H_ #include "base/memory/scoped_refptr.h" +#include "base/synchronization/lock.h" #include "chrome/services/sharing/nearby/platform/bidirectional_stream.h" #include "chrome/services/sharing/nearby/platform/bluetooth_device.h" #include "device/bluetooth/public/mojom/adapter.mojom.h" @@ -61,6 +62,11 @@ api::BluetoothDevice* GetRemoteDevice() override; private: + void CloseMojoSocketIfNecessary(); + + // Protects |socket_| while closing. + base::Lock lock_; + // If this BluetoothSocket is created by connecting to a discovered device, a // reference to that device will be provided to set |remote_device_ref_|, and // |remote_device_| will be left unset.
diff --git a/chrome/services/sharing/nearby/platform/bluetooth_socket_unittest.cc b/chrome/services/sharing/nearby/platform/bluetooth_socket_unittest.cc index 51f4eda3..dd8b3767 100644 --- a/chrome/services/sharing/nearby/platform/bluetooth_socket_unittest.cc +++ b/chrome/services/sharing/nearby/platform/bluetooth_socket_unittest.cc
@@ -9,6 +9,8 @@ #include "base/bind.h" #include "base/run_loop.h" +#include "base/task/thread_pool.h" +#include "base/test/bind.h" #include "base/test/task_environment.h" #include "chrome/services/sharing/nearby/platform/bluetooth_device.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -133,6 +135,33 @@ EXPECT_TRUE(bluetooth_socket_->Close().Ok()); } +TEST_F(BluetoothSocketTest, Close_CalledFromMultipleThreads) { + base::RunLoop run_loop; + const size_t kNumThreads = 3; + + // Quit the run loop after Close() returns on all threads. + size_t num_close_calls = 0; + auto quit_callback = + base::BindLambdaForTesting([&num_close_calls, &run_loop] { + ++num_close_calls; + if (num_close_calls == kNumThreads) + run_loop.Quit(); + }); + + // Call Close() from different threads simultaneously to ensure the socket is + // shut down gracefully. + for (size_t thread = 0; thread < kNumThreads; ++thread) { + base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}) + ->PostTaskAndReply( + FROM_HERE, base::BindLambdaForTesting([this] { + base::ScopedAllowBaseSyncPrimitivesForTesting allow; + EXPECT_EQ(Exception::kSuccess, bluetooth_socket_->Close().value); + }), + quit_callback); + } + run_loop.Run(); +} + TEST_F(BluetoothSocketTest, Destroy) { ASSERT_TRUE(fake_socket_);
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index b438cb4..8f1b3dd 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2059,7 +2059,6 @@ "../browser/unload_browsertest.cc", "../browser/usb/usb_browsertest.cc", "../browser/wake_lock/wake_lock_browsertest.cc", - "../browser/web_applications/extensions/bookmark_app_browsertest.cc", "../browser/webauthn/chrome_webauthn_browsertest.cc", "../browser/window_placement/window_placement_browsertest.cc", "../browser/window_placement/window_placement_permission_context_browsertest.cc", @@ -3423,7 +3422,6 @@ "../browser/ui/ash/keyboard/keyboard_end_to_end_browsertest.cc", "../browser/ui/ash/multi_user/test_multi_user_window_manager.cc", "../browser/ui/ash/multi_user/test_multi_user_window_manager.h", - "../browser/ui/ash/projector/projector_annotator_controller_browsertest.cc", "../browser/ui/ash/projector/projector_client_impl_browsertest.cc", "../browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc", "../browser/ui/ash/screen_orientation_delegate_chromeos_browsertest.cc", @@ -6402,6 +6400,7 @@ "../browser/lacros/client_cert_store_lacros_unittest.cc", "../browser/lacros/force_installed_tracker_lacros_unittest.cc", "../browser/lacros/lacros_memory_pressure_evaluator_unittest.cc", + "../browser/lacros/lacros_url_handling_unittest.cc", "../browser/lacros/metrics_reporting_observer_unittest.cc", "../browser/lacros/net/network_settings_translation_unittest.cc", "../browser/lacros/prefs_ash_observer_unittest.cc", @@ -6564,6 +6563,8 @@ "../browser/ui/ash/network/network_state_notifier_unittest.cc", "../browser/ui/ash/network/tether_notification_presenter_unittest.cc", "../browser/ui/ash/notification_badge_color_cache_unittest.cc", + "../browser/ui/ash/projector/projector_client_impl_unittest.cc", + "../browser/ui/ash/projector/projector_soda_installation_controller_unittest.cc", "../browser/ui/ash/quick_answers/quick_answers_controller_unittest.cc", "../browser/ui/ash/quick_answers/quick_answers_state_controller_unittest.cc", "../browser/ui/ash/quick_answers/quick_answers_ui_controller_unittest.cc", @@ -6590,6 +6591,8 @@ "//ash/public/cpp/resources:ash_public_unscaled_resources", "//ash/resources/vector_icons", "//ash/strings", + "//ash/webui/projector_app:test_support", + "//ash/webui/projector_app/public/cpp", "//chrome/browser/ash/crosapi:test_support", "//chrome/browser/ash/system_extensions:unit_tests", "//chrome/browser/chromeos:test_support", @@ -6619,6 +6622,7 @@ "//chromeos/services/nearby/public/cpp:test_support", "//chromeos/ui/wm", "//components/app_restore:unit_tests", + "//components/soda:soda", ] }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModelSelector.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModelSelector.java index 2cb7e029..a35b6a5 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModelSelector.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/browser/tabmodel/MockTabModelSelector.java
@@ -22,6 +22,7 @@ public static final int ID_OFFSET = 100000; public static final int INCOGNITO_ID_OFFSET = 200000; private static int sCurTabOffset; + private int mTabCount; public MockTabModelSelector( int tabCount, int incognitoTabCount, MockTabModel.MockTabModelDelegate delegate) { @@ -36,6 +37,7 @@ addMockIncognitoTab(); } if (incognitoTabCount > 0) TabModelUtils.setIndex(getModel(true), 0); + mTabCount = tabCount; } /** @@ -74,7 +76,7 @@ @Override public int getTotalTabCount() { - throw new UnsupportedOperationException(); + return mTabCount; } @Override
diff --git a/chrome/test/data/extensions/api_test/messaging/connect/history_back.html b/chrome/test/data/extensions/api_test/messaging/connect/history_back.html new file mode 100644 index 0000000..07288625 --- /dev/null +++ b/chrome/test/data/extensions/api_test/messaging/connect/history_back.html
@@ -0,0 +1,7 @@ +<!-- + * 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. +--> + +<script src="history_back.js"></script>
diff --git a/chrome/test/data/extensions/api_test/messaging/connect/history_back.js b/chrome/test/data/extensions/api_test/messaging/connect/history_back.js new file mode 100644 index 0000000..1bca9b48 --- /dev/null +++ b/chrome/test/data/extensions/api_test/messaging/connect/history_back.js
@@ -0,0 +1,5 @@ +// 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. + +window.history.back();
diff --git a/chrome/test/data/extensions/api_test/messaging/connect/page.js b/chrome/test/data/extensions/api_test/messaging/connect/page.js index 62ad0736..e555e3c 100644 --- a/chrome/test/data/extensions/api_test/messaging/connect/page.js +++ b/chrome/test/data/extensions/api_test/messaging/connect/page.js
@@ -25,6 +25,32 @@ chrome.runtime.onConnect.removeListener(onConnect); chrome.test.assertFalse(chrome.runtime.onConnect.hasListeners()); testConnectChildFrameAndNavigateSetup(); + } else if (msg.testNavigateAwayAndHistoryBack) { + // This tests the following scenario: + // 1. Open port to the background script (test.js). + // 2. The background script (test.js) sends a message + // ("navigateAwayAndHistoryBack") to this page. + // 3. Attach a pageshow event handler on this page. + // 4. Navigate to history_back.html, and navigate away from the + // current page. + // 5. The current page is stored in the back/forward cache. + // 6. history_back.html runs window.history.back(). + // 7. The previous page is salvaged from the back/forward cache. + // 8. The pageshow event handler sends two messages to the + // background script (test.js) to confirm that these ports + // that are opened before navigating away are still + // available. + let portFromTab = chrome.runtime.connect(); + portFromTab.onMessage.addListener(function(msg) { + window.addEventListener('pageshow', function(event) { + if (event.persisted) { + port.postMessage({salvagedFromBackForwardCache1: true}); + portFromTab.postMessage({salvagedFromBackForwardCache2: true}); + } + }); + chrome.test.assertEq('navigateAwayAndHistoryBack', msg); + window.location = 'api_test/messaging/connect/history_back.html'; + }); } else if (msg.testDisconnectOnClose) { chrome.runtime.connect().onMessage.addListener(function(msg) { chrome.test.assertEq('unloadTabContent', msg);
diff --git a/chrome/test/data/extensions/api_test/messaging/connect/test.js b/chrome/test/data/extensions/api_test/messaging/connect/test.js index 465e8fd..9eddd7f2 100644 --- a/chrome/test/data/extensions/api_test/messaging/connect/test.js +++ b/chrome/test/data/extensions/api_test/messaging/connect/test.js
@@ -272,8 +272,39 @@ chrome.tabs.reload(testTab.id); }, + // Tests that the port is still available even if the page is salvaged + // from back/forward cache. + function keepConnectionOnNavigationWithBfcache() { + // Skip test if bfcache is disabled because this test expects + // the port will remain open when the page is salvaged from the + // back/forward cache. + if (config.customArg !== 'bfcache') { + chrome.test.succeed(); + return; + } + listenOnce(chrome.runtime.onConnect, function(portFromTab) { + portFromTab.postMessage('navigateAwayAndHistoryBack'); + listenOnce(portFromTab.onMessage, function(msg) { + chrome.test.assertTrue(msg.salvagedFromBackForwardCache2); + }); + }); + var port = chrome.tabs.connect(testTab.id); + listenOnce(port.onMessage, function(msg) { + // The port is still available even if the page is salvaged + // from back/forward cache. + chrome.test.assertTrue(msg.salvagedFromBackForwardCache1); + }); + port.postMessage({testNavigateAwayAndHistoryBack: true}); + }, + // Tests that we get the disconnect event when the tab context closes. function disconnectOnClose() { + // Skip test if bfcache is enabled because the port will not be + // closed immediately if the page is cached. + if (config.customArg === 'bfcache') { + chrome.test.succeed(); + return; + } listenOnce(chrome.runtime.onConnect, function(portFromTab) { listenOnce(portFromTab.onDisconnect, function() { chrome.test.assertNoLastError();
diff --git a/chrome/test/data/extensions/api_test/scripting/main_frame/worker.js b/chrome/test/data/extensions/api_test/scripting/main_frame/worker.js index fcc8c942..1e1586b 100644 --- a/chrome/test/data/extensions/api_test/scripting/main_frame/worker.js +++ b/chrome/test/data/extensions/api_test/scripting/main_frame/worker.js
@@ -235,6 +235,28 @@ chrome.test.succeed(); }, + async function promisesAreResolved() { + const query = {url: 'http://example.com/*'}; + let tab = await getSingleTab(query); + const target = {tabId: tab.id}; + + const promiseFunc = async () => { + // Return a promise that resolves asynchronously. + let result = await new Promise((r) => { + setTimeout(r, 50, 'Hello, World!'); + }); + return result; + }; + const results = await chrome.scripting.executeScript({ + target: target, + func: promiseFunc, + }); + + chrome.test.assertEq(1, results.length); + chrome.test.assertEq('Hello, World!', results[0].result); + chrome.test.succeed(); + }, + async function injectedFunctionHasError() { const query = {url: 'http://example.com/*'}; let tab = await getSingleTab(query);
diff --git a/chrome/test/data/prefetch/prefetch_proxy/app_cache.html b/chrome/test/data/prefetch/prefetch_proxy/app_cache.html deleted file mode 100644 index 07cf691..0000000 --- a/chrome/test/data/prefetch/prefetch_proxy/app_cache.html +++ /dev/null
@@ -1,10 +0,0 @@ -<html manifest="manifest.appcache"> -<!-- -Copyright (c) 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. ---> -<body> - Hello, world! -</body> -</html>
diff --git a/chrome/test/data/prefetch/prefetch_proxy/link-rel-search-tag.html b/chrome/test/data/prefetch/prefetch_proxy/link-rel-search-tag.html index 6fc77692..1d404a0 100644 --- a/chrome/test/data/prefetch/prefetch_proxy/link-rel-search-tag.html +++ b/chrome/test/data/prefetch/prefetch_proxy/link-rel-search-tag.html
@@ -1,4 +1,4 @@ -<html manifest="manifest.appcache"> +<html> <!-- Copyright (c) 2020 The Chromium Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index 0afd4437..1e0f549 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -365,6 +365,7 @@ "$root_gen_dir/chrome/test/data/webui/settings/chromeos/personalization_page_test.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/quick_unlock_authenticate_browsertest_chromeos.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/smart_inputs_page_test.m.js", + "$root_gen_dir/chrome/test/data/webui/settings/chromeos/smart_privacy_subpage_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/smb_shares_page_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/os_a11y_page_tests.m.js", "$root_gen_dir/chrome/test/data/webui/settings/chromeos/reducers_test.m.js",
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js index fbb8c34a5..4132df5 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/onboarding_update_page_test.js
@@ -187,4 +187,35 @@ assertTrue(progressComponent.textContent.trim().startsWith( 'OS update progress received ')); }); + + test('UpdatePageSetSkipButton', async () => { + const version = '90.1.2.3'; + const update = false; + + service.setGetCurrentOsVersionResult(version); + service.setCheckForOsUpdatesResult(update, 'fake version'); + service.setUpdateOsResult(update); + + component = /** @type {!OnboardingUpdatePageElement} */ ( + document.createElement('onboarding-update-page')); + let buttonLabelKey; + component.addEventListener('set-next-button-label', (e) => { + buttonLabelKey = e.detail; + }); + + document.body.appendChild(component); + await flushTasks(); + assertEquals('nextButtonLabel', buttonLabelKey); + + service.setCheckForOsUpdatesResult(true, 'fake version'); + component = /** @type {!OnboardingUpdatePageElement} */ ( + document.createElement('onboarding-update-page')); + component.addEventListener('set-next-button-label', (e) => { + buttonLabelKey = e.detail; + }); + + document.body.appendChild(component); + await flushTasks(); + assertEquals('skipButtonLabel', buttonLabelKey); + }); }
diff --git a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js index 49196f1..559ada7b 100644 --- a/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js +++ b/chrome/test/data/webui/chromeos/shimless_rma/shimless_rma_app_test.js
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; import {fakeChromeVersion, fakeStates} from 'chrome://shimless-rma/fake_data.js'; import {FakeShimlessRmaService} from 'chrome://shimless-rma/fake_shimless_rma_service.js'; @@ -193,4 +194,28 @@ assertFalse(backButton.hidden); }); + + test('UpdateNextButtonLabel', async () => { + await initializeShimlessRMAApp( + [{ + state: RmaState.kSelectComponents, + canCancel: true, + canGoBack: true, + error: RmadErrorCode.kOk + }], + fakeChromeVersion[0]); + + const nextButton = component.shadowRoot.querySelector('#next'); + assertEquals( + loadTimeData.getString('nextButtonLabel'), + nextButton.textContent.trim()); + + component.dispatchEvent(new CustomEvent( + 'set-next-button-label', + {bubbles: true, composed: true, detail: 'skipButtonLabel'}, + )); + assertEquals( + loadTimeData.getString('skipButtonLabel'), + nextButton.textContent.trim()); + }); }
diff --git a/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js b/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js index a39673d..e459ccb 100644 --- a/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js +++ b/chrome/test/data/webui/cr_components/chromeos/bluetooth/bluetooth_pairing_ui_test.js
@@ -436,4 +436,63 @@ await displayPinOrPasskey(PairingAuthType.DISPLAY_PASSKEY); }); + test('Pairing a new device cancels old pairing', async function() { + let finishedPromise = eventToPromise('finished', bluetoothPairingUi); + const device = createDefaultBluetoothDevice( + /*id=*/ '1234321', + /*publicName=*/ 'BeatsX', + /*connectionState=*/ + chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, + /*opt_nickname=*/ 'device 1', + /*opt_audioCapability=*/ + mojom.AudioOutputCapability.kCapableOfAudioOutput, + /*opt_deviceType=*/ mojom.DeviceType.kMouse); + + const device1 = createDefaultBluetoothDevice( + /*id=*/ '12345654321', + /*publicName=*/ 'Head phones', + /*connectionState=*/ + chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, + /*opt_nickname=*/ 'device 2', + /*opt_audioCapability=*/ + mojom.AudioOutputCapability.kCapableOfAudioOutput, + /*opt_deviceType=*/ mojom.DeviceType.kMouse); + + const device2 = createDefaultBluetoothDevice( + /*id=*/ '123454321', + /*publicName=*/ 'Speakers', + /*connectionState=*/ + chromeos.bluetoothConfig.mojom.DeviceConnectionState.kConnected, + /*opt_nickname=*/ 'device 3', + /*opt_audioCapability=*/ + mojom.AudioOutputCapability.kCapableOfAudioOutput, + /*opt_deviceType=*/ mojom.DeviceType.kMouse); + + bluetoothConfig.appendToDiscoveredDeviceList( + [device.deviceProperties, device1.deviceProperties]); + await flushTasks(); + let deviceHandler = bluetoothConfig.getLastCreatedPairingHandler(); + + // Try pairing to first device. + await selectDevice(device.deviceProperties); + await flushTasks(); + + // Try pairing to second device, before first device has completed pairing. + await selectDevice(device1.deviceProperties); + await flushTasks(); + + // Try pairing to third device, before first device has completed pairing. + await selectDevice(device2.deviceProperties); + await flushTasks(); + + // Simulate device pairing cancellation. + deviceHandler.completePairDevice(/*success=*/ false); + await flushTasks(); + + assertEquals(deviceHandler.getPairDeviceCalledCount(), 2); + + // Complete second device pairing. + deviceHandler.completePairDevice(/*success=*/ true); + await finishedPromise; + }); });
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index 6effc10..dd2c0e8 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -156,6 +156,7 @@ "search_engine_test.js", "settings_scheduler_slider_test.js", "smart_inputs_page_test.js", + "smart_privacy_subpage_tests.js", "smb_shares_page_tests.js", "switch_access_action_assignment_dialog_test.js", "switch_access_setup_guide_dialog_test.js",
diff --git a/chrome/test/data/webui/settings/chromeos/os_privacy_page_test.js b/chrome/test/data/webui/settings/chromeos/os_privacy_page_test.js index bf7f700..15144f487 100644 --- a/chrome/test/data/webui/settings/chromeos/os_privacy_page_test.js +++ b/chrome/test/data/webui/settings/chromeos/os_privacy_page_test.js
@@ -96,6 +96,19 @@ settings.Router.getInstance().resetRouteForTesting(); }); + /** + * Returns true if the element exists and has not been 'removed' by the + * Polymer template system. + * @param {string} selector The ID of the element about which to query. + * @return {boolean} Whether or not the element has been masked by the + * template system. + * @private + */ + function elementExists(selector) { + const el = privacyPage.$$(selector); + return (el !== null) && (el.style.display !== 'none'); + } + test('Suggested content, pref disabled', async () => { privacyPage = document.createElement('os-settings-privacy-page'); document.body.appendChild(privacyPage); @@ -240,6 +253,36 @@ settings.routes.FINGERPRINT); assertTrue(privacyPage.showPasswordPromptDialog_); }); + + + test('Smart privacy hidden when feature disabled', async () => { + loadTimeData.overrideValues({ + isSnoopingProtectionEnabled: false, + }); + + privacyPage = document.createElement('os-settings-privacy-page'); + document.body.appendChild(privacyPage); + + await test_util.waitAfterNextRender(privacyPage); + + assertFalse(elementExists('#smartPrivacySubpageTrigger')); + }); + + test('Smart privacy shown when feature enabled', async () => { + loadTimeData.overrideValues({ + isSnoopingProtectionEnabled: true, + }); + + privacyPage = document.createElement('os-settings-privacy-page'); + document.body.appendChild(privacyPage); + + await test_util.waitAfterNextRender(privacyPage); + + assertTrue(elementExists('#smartPrivacySubpageTrigger')); + }); + + // TODO(crbug.com/1262869): add a test for deep linking to snopping setting + // once it has been added. }); suite('PrivacePageTest_OfficialBuild', async () => {
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js index 42bc133..1eb27f85 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_v3_browsertest.js
@@ -324,6 +324,7 @@ ['SearchSubpage', 'search_subpage_test.m.js'], ['SmartInputsPage', 'smart_inputs_page_test.m.js'], ['SmbPage', 'smb_shares_page_tests.m.js'], + ['SmartPrivacySubpage', 'smart_privacy_subpage_tests.m.js'], [ 'SwitchAccessActionAssignmentDialog', 'switch_access_action_assignment_dialog_test.m.js'
diff --git a/chrome/test/data/webui/settings/chromeos/smart_privacy_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/smart_privacy_subpage_tests.js new file mode 100644 index 0000000..70f995f --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/smart_privacy_subpage_tests.js
@@ -0,0 +1,65 @@ +// 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. + +// clang-format off +// #import 'chrome://os-settings/chromeos/lazy_load.js'; + +// #import {CrSettingsPrefs, Router} from 'chrome://os-settings/chromeos/os_settings.js'; +// #import {flush} from'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +// #import {assertFalse, assertTrue} from '../../chai_assert.js'; +// #import {assert} from 'chrome://resources/js/assert.m.js'; +// clang-format on + + +suite('SmartPrivacySubpageTests', function() { + /** @type {SettingsSmartPrivacyPage} */ + let smartPrivacySubpage = null; + + /** + * Generate preferences for the smart privacy page that either enable or + * disable the snooping protection feature. + * @ param {boolean} state Whether to enable or disable. + * @return {!CrSettingsPrefs} The corresponding pref dictionary. + * @private + */ + function makePrefs(snoopingState) { + return { + 'ash': { + 'privacy': { + 'snooping_protection_enabled': { + value: snoopingState, + } + } + }, + }; + } + + setup(async () => { + PolymerTest.clearBody(); + + smartPrivacySubpage = document.createElement('settings-smart-privacy-page'); + assertTrue(!!smartPrivacySubpage); + smartPrivacySubpage.prefs = makePrefs(false); + document.body.appendChild(smartPrivacySubpage); + }); + + teardown(async () => { + smartPrivacySubpage.remove(); + settings.Router.getInstance().resetRouteForTesting(); + }); + + test('Snooping radio list visibility tied to pref', async () => { + /** @type {?HTMLElement} */ + const collapse = assert(smartPrivacySubpage.$.snoopingProtectionOptions); + + // Default pref value is false. + assertFalse(collapse.opened); + + // Atomic reassign to so that Polymer notices the change. + smartPrivacySubpage.prefs = makePrefs(true); + Polymer.dom.flush(); + + assertTrue(collapse.opened); + }); +});
diff --git a/chrome/updater/app/app_server.cc b/chrome/updater/app/app_server.cc index 20029d12..125206d4 100644 --- a/chrome/updater/app/app_server.cc +++ b/chrome/updater/app/app_server.cc
@@ -155,7 +155,7 @@ bool AppServer::SwapVersions(GlobalPrefs* global_prefs) { global_prefs->SetSwapping(true); PrefsCommitPendingWrites(global_prefs->GetPrefService()); - if (!SwapRPCInterfaces()) + if (!SwapInNewVersion()) return false; if (!ConvertLegacyUpdaters(base::BindRepeating( &PersistedData::RegisterApp, base::MakeRefCounted<PersistedData>(
diff --git a/chrome/updater/app/app_server.h b/chrome/updater/app/app_server.h index 1f5a7eb..42cc2430 100644 --- a/chrome/updater/app/app_server.h +++ b/chrome/updater/app/app_server.h
@@ -50,9 +50,8 @@ virtual void ActiveDutyInternal( scoped_refptr<UpdateServiceInternal> update_service_internal) = 0; - // Sets up all non-side-by-side RPC interfaces to point to this candidate - // server. - virtual bool SwapRPCInterfaces() = 0; + // Sets up all non-side-by-side registration to point to the new version. + virtual bool SwapInNewVersion() = 0; // Ingests metadata from incompatible legacy updaters, then replaces those // updaters with shims.
diff --git a/chrome/updater/app/app_server_unittest.cc b/chrome/updater/app/app_server_unittest.cc index ccc65801..f176c77 100644 --- a/chrome/updater/app/app_server_unittest.cc +++ b/chrome/updater/app/app_server_unittest.cc
@@ -44,7 +44,7 @@ ActiveDutyInternal, (scoped_refptr<UpdateServiceInternal>), (override)); - MOCK_METHOD(bool, SwapRPCInterfaces, (), (override)); + MOCK_METHOD(bool, SwapInNewVersion, (), (override)); MOCK_METHOD(bool, ConvertLegacyUpdaters, (base::RepeatingCallback<void(const RegistrationRequest&)>), @@ -108,7 +108,7 @@ // Expect the app to ActiveDuty then SelfUninstall. EXPECT_CALL(*app, ActiveDuty).Times(1); - EXPECT_CALL(*app, SwapRPCInterfaces).Times(0); + EXPECT_CALL(*app, SwapInNewVersion).Times(0); EXPECT_CALL(*app, ConvertLegacyUpdaters).Times(0); EXPECT_CALL(*app, UninstallSelf).Times(1); EXPECT_EQ(app->Run(), 0); @@ -124,9 +124,10 @@ { auto app = base::MakeRefCounted<AppServerTest>(); - // Expect the app to SwapRpcInterfaces and then ActiveDuty then Shutdown(0). + // Expect the app to SwapInNewVersion and then ActiveDuty then + // Shutdown(0). EXPECT_CALL(*app, ActiveDuty).Times(1); - EXPECT_CALL(*app, SwapRPCInterfaces).WillOnce(Return(true)); + EXPECT_CALL(*app, SwapInNewVersion).WillOnce(Return(true)); EXPECT_CALL(*app, ConvertLegacyUpdaters).WillOnce(Return(true)); EXPECT_CALL(*app, UninstallSelf).Times(0); EXPECT_EQ(app->Run(), 0); @@ -141,10 +142,10 @@ { auto app = base::MakeRefCounted<AppServerTest>(); - // Expect the app to SwapRpcInterfaces and then ActiveDuty then Shutdown(0). - // In this case it bypasses qualification. + // Expect the app to SwapInNewVersion and then ActiveDuty then + // Shutdown(0). In this case it bypasses qualification. EXPECT_CALL(*app, ActiveDuty).Times(1); - EXPECT_CALL(*app, SwapRPCInterfaces).WillOnce(Return(true)); + EXPECT_CALL(*app, SwapInNewVersion).WillOnce(Return(true)); EXPECT_CALL(*app, ConvertLegacyUpdaters).WillOnce(Return(true)); EXPECT_CALL(*app, UninstallSelf).Times(0); EXPECT_EQ(app->Run(), 0); @@ -165,9 +166,9 @@ { auto app = base::MakeRefCounted<AppServerTest>(); - // Expect the app to SwapRpcInterfaces and then Shutdown(2). + // Expect the app to SwapInNewVersion and then Shutdown(2). EXPECT_CALL(*app, ActiveDuty).Times(0); - EXPECT_CALL(*app, SwapRPCInterfaces).WillOnce(Return(false)); + EXPECT_CALL(*app, SwapInNewVersion).WillOnce(Return(false)); EXPECT_CALL(*app, ConvertLegacyUpdaters).Times(0); EXPECT_CALL(*app, UninstallSelf).Times(0); EXPECT_EQ(app->Run(), 2); @@ -193,7 +194,7 @@ // Expect the app to ActiveDuty and then Shutdown(0). EXPECT_CALL(*app, ActiveDuty).Times(1); - EXPECT_CALL(*app, SwapRPCInterfaces).Times(0); + EXPECT_CALL(*app, SwapInNewVersion).Times(0); EXPECT_CALL(*app, ConvertLegacyUpdaters).Times(0); EXPECT_CALL(*app, UninstallSelf).Times(0); EXPECT_EQ(app->Run(), 0); @@ -218,10 +219,10 @@ { auto app = base::MakeRefCounted<AppServerTest>(); - // Expect the app to SwapRpcInterfaces and then ActiveDuty and then + // Expect the app to SwapInNewVersion and then ActiveDuty and then // Shutdown(0). EXPECT_CALL(*app, ActiveDuty).Times(1); - EXPECT_CALL(*app, SwapRPCInterfaces).WillOnce(Return(true)); + EXPECT_CALL(*app, SwapInNewVersion).WillOnce(Return(true)); EXPECT_CALL(*app, ConvertLegacyUpdaters).WillOnce(Return(true)); EXPECT_CALL(*app, UninstallSelf).Times(0); EXPECT_EQ(app->Run(), 0); @@ -246,9 +247,9 @@ { auto app = base::MakeRefCounted<AppServerTest>(); - // Expect the app to SwapRpcInterfaces and Shutdown(2). + // Expect the app to SwapInNewVersion and Shutdown(2). EXPECT_CALL(*app, ActiveDuty).Times(0); - EXPECT_CALL(*app, SwapRPCInterfaces).WillOnce(Return(false)); + EXPECT_CALL(*app, SwapInNewVersion).WillOnce(Return(false)); EXPECT_CALL(*app, ConvertLegacyUpdaters).Times(0); EXPECT_CALL(*app, UninstallSelf).Times(0); EXPECT_EQ(app->Run(), 2);
diff --git a/chrome/updater/app/server/mac/app_server.h b/chrome/updater/app/server/mac/app_server.h index 745eeae..f439344 100644 --- a/chrome/updater/app/server/mac/app_server.h +++ b/chrome/updater/app/server/mac/app_server.h
@@ -48,7 +48,7 @@ void ActiveDuty(scoped_refptr<UpdateService> update_service) override; void ActiveDutyInternal( scoped_refptr<UpdateServiceInternal> update_service_internal) override; - bool SwapRPCInterfaces() override; + bool SwapInNewVersion() override; bool ConvertLegacyUpdaters( base::RepeatingCallback<void(const RegistrationRequest&)> register_callback) override;
diff --git a/chrome/updater/app/server/mac/server.mm b/chrome/updater/app/server/mac/server.mm index 86325e5..5cceaa7 100644 --- a/chrome/updater/app/server/mac/server.mm +++ b/chrome/updater/app/server/mac/server.mm
@@ -90,7 +90,7 @@ UninstallCandidate(updater_scope()); } -bool AppServerMac::SwapRPCInterfaces() { +bool AppServerMac::SwapInNewVersion() { return PromoteCandidate(updater_scope()) == setup_exit_codes::kSuccess; }
diff --git a/chrome/updater/app/server/win/server.cc b/chrome/updater/app/server/win/server.cc index 3c93976..2f71fb93 100644 --- a/chrome/updater/app/server/win/server.cc +++ b/chrome/updater/app/server/win/server.cc
@@ -39,6 +39,7 @@ #include "chrome/updater/win/setup/setup_util.h" #include "chrome/updater/win/setup/uninstall.h" #include "chrome/updater/win/win_constants.h" +#include "chrome/updater/win/win_util.h" #include "components/prefs/pref_service.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -61,6 +62,31 @@ return GetCOMGroup(L"Internal", scope); } +// Update the registry value for the "UninstallCmdLine" under the UPDATER_KEY. +bool SwapUninstallCmdLine(UpdaterScope scope, + const base::FilePath& updater_path, + HKEY root, + WorkItemList* list) { + DCHECK(list); + + base::CommandLine uninstall_if_unused_command(updater_path); + + // TODO(crbug.com/1270520) - use a switch that can uninstall immediately if + // unused, instead of requiring server starts. + uninstall_if_unused_command.AppendSwitch(kUninstallIfUnusedSwitch); + if (scope == UpdaterScope::kSystem) + uninstall_if_unused_command.AppendSwitch(kSystemSwitch); + uninstall_if_unused_command.AppendSwitch(kEnableLoggingSwitch); + uninstall_if_unused_command.AppendSwitchASCII(kLoggingModuleSwitch, + kLoggingModuleSwitchValue); + list->AddCreateRegKeyWorkItem(root, UPDATER_KEY, Wow6432(0)); + list->AddSetRegValueWorkItem( + root, UPDATER_KEY, Wow6432(0), kRegValueUninstallCmdLine, + uninstall_if_unused_command.GetCommandLineString(), true); + + return true; +} + } // namespace // Returns a leaky singleton of the App instance. @@ -155,7 +181,7 @@ UninstallCandidate(updater_scope()); } -bool ComServerApp::SwapRPCInterfaces() { +bool ComServerApp::SwapInNewVersion() { std::unique_ptr<WorkItemList> list(WorkItem::CreateWorkItemList()); const absl::optional<base::FilePath> versioned_directory = @@ -166,19 +192,21 @@ const base::FilePath updater_path = versioned_directory->Append(FILE_PATH_LITERAL("updater.exe")); - if (IsCOMService()) { - AddComServiceWorkItems(updater_path, false, list.get()); - return list->Do(); - } - HKEY root = (updater_scope() == UpdaterScope::kSystem) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; - for (const CLSID& clsid : GetActiveServers(updater_scope())) { - AddInstallServerWorkItems(root, clsid, updater_path, false, list.get()); - } + if (!SwapUninstallCmdLine(updater_scope(), updater_path, root, list.get())) + return false; - for (const GUID& iid : GetActiveInterfaces()) { - AddInstallComInterfaceWorkItems(root, updater_path, iid, list.get()); + if (IsCOMService()) { + AddComServiceWorkItems(updater_path, false, list.get()); + } else { + for (const CLSID& clsid : GetActiveServers(updater_scope())) { + AddInstallServerWorkItems(root, clsid, updater_path, false, list.get()); + } + + for (const GUID& iid : GetActiveInterfaces()) { + AddInstallComInterfaceWorkItems(root, updater_path, iid, list.get()); + } } return list->Do();
diff --git a/chrome/updater/app/server/win/server.h b/chrome/updater/app/server/win/server.h index 32a391c..83a66d0 100644 --- a/chrome/updater/app/server/win/server.h +++ b/chrome/updater/app/server/win/server.h
@@ -69,7 +69,7 @@ void ActiveDuty(scoped_refptr<UpdateService> update_service) override; void ActiveDutyInternal( scoped_refptr<UpdateServiceInternal> update_service_internal) override; - bool SwapRPCInterfaces() override; + bool SwapInNewVersion() override; bool ConvertLegacyUpdaters( base::RepeatingCallback<void(const RegistrationRequest&)> register_callback) override;
diff --git a/chrome/updater/test/integration_test_commands.h b/chrome/updater/test/integration_test_commands.h index 9358763f..ccfab8bb 100644 --- a/chrome/updater/test/integration_test_commands.h +++ b/chrome/updater/test/integration_test_commands.h
@@ -65,6 +65,7 @@ virtual void ExpectLegacyUpdate3WebSucceeds( const std::string& app_id) const = 0; virtual void ExpectLegacyProcessLauncherSucceeds() const = 0; + virtual void RunUninstallCmdLine() const = 0; virtual void SetUpTestService() const = 0; virtual void TearDownTestService() const = 0; #endif // OS_WIN
diff --git a/chrome/updater/test/integration_test_commands_system.cc b/chrome/updater/test/integration_test_commands_system.cc index 5a0e9b7..8dd7cd3 100644 --- a/chrome/updater/test/integration_test_commands_system.cc +++ b/chrome/updater/test/integration_test_commands_system.cc
@@ -163,6 +163,10 @@ RunCommand("expect_legacy_process_launcher_succeeds"); } + void RunUninstallCmdLine() const override { + RunCommand("run_uninstall_cmd_line"); + } + void SetUpTestService() const override { updater::test::RunTestServiceCommand("setup"); }
diff --git a/chrome/updater/test/integration_test_commands_user.cc b/chrome/updater/test/integration_test_commands_user.cc index af171c2..31a47726 100644 --- a/chrome/updater/test/integration_test_commands_user.cc +++ b/chrome/updater/test/integration_test_commands_user.cc
@@ -152,6 +152,10 @@ updater::test::ExpectLegacyProcessLauncherSucceeds(updater_scope_); } + void RunUninstallCmdLine() const override { + updater::test::RunUninstallCmdLine(updater_scope_); + } + void SetUpTestService() const override {} void TearDownTestService() const override {}
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index f2ec9a8..69174c1 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -149,6 +149,7 @@ test_commands_->ExpectLegacyProcessLauncherSucceeds(); } + void RunUninstallCmdLine() { test_commands_->RunUninstallCmdLine(); } #endif // OS_WIN void SetupFakeUpdaterHigherVersion() { @@ -448,6 +449,23 @@ ExpectLegacyProcessLauncherSucceeds(); Uninstall(); } + +TEST_F(IntegrationTest, UninstallCmdLine) { + Install(); + ExpectInstalled(); + + // TODO(crbug.com/1270520) - use a switch that can uninstall immediately if + // unused, instead of requiring server starts. + SetServerStarts(24); + + ExpectVersionActive(kUpdaterVersion); + ExpectActiveUpdater(); + + RunUninstallCmdLine(); + WaitForServerExit(); + SleepFor(2); + ExpectClean(); +} #endif // defined(OS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) TEST_F(IntegrationTest, UnregisterUninstalledApp) {
diff --git a/chrome/updater/test/integration_tests_helper.cc b/chrome/updater/test/integration_tests_helper.cc index 7db260a..08f49861 100644 --- a/chrome/updater/test/integration_tests_helper.cc +++ b/chrome/updater/test/integration_tests_helper.cc
@@ -200,6 +200,7 @@ WithSystemScope(Wrap(&ExpectLegacyUpdate3WebSucceeds)))}, {"expect_legacy_process_launcher_succeeds", WithSystemScope(Wrap(&ExpectLegacyProcessLauncherSucceeds))}, + {"run_uninstall_cmd_line", WithSystemScope(Wrap(&RunUninstallCmdLine))}, #endif // OS_WIN {"expect_version_active", WithSwitch("version", WithSystemScope(Wrap(&ExpectVersionActive)))},
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h index d47c82b0..618de44c7 100644 --- a/chrome/updater/test/integration_tests_impl.h +++ b/chrome/updater/test/integration_tests_impl.h
@@ -158,6 +158,8 @@ void InvokeTestServiceFunction( const std::string& function_name, const base::flat_map<std::string, base::Value>& arguments); + +void RunUninstallCmdLine(UpdaterScope scope); #endif // OS_WIN // Returns the number of files in the directory, not including directories,
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc index 946a85e..ab01e69 100644 --- a/chrome/updater/test/integration_tests_win.cc +++ b/chrome/updater/test/integration_tests_win.cc
@@ -208,7 +208,15 @@ EXPECT_EQ(is_installed, RegKeyExists(root, key)); } - if (!is_installed) { + if (is_installed) { + std::wstring uninstall_cmd_line_string; + EXPECT_EQ(ERROR_SUCCESS, + base::win::RegKey(root, UPDATER_KEY, Wow6432(KEY_READ)) + .ReadValue(kRegValueUninstallCmdLine, + &uninstall_cmd_line_string)); + EXPECT_TRUE(base::CommandLine::FromString(uninstall_cmd_line_string) + .HasSwitch(kUninstallIfUnusedSwitch)); + } else { for (const wchar_t* key : {kRegKeyCompanyCloudManagement, kRegKeyCompanyEnrollment, UPDATER_POLICIES_KEY}) { @@ -770,5 +778,27 @@ EXPECT_EQ(RunVPythonCommand(command), 0); } +void RunUninstallCmdLine(UpdaterScope scope) { + HKEY root = + (scope == UpdaterScope::kSystem) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; + + std::wstring uninstall_cmd_line_string; + EXPECT_EQ( + ERROR_SUCCESS, + base::win::RegKey(root, UPDATER_KEY, Wow6432(KEY_READ)) + .ReadValue(kRegValueUninstallCmdLine, &uninstall_cmd_line_string)); + base::CommandLine command_line = + base::CommandLine::FromString(uninstall_cmd_line_string); + + base::ScopedAllowBaseSyncPrimitivesForTesting allow_wait_process; + + base::Process process = base::LaunchProcess(command_line, {}); + EXPECT_TRUE(process.IsValid()); + + int exit_code = 0; + EXPECT_TRUE(process.WaitForExitWithTimeout(base::Seconds(45), &exit_code)); + EXPECT_EQ(0, exit_code); +} + } // namespace test } // namespace updater
diff --git a/chrome/updater/win/win_constants.cc b/chrome/updater/win/win_constants.cc index e2c84eafb..08bff61 100644 --- a/chrome/updater/win/win_constants.cc +++ b/chrome/updater/win/win_constants.cc
@@ -15,6 +15,7 @@ const wchar_t kRegValuePV[] = L"pv"; const wchar_t kRegValueName[] = L"name"; +const wchar_t kRegValueUninstallCmdLine[] = L"UninstallCmdLine"; const wchar_t kRegValueInstallerError[] = L"InstallerError"; const wchar_t kRegValueInstallerExtraCode1[] = L"InstallerExtraCode1";
diff --git a/chrome/updater/win/win_constants.h b/chrome/updater/win/win_constants.h index 76bc581..06f0244 100644 --- a/chrome/updater/win/win_constants.h +++ b/chrome/updater/win/win_constants.h
@@ -44,6 +44,7 @@ extern const wchar_t kRegValuePV[]; extern const wchar_t kRegValueName[]; +extern const wchar_t kRegValueUninstallCmdLine[]; // Installer API registry names. extern const wchar_t kRegValueInstallerError[];
diff --git a/chromecast/media/gpu/cast_gpu_factory_impl.cc b/chromecast/media/gpu/cast_gpu_factory_impl.cc index 7114aab..3b1dc55 100644 --- a/chromecast/media/gpu/cast_gpu_factory_impl.cc +++ b/chromecast/media/gpu/cast_gpu_factory_impl.cc
@@ -110,8 +110,13 @@ return CreateVideoEncodeAccelerator(); } -// Return whether GPU encoding/decoding is enabled. -bool CastGpuFactoryImpl::IsGpuVideoAcceleratorEnabled() { +// Return whether GPU decoding is enabled. +bool CastGpuFactoryImpl::IsGpuVideoDecodeAcceleratorEnabled() { + return true; +} + +// Return whether GPU encoding is enabled. +bool CastGpuFactoryImpl::IsGpuVideoEncodeAcceleratorEnabled() { return true; }
diff --git a/chromecast/media/gpu/cast_gpu_factory_impl.h b/chromecast/media/gpu/cast_gpu_factory_impl.h index f226341..1311af1 100644 --- a/chromecast/media/gpu/cast_gpu_factory_impl.h +++ b/chromecast/media/gpu/cast_gpu_factory_impl.h
@@ -52,7 +52,8 @@ override; // media::GpuVideoAcceleratorFactories implementation. - bool IsGpuVideoAcceleratorEnabled() override; + bool IsGpuVideoDecodeAcceleratorEnabled() override; + bool IsGpuVideoEncodeAcceleratorEnabled() override; base::UnguessableToken GetChannelToken() override; int32_t GetCommandBufferRouteId() override; ::media::GpuVideoAcceleratorFactories::Supported IsDecoderConfigSupported(
diff --git a/chromecast/renderer/cast_content_renderer_client.cc b/chromecast/renderer/cast_content_renderer_client.cc index 970e6b7..767144d 100644 --- a/chromecast/renderer/cast_content_renderer_client.cc +++ b/chromecast/renderer/cast_content_renderer_client.cc
@@ -154,12 +154,6 @@ #endif } -void CastContentRendererClient::WebViewCreated(blink::WebView* webview) { - // Disable application cache as Chromecast doesn't support off-line - // application running. - webview->GetSettings()->SetOfflineWebApplicationCacheEnabled(false); -} - void CastContentRendererClient::RenderFrameCreated( content::RenderFrame* render_frame) { DCHECK(render_frame);
diff --git a/chromecast/renderer/cast_content_renderer_client.h b/chromecast/renderer/cast_content_renderer_client.h index 47272b6b..fe9ac94 100644 --- a/chromecast/renderer/cast_content_renderer_client.h +++ b/chromecast/renderer/cast_content_renderer_client.h
@@ -61,7 +61,6 @@ // ContentRendererClient implementation: void RenderThreadStarted() override; - void WebViewCreated(blink::WebView* web_view) override; void RenderFrameCreated(content::RenderFrame* render_frame) override; void RunScriptsAtDocumentStart(content::RenderFrame* render_frame) override; void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) override;
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 34a54b5d..08be718a 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -2091,6 +2091,9 @@ <message name="IDS_SHIMLESS_RMA_NEXT_BUTTON" desc="Default text for the button used to progress to the next step of RMA finalization."> Next </message> + <message name="IDS_SHIMLESS_RMA_SKIP_BUTTON" desc="Default text for the button used to skip to the next step of RMA finalization."> + Skip + </message> <!-- Landing page --> <message name="IDS_SHIMLESS_RMA_LANDING_PAGE_TITLE" translateable="false" desc="Title for the landing page at the start of RMA."> Chromebook repair
diff --git a/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_SKIP_BUTTON.png.sha1 b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_SKIP_BUTTON.png.sha1 new file mode 100644 index 0000000..7e8e728 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_SHIMLESS_RMA_SKIP_BUTTON.png.sha1
@@ -0,0 +1 @@ +4c21805ff4d50a9994fbffaa2495601c3b9b8ef2 \ No newline at end of file
diff --git a/chromeos/components/trial_group/BUILD.gn b/chromeos/components/trial_group/BUILD.gn index ae4884e..31973ed7 100644 --- a/chromeos/components/trial_group/BUILD.gn +++ b/chromeos/components/trial_group/BUILD.gn
@@ -12,7 +12,6 @@ deps = [ "//base", - "//content/public/browser", "//net", "//services/network/public/cpp", "//services/network/public/cpp:cpp_base", @@ -31,7 +30,6 @@ deps = [ ":trial_group", "//base", - "//content/test:test_support", "//net:test_support", "//services/network:test_support", "//testing/gtest",
diff --git a/chromeos/components/trial_group/DEPS b/chromeos/components/trial_group/DEPS deleted file mode 100644 index d79a7d0..0000000 --- a/chromeos/components/trial_group/DEPS +++ /dev/null
@@ -1,4 +0,0 @@ -include_rules = [ - "+content/public/browser", - "+content/public/test", -]
diff --git a/chromeos/components/trial_group/trial_group_checker.h b/chromeos/components/trial_group/trial_group_checker.h index df7f6739..638092e8 100644 --- a/chromeos/components/trial_group/trial_group_checker.h +++ b/chromeos/components/trial_group/trial_group_checker.h
@@ -10,7 +10,6 @@ #include "base/callback.h" #include "base/component_export.h" #include "base/memory/weak_ptr.h" -#include "content/public/browser/browser_context.h" #include "url/gurl.h" namespace network {
diff --git a/chromeos/components/trial_group/trial_group_checker_unittest.cc b/chromeos/components/trial_group/trial_group_checker_unittest.cc index f0e9348..dfe9f992 100644 --- a/chromeos/components/trial_group/trial_group_checker_unittest.cc +++ b/chromeos/components/trial_group/trial_group_checker_unittest.cc
@@ -4,7 +4,7 @@ #include "chromeos/components/trial_group/trial_group_checker.h" -#include "content/public/test/browser_task_environment.h" +#include "base/test/task_environment.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" #include "services/network/test/test_url_loader_factory.h" @@ -22,7 +22,7 @@ class TrialGroupCheckerTest : public testing::Test { public: TrialGroupCheckerTest() - : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP), + : task_environment_(base::test::TaskEnvironment::MainThreadType::IO), test_shared_loader_factory_( base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_)) {} @@ -36,7 +36,7 @@ } std::unique_ptr<net::test_server::EmbeddedTestServer> test_server_; - content::BrowserTaskEnvironment task_environment_; + base::test::TaskEnvironment task_environment_; network::TestURLLoaderFactory test_url_loader_factory_; scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
diff --git a/chromeos/crosapi/cpp/BUILD.gn b/chromeos/crosapi/cpp/BUILD.gn index fdf65c3..7cb2a9d 100644 --- a/chromeos/crosapi/cpp/BUILD.gn +++ b/chromeos/crosapi/cpp/BUILD.gn
@@ -12,6 +12,8 @@ sources = [ "crosapi_constants.cc", "crosapi_constants.h", + "gurl_os_handler_utils.cc", + "gurl_os_handler_utils.h", "keystore_service_util.cc", "keystore_service_util.h", "scoped_allow_sync_call.cc", @@ -33,5 +35,8 @@ "//chromeos/crosapi/mojom", "//testing/gtest", ] - sources = [ "keystore_service_util_unittest.cc" ] + sources = [ + "gurl_os_handler_unittest.cc", + "keystore_service_util_unittest.cc", + ] }
diff --git a/chromeos/crosapi/cpp/gurl_os_handler_unittest.cc b/chromeos/crosapi/cpp/gurl_os_handler_unittest.cc new file mode 100644 index 0000000..65f0c6c --- /dev/null +++ b/chromeos/crosapi/cpp/gurl_os_handler_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 "chromeos/crosapi/cpp/gurl_os_handler_utils.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace crosapi { + +namespace gurl_os_handler_utils { + +TEST(GurlOsHandlerUtilsTest, SanitizeAshURL) { + // Using a known GURL scheme, we should get scheme + host. + EXPECT_EQ(SanitizeAshURL(GURL("http://version")), GURL("http://version")); + EXPECT_EQ(SanitizeAshURL(GURL("http://version/#foo")), + GURL("http://version")); + EXPECT_EQ(SanitizeAshURL(GURL("http://version/1/#foo")), + GURL("http://version")); + EXPECT_EQ(SanitizeAshURL(GURL("http://version/1/?foo")), + GURL("http://version")); + + // Using a standard path, we should get scheme + host. + EXPECT_EQ(SanitizeAshURL(GURL("os://version")), GURL("os://version")); + + // Passing in an empty scheme will lead into an invalid result. + EXPECT_EQ(SanitizeAshURL(GURL("os://")), GURL("")); + + // Any path more than that will be ignored. + EXPECT_EQ(SanitizeAshURL(GURL("os://version/1")), GURL("os://version")); + EXPECT_EQ(SanitizeAshURL(GURL("os://version/1/foo")), GURL("os://version")); + EXPECT_EQ(SanitizeAshURL(GURL("os://version#")), GURL("os://version")); + EXPECT_EQ(SanitizeAshURL(GURL("os://version?")), GURL("os://version")); + EXPECT_EQ(SanitizeAshURL(GURL("os://version&")), GURL("os://version")); + + // Special characters get ignored + EXPECT_EQ(SanitizeAshURL(GURL("os://version%65")), GURL("os://version")); + + // Passing in any parameters, etc. we should get nothing as that is invalid. + EXPECT_EQ(SanitizeAshURL(GURL("os://version/query?foo=1&bar=1")), + GURL("os://version")); + EXPECT_EQ(SanitizeAshURL(GURL("os://version/+/query")), GURL("os://version")); + EXPECT_EQ(SanitizeAshURL(GURL("os://version/#foo")), GURL("os://version")); + EXPECT_EQ(SanitizeAshURL(GURL("os://version/1/#foo")), GURL("os://version")); + EXPECT_EQ(SanitizeAshURL(GURL("os://version/1/?foo")), GURL("os://version")); + + // Invalid syntax of kind will be detected by GURL as well. + EXPECT_EQ(SanitizeAshURL(GURL("os://version/foo#")), GURL("os://version")); + EXPECT_EQ(SanitizeAshURL(GURL("os://version/ver\\")), GURL("os://version")); + EXPECT_EQ(SanitizeAshURL(GURL("os://version/foo bar")), GURL("os://version")); + + // Case insensitive + EXPECT_EQ(SanitizeAshURL(GURL("Os://Foo/Bar")), GURL("os://foo")); +} + +TEST(GurlOsHandlerUtilsTest, IsURLInList) { + std::vector<GURL> list_of_urls = { + GURL("os://version"), GURL("Os://version2"), GURL("http://version"), + GURL("http://Foobar"), GURL("os://flags"), + }; + // As we expect the input to be sanitized, we cannot add any parameters. + EXPECT_TRUE(IsUrlInList(GURL("os://version"), list_of_urls)); + EXPECT_TRUE(IsUrlInList(GURL("os://flags"), list_of_urls)); + EXPECT_TRUE(IsUrlInList(GURL("http://version"), list_of_urls)); + // Does not exist. + EXPECT_FALSE(IsUrlInList(GURL("http://flags"), list_of_urls)); + // Our internal URLs will be treated part in part in/sensitive. The scheme + // is treated insensitive, while the host is not - so if an os:// URL in the + // list is upper case, it cannot be (ever) found. + // Note that DCHECKs make sure that no case insensitive host can be passed. + EXPECT_TRUE(IsUrlInList(GURL("Os://version"), list_of_urls)); + EXPECT_TRUE(IsUrlInList(GURL("Os://version2"), list_of_urls)); + // Whereas - if there is a valid scheme, the rest of the host will be handled + // case insensitive and be found. + EXPECT_TRUE(IsUrlInList(GURL("http://fOOBar"), list_of_urls)); +} + +TEST(GurlOsHandlerUtilsTest, IsAshOsUrl) { + // As we expect the input to be sanitized, we cannot add any parameters. + EXPECT_TRUE(IsAshOsUrl(GURL("os://version"))); + EXPECT_TRUE(IsAshOsUrl(GURL("os://flags"))); + EXPECT_TRUE(IsAshOsUrl(GURL("OS://flags"))); // case insensitive. + EXPECT_FALSE(IsAshOsUrl(GURL("os:/flags"))); // Proper '://' required. + EXPECT_FALSE(IsAshOsUrl(GURL("os://"))); // There needs to be a host. + EXPECT_FALSE(IsAshOsUrl(GURL("oo://version"))); // scheme need matching. + EXPECT_FALSE(IsAshOsUrl(GURL(""))); // No crash. + EXPECT_FALSE(IsAshOsUrl(GURL("::/bar"))); // No crash. + EXPECT_FALSE(IsAshOsUrl(GURL("osos::/bar"))); // In string correct. +} + +TEST(GurlOsHandlerUtilsTest, IsAshOsAsciiScheme) { + // As we expect the input to be sanitized, we cannot add any parameters. + EXPECT_TRUE(IsAshOsAsciiScheme("os")); + EXPECT_TRUE(IsAshOsAsciiScheme("Os")); + EXPECT_FALSE(IsAshOsAsciiScheme("")); // Should not crash. + EXPECT_FALSE(IsAshOsAsciiScheme("so")); + EXPECT_FALSE(IsAshOsAsciiScheme("soo")); +} + +TEST(GurlOsHandlerUtilsTest, AshOsUrlHost) { + EXPECT_EQ(AshOsUrlHost(GURL("os://flags")), "flags"); + EXPECT_EQ(AshOsUrlHost(GURL("os://flags/test")), "flags"); + EXPECT_EQ(AshOsUrlHost(GURL("os://flags?foo::bar")), "flags"); + EXPECT_EQ(AshOsUrlHost(GURL("os://flags#foo")), "flags"); + EXPECT_EQ(AshOsUrlHost(GURL("os://flags/foo")), "flags"); + EXPECT_EQ(AshOsUrlHost(GURL("os://FlagS/foo")), "flags"); + EXPECT_EQ(AshOsUrlHost(GURL("os://")), ""); + EXPECT_EQ(AshOsUrlHost(GURL("")), ""); + EXPECT_EQ(AshOsUrlHost(GURL("foo")), ""); + EXPECT_EQ(AshOsUrlHost(GURL("://")), ""); +} + +} // namespace gurl_os_handler_utils + +} // namespace crosapi
diff --git a/chromeos/crosapi/cpp/gurl_os_handler_utils.cc b/chromeos/crosapi/cpp/gurl_os_handler_utils.cc new file mode 100644 index 0000000..3b226d1d --- /dev/null +++ b/chromeos/crosapi/cpp/gurl_os_handler_utils.cc
@@ -0,0 +1,111 @@ +// 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 "chromeos/crosapi/cpp/gurl_os_handler_utils.h" + +#include <stddef.h> + +#include "base/logging.h" +#include "base/strings/string_util.h" + +namespace { + +const char kOsScheme[] = "os"; +const char kOsUrlPrefix[] = "os://"; + +// The start of the host portion of a GURL which starts with the os scheme. +const size_t kHostStart = sizeof(kOsUrlPrefix) - 1; + +// Used for sanitation - any of the characters will cut the rest of the URL. +const char kTerminatingCharacters[] = "/\\? #.%$&*<>"; + +} // namespace + +namespace crosapi { + +namespace gurl_os_handler_utils { + +GURL SanitizeAshURL(const GURL& url) { + if (!IsAshOsUrl(url)) { + // We do not use url.GetWithEmptyPath() here as there are various cases + // which do not result in proper results (e.g. chrome://flags => "" or + // chrome://flags/123 => chrome://flags/). + return url.DeprecatedGetOriginAsURL(); + } + + // Only keep the scheme and the host. Everything else gets cut off. + base::StringPiece url_spec = url.spec(); + + // Find the first character after the host start + std::size_t host_end = + url_spec.find_first_of(kTerminatingCharacters, kHostStart); + + // Note: We want to treat the internal URLs caseinsensitive. GURL usually + // handles this - but as we use an unknown scheme, only the scheme is treated + // caseinsensitive. + if (host_end == std::string::npos) + return GURL(base::ToLowerASCII(url_spec)); + + return GURL(base::ToLowerASCII(url_spec.substr(0, host_end))); +} + +bool IsUrlInList(const GURL& test_url, std::vector<GURL> list) { + // It is assumed that the provided URL is sanitized as requested by + // security at this point. + DCHECK(SanitizeAshURL(test_url) == test_url); + + const GURL& target_url = test_url; + for (const GURL& url : list) { + // It is expected that all os:// scheme items in the list are lower case + // no "/" at the end and properly sanitized as the GURL comparison will + // treat everything past the unknown scheme as an unknown string and hence + // do no processing. + DCHECK(!IsAshOsUrl(url) || SanitizeAshURL(url) == url); + if (target_url == url) + return true; + } + return false; +} + +bool IsAshOsUrl(const GURL& url) { + if (!url.is_valid() || url.spec().length() <= strlen(kOsUrlPrefix)) + return false; + + // Do not use "url.SchemeIs(kOsScheme)" here as it would require further + // parsing of the "://" portion to see if the Url is also valid. + return base::StartsWith(url.spec(), kOsUrlPrefix, + base::CompareCase::INSENSITIVE_ASCII); +} + +bool IsAshOsAsciiScheme(const base::StringPiece& scheme) { + return base::LowerCaseEqualsASCII(scheme, kOsScheme); +} + +std::string AshOsUrlHost(const GURL& url) { + if (!url.is_valid()) + return ""; + + // If we are using a default scheme, GURL does all for us. + if (!IsAshOsUrl(url)) + return url.host(); + + // Get the URL string after the start of the host portion. + base::StringPiece url_part = url.spec().substr(kHostStart); + + // Find the first "invalid character" we want to cut off. + std::size_t cut_off = url_part.find_first_of(kTerminatingCharacters); + + // Note: We want to treat the internal URLs caseinsensitive. GURL usually + // handles this - but as we use an unknown scheme, only the scheme is treated + // caseinsensitive. + // Return the string to the terminating character - or all. + if (cut_off == std::string::npos) + return base::ToLowerASCII(url_part); + + return base::ToLowerASCII(url_part.substr(0, cut_off)); +} + +} // namespace gurl_os_handler_utils + +} // namespace crosapi
diff --git a/chromeos/crosapi/cpp/gurl_os_handler_utils.h b/chromeos/crosapi/cpp/gurl_os_handler_utils.h new file mode 100644 index 0000000..e01f21a44 --- /dev/null +++ b/chromeos/crosapi/cpp/gurl_os_handler_utils.h
@@ -0,0 +1,60 @@ +// 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 CHROMEOS_CROSAPI_CPP_GURL_OS_HANDLER_UTILS_H_ +#define CHROMEOS_CROSAPI_CPP_GURL_OS_HANDLER_UTILS_H_ + +#include <vector> + +#include "url/gurl.h" + +#if defined(OS_CHROMEOS) + +// Adds utility functions for Lacros's system URL handling. +// +// Lacros is sending some special system os URLs to Ash for execution. These +// utility functions do add the functionality to handle the os:// scheme without +// adding it to the list of known schemes by the GURL / url library. +// +// Note also that the unknown scheme is treated case insensitive whereas the +// host and rest of the URL is unprocessed and therefore case senseitive. +// The sanitization will take care of lower casing the host of the os:// urls +// as will these functions making sure that this is properly handled. +// The host() / remaining spec() of the URL will also not be terminated by a +// "/" sign. + +namespace crosapi { + +namespace gurl_os_handler_utils { + +// Sanitize the URL according to security requests (only scheme and hos, +// nothing more should be passed). Note that as os:// is not safe to be added +// to the general GURL handler, we cannot use the standard library for this. +COMPONENT_EXPORT(CROSAPI) GURL SanitizeAshURL(const GURL& url); + +// Determines if a given URL matches any of the given URLs in the list. +// Note that the provided |url| needs to be sanitized. +// Note furthermore that the passed |list| is expected to be lower case for +// os:// scheme links. +COMPONENT_EXPORT(CROSAPI) +bool IsUrlInList(const GURL& url, const std::vector<GURL> list); + +// Returns true when the URL is an internal os:// url. Note that we do need +// This support only for OpenURL Lacros to Ash and as such +// RegisterContentScheme and/or url::AddSecureScheme should be avoided. +COMPONENT_EXPORT(CROSAPI) bool IsAshOsUrl(const GURL& url); + +// Returns true when the passed scheme string matches the "os" scheme. +COMPONENT_EXPORT(CROSAPI) bool IsAshOsAsciiScheme(const base::StringPiece& url); + +// Get the host from the given os:// URL. +COMPONENT_EXPORT(CROSAPI) std::string AshOsUrlHost(const GURL& url); + +} // namespace gurl_os_handler_utils + +} // namespace crosapi + +#endif // defined(OS_CHROMEOS) + +#endif // CHROMEOS_CROSAPI_CPP_GURL_OS_HANDLER_UTILS_H_
diff --git a/chromeos/crosapi/mojom/crosapi.mojom b/chromeos/crosapi/mojom/crosapi.mojom index ca04c37..6bb79e6 100644 --- a/chromeos/crosapi/mojom/crosapi.mojom +++ b/chromeos/crosapi/mojom/crosapi.mojom
@@ -600,8 +600,8 @@ // If ash-chrome is newer than the browser, then some fields may not be // processed by the browser. // -// Next version: 32 -// Next id: 31 +// Next version: 33 +// Next id: 32 [Stable, RenamedFrom="crosapi.mojom.LacrosInitParams"] struct BrowserInitParams { // This is ash-chrome's version of the Crosapi interface. This is used by @@ -801,6 +801,12 @@ // is present for Ash. [MinVersion=31] bool is_unfiltered_bluetooth_device_enabled@30; + + // Internal chrome:// URLs which can be handled by Ash. These are sent from + // Ash to Lacros at startup so Lacros knows which URLs are OK to forward. + // Added in M97. + [MinVersion=32] + array<url.mojom.Url>? accepted_internal_ash_urls@31; }; // BrowserService defines the APIs that live in a browser (such as
diff --git a/chromeos/dbus/fwupd/fwupd_client.cc b/chromeos/dbus/fwupd/fwupd_client.cc index 743a72b3..cd4bfdc 100644 --- a/chromeos/dbus/fwupd/fwupd_client.cc +++ b/chromeos/dbus/fwupd/fwupd_client.cc
@@ -37,12 +37,14 @@ protected: void Init(dbus::Bus* bus) override { + DCHECK(bus); + if (!features::IsFirmwareUpdaterAppEnabled()) return; proxy_ = bus->GetObjectProxy(kFwupdServiceName, dbus::ObjectPath(kFwupdServicePath)); - + DCHECK(proxy_); proxy_->ConnectToSignal( kFwupdServiceInterface, kFwupdDeviceAddedSignalName, base::BindRepeating(&FwupdClientImpl::OnDeviceAddedReceived, @@ -52,6 +54,7 @@ } void RequestUpdates(const std::string& device_id) override { + DCHECK(IsInitialized()); dbus::MethodCall method_call(kFwupdServiceInterface, kFwupdGetUpgradesMethodName); dbus::MessageWriter writer(&method_call); @@ -65,6 +68,7 @@ } void RequestDevices() override { + DCHECK(IsInitialized()); dbus::MethodCall method_call(kFwupdServiceInterface, kFwupdGetDevicesMethodName); proxy_->CallMethodWithErrorResponse( @@ -74,6 +78,9 @@ } private: + // Return true if the client has been initialized. + bool IsInitialized() { return proxy_; } + // Pops a string-to-variant-string dictionary from the reader. std::unique_ptr<base::DictionaryValue> PopStringToStringDictionary( dbus::MessageReader* reader) {
diff --git a/chromeos/dbus/fwupd/fwupd_client.h b/chromeos/dbus/fwupd/fwupd_client.h index 3cbbcf9..1388fdc2 100644 --- a/chromeos/dbus/fwupd/fwupd_client.h +++ b/chromeos/dbus/fwupd/fwupd_client.h
@@ -12,7 +12,6 @@ #include "chromeos/dbus/dbus_client.h" #include "chromeos/dbus/fwupd/fwupd_device.h" #include "chromeos/dbus/fwupd/fwupd_update.h" -#include "dbus/message.h" namespace chromeos { // FwupdClient is used for handling signals from the fwupd daemon.
diff --git a/chromeos/network/cellular_esim_profile_handler_impl_unittest.cc b/chromeos/network/cellular_esim_profile_handler_impl_unittest.cc index 8a0eac4..48d9c9d 100644 --- a/chromeos/network/cellular_esim_profile_handler_impl_unittest.cc +++ b/chromeos/network/cellular_esim_profile_handler_impl_unittest.cc
@@ -270,8 +270,8 @@ /*euicc_num=*/1, hermes::profile::State::kActive, /*activation_code=*/"code2"); - // Add one kTesting and one kProvisioning profile. These profiles are ignored - // and should never be returned by CellularESimProfileHandlerImpl. + // Add one kTesting and one kProvisioning profile. These profiles should not + // be ignored if they are returned from Hermes. AddProfile( /*euicc_num=*/1, hermes::profile::State::kInactive, /*activation_code=*/"code3", hermes::profile::ProfileClass::kTesting); @@ -289,11 +289,15 @@ EXPECT_EQ(1u, NumObserverEvents()); std::vector<CellularESimProfile> profiles = GetESimProfiles(); - EXPECT_EQ(2u, profiles.size()); + EXPECT_EQ(4u, profiles.size()); EXPECT_EQ(CellularESimProfile::State::kPending, profiles[0].state()); EXPECT_EQ("code1", profiles[0].activation_code()); EXPECT_EQ(CellularESimProfile::State::kActive, profiles[1].state()); EXPECT_EQ("code2", profiles[1].activation_code()); + EXPECT_EQ(CellularESimProfile::State::kInactive, profiles[2].state()); + EXPECT_EQ("code3", profiles[2].activation_code()); + EXPECT_EQ(CellularESimProfile::State::kInactive, profiles[3].state()); + EXPECT_EQ("code4", profiles[3].activation_code()); // Update profile properties; GetESimProfiles() should return the new values. HermesProfileClient::Properties* profile_properties1 = @@ -306,9 +310,11 @@ EXPECT_EQ(2u, NumObserverEvents()); profiles = GetESimProfiles(); - EXPECT_EQ(2u, profiles.size()); + EXPECT_EQ(4u, profiles.size()); EXPECT_EQ(CellularESimProfile::State::kInactive, profiles[0].state()); EXPECT_EQ(CellularESimProfile::State::kPending, profiles[1].state()); + EXPECT_EQ(CellularESimProfile::State::kInactive, profiles[2].state()); + EXPECT_EQ(CellularESimProfile::State::kInactive, profiles[3].state()); // Unset prefs; no profiles should exist. SetDevicePrefs(/*set_to_null=*/true);
diff --git a/chromeos/network/cellular_utils.cc b/chromeos/network/cellular_utils.cc index 56db5a7..76da35f4 100644 --- a/chromeos/network/cellular_utils.cc +++ b/chromeos/network/cellular_utils.cc
@@ -65,13 +65,9 @@ HermesProfileClient::Properties* profile_properties = HermesProfileClient::Get()->GetProperties(profile_path); - // Only consider profiles of type kOperational. Other profile types are only - // used for testing and should not be exposed to the UI. - if (profile_properties->profile_class().value() != - hermes::profile::ProfileClass::kOperational) { - continue; - } - + // Hermes only exposes eSIM profiles with relevant profile class. e.g. + // Test profiles are exposed only when Hermes is put into test mode. + // No additional profile filtering is done on Chrome side. profiles.emplace_back( FromProfileState(profile_properties->state().value()), profile_path, eid, profile_properties->iccid().value(),
diff --git a/chromeos/strings/chromeos_strings_be.xtb b/chromeos/strings/chromeos_strings_be.xtb index a752c37..8912325 100644 --- a/chromeos/strings/chromeos_strings_be.xtb +++ b/chromeos/strings/chromeos_strings_be.xtb
@@ -63,6 +63,7 @@ <translation id="1759842336958782510">Chrome</translation> <translation id="1792647875738159689">Сканіраванне скасоўваецца</translation> <translation id="1851218745569890714">Відэаканферэнцыі</translation> +<translation id="1857850044054738019">Выберыце гэты параметр, калі прылада адпраўляецца на склад або на аднаўленне для продажу новаму кліенту.</translation> <translation id="1874612839560830905">MTU</translation> <translation id="1887850431809612466">Версія апаратнага забеспячэння</translation> <translation id="1905710495812624430">Перавышана максімальная колькасць спроб.</translation> @@ -200,6 +201,7 @@ <translation id="4244962993387259361">Каб выканаць праверку памяці, вам патрэбна не менш за 500 МБ вольнага месца. Каб вызваліць месца, перайдзіце ў раздзел "Налады > Кіраванне сховішчам".</translation> <translation id="4258281355379922695">Затрымка HTTP-запытаў</translation> <translation id="4271957103967917607">Праглядзець у поўнаэкранным рэжыме</translation> +<translation id="4275799948641988986">Хто будзе выкарыстоўваць прыладу пасля рамонту?</translation> <translation id="4297501883039923494">Спынена: невядомая памылка</translation> <translation id="4300073214558989">Відарысаў: <ph name="IMAGE_COUNT" /></translation> <translation id="4378373042927530923">Паслядоўнасць дзеянняў не запускалася</translation> @@ -416,6 +418,7 @@ <translation id="7297226631177386107">Не ўдалося падключыцца праз брандмаўар да вэб-сайтаў HTTPS</translation> <translation id="7302860742311162920">ICCID</translation> <translation id="7305884605064981971">EDGE</translation> +<translation id="7309920310754476121">Прылада будзе перададзена іншаму ўладальніку</translation> <translation id="7319430975418800333">A3</translation> <translation id="7343649194310845056">Сеткавыя прылады</translation> <translation id="7359657277149375382">Тып файла</translation> @@ -423,6 +426,8 @@ <translation id="7415801143053185905">Вельмі вялікая затрымка HTTP-запытаў</translation> <translation id="7427315641433634153">MSCHAP</translation> <translation id="7435977162516949853">{NUMBER_OF_PAGES,plural, =1{Сканіраванне завершана. Адсканіравана 1 старонка}one{Сканіраванне завершана. Адсканіравана {NUMBER_OF_PAGES} старонка}few{Сканіраванне завершана. Адсканіравана {NUMBER_OF_PAGES} старонкі}many{Сканіраванне завершана. Адсканіравана {NUMBER_OF_PAGES} старонак}other{Сканіраванне завершана. Адсканіравана {NUMBER_OF_PAGES} старонкі}}</translation> +<translation id="7451112128070628323">Выберыце гэты параметр, калі права ўласнасці на прыладу не зменіцца + (напрыклад, калі прылада перадаецца іншай асобе ўнутры арганізацыі).</translation> <translation id="7469648432129124067">Выяўлены партал</translation> <translation id="7487067081878637334">Тэхналогія</translation> <translation id="7490813197707563893">MAC-адрас</translation> @@ -549,6 +554,7 @@ <translation id="9073281213608662541">PAP</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9088306295921699330">Бягучае выкарыстанне</translation> +<translation id="9095415590198785865">Прылада застанецца ў ранейшага ўладальніка</translation> <translation id="9095775724867566971">Pluginvm</translation> <translation id="910415269708673980">Абнавіце білет для <ph name="PRINCIPAL_NAME" /></translation> <translation id="9106415115617144481">Сканіруецца старонка <ph name="PAGE_NUMBER" /></translation>
diff --git a/chromeos/strings/chromeos_strings_et.xtb b/chromeos/strings/chromeos_strings_et.xtb index bb5774d..99d8086 100644 --- a/chromeos/strings/chromeos_strings_et.xtb +++ b/chromeos/strings/chromeos_strings_et.xtb
@@ -63,6 +63,7 @@ <translation id="1759842336958782510">Chrome</translation> <translation id="1792647875738159689">Skannimise tühistamine</translation> <translation id="1851218745569890714">Videokonverents</translation> +<translation id="1857850044054738019">Tehke see valik, kui seade läheb uuesti lattu või see taastatakse, et anda edasi uuele kliendile.</translation> <translation id="1874612839560830905">MTU</translation> <translation id="1887850431809612466">Riistvara redaktsioon</translation> <translation id="1905710495812624430">Katsete maksimaalne arv on ületatud.</translation> @@ -199,6 +200,7 @@ <translation id="4244962993387259361">Mälutesti käitamiseks on vaja vähemalt 500 MB vaba ruumi. Ruumi vabastamiseks tehke valikud Seaded > Salvestusruumi haldamine.</translation> <translation id="4258281355379922695">HTTP latentsusaeg</translation> <translation id="4271957103967917607">Kuva täisekraanil</translation> +<translation id="4275799948641988986">Kes hakkab pärast remontimist seadet kasutama?</translation> <translation id="4297501883039923494">Peatatud – tundmatu viga</translation> <translation id="4300073214558989"><ph name="IMAGE_COUNT" /> pilti</translation> <translation id="4378373042927530923">Ei käitatud</translation> @@ -415,6 +417,7 @@ <translation id="7297226631177386107">Ei saa HTTPS-veebisaitidega läbi tulemüüri ühendust luua</translation> <translation id="7302860742311162920">ICCID</translation> <translation id="7305884605064981971">EDGE</translation> +<translation id="7309920310754476121">Seade antakse teisele omanikule</translation> <translation id="7319430975418800333">A3</translation> <translation id="7343649194310845056">Võrguseadmed</translation> <translation id="7359657277149375382">Faili tüüp</translation> @@ -422,6 +425,8 @@ <translation id="7415801143053185905">Väga pikk HTTP latentsusaeg</translation> <translation id="7427315641433634153">MSCHAP</translation> <translation id="7435977162516949853">{NUMBER_OF_PAGES,plural, =1{Skannimine on lõpetatud. Skanniti üks leht.}other{Skannimine on lõpetatud. Skanniti {NUMBER_OF_PAGES} lehte}}</translation> +<translation id="7451112128070628323">Tehke see valik, kui seadme omandiline kuuluvus ei muutu. + Näiteks antakse seade organisatsioonis edasi teisele inimesele.</translation> <translation id="7469648432129124067">Tuvastati portaal</translation> <translation id="7487067081878637334">Tehnoloogia</translation> <translation id="7490813197707563893">MAC-aadress</translation> @@ -548,6 +553,7 @@ <translation id="9073281213608662541">PAP</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9088306295921699330">Praegune kasutus</translation> +<translation id="9095415590198785865">Seade antakse samale omanikule</translation> <translation id="9095775724867566971">Pluginvm</translation> <translation id="910415269708673980">Kasutaja <ph name="PRINCIPAL_NAME" /> pileti värskendamine</translation> <translation id="9106415115617144481">Lehe <ph name="PAGE_NUMBER" /> skannimine</translation>
diff --git a/chromeos/strings/chromeos_strings_hy.xtb b/chromeos/strings/chromeos_strings_hy.xtb index d95d45d..75d5c8f 100644 --- a/chromeos/strings/chromeos_strings_hy.xtb +++ b/chromeos/strings/chromeos_strings_hy.xtb
@@ -158,6 +158,8 @@ <translation id="357889014807611375">սահմանափակ Wi-Fi</translation> <translation id="3583278742022654445">Ազդանշանը թույլ է։ Փորձեք սարքը մոտեցնել Wi-Fi ազդանշանի աղբյուրին։</translation> <translation id="3595596368722241419">Մարտկոցը լրիվ լիցքավորված է</translation> +<translation id="360089215033199597">Վերականգնման գործընթացը հեշտացնելու համար խորհուրդ է տրվում միանալ Wi-Fi-ին։ + Ձեր ցանցի տվյալները կպահվեն։</translation> <translation id="360565022852130722">Wi-Fi ցանցը պաշտպանված է WEP 802.1x թույլ հաղորդակարգով</translation> <translation id="3606583719724308068">Բարձր հապաղում HTTPS կայքերի համար</translation> <translation id="3689839747745352263"><ph name="TEST_NAME" /> փորձարկում</translation> @@ -480,6 +482,7 @@ <translation id="816013303019725643">Մուտքագրեք ապակողպման կոդը՝</translation> <translation id="8206859287963243715">Բջջային</translation> <translation id="8208861521865154048">Բոնուսներ</translation> +<translation id="8217675307824400706">Միացեք ցանցին</translation> <translation id="8230672074305416752">Չհաջողվեց փինգ ուղարկել կանխադրված ցանցի անցախուցին</translation> <translation id="8246209727385807362">Անհայտ օպերատոր</translation> <translation id="8286154143153872371">Միացեք որևէ ցանցի և վերաբեռնեք էջը՝ պաստառը դիտելու համար։</translation>
diff --git a/chromeos/strings/chromeos_strings_it.xtb b/chromeos/strings/chromeos_strings_it.xtb index 377660c..dbc162f 100644 --- a/chromeos/strings/chromeos_strings_it.xtb +++ b/chromeos/strings/chromeos_strings_it.xtb
@@ -158,6 +158,8 @@ <translation id="357889014807611375">Wi-Fi a consumo</translation> <translation id="3583278742022654445">Intensità segnale debole. Prova ad avvicinarti alla fonte del segnale Wi-Fi.</translation> <translation id="3595596368722241419">Batteria carica</translation> +<translation id="360089215033199597">Si consiglia di connettersi al Wi-Fi per semplificare il processo di riparazione. + La rete verrà salvata.</translation> <translation id="360565022852130722">la rete Wi-Fi è protetta con un protocollo WEP 802.1x inefficace</translation> <translation id="3606583719724308068">Alta latenza a siti web HTTPS</translation> <translation id="3689839747745352263">Test <ph name="TEST_NAME" /></translation> @@ -479,6 +481,7 @@ <translation id="8138405288920084977">LTEAdvanced</translation> <translation id="8206859287963243715">Cellulare</translation> <translation id="8208861521865154048">Vantaggi</translation> +<translation id="8217675307824400706">Connettiti</translation> <translation id="8230672074305416752">impossibile eseguire il ping del gateway di rete predefinito</translation> <translation id="8246209727385807362">Operatore sconosciuto</translation> <translation id="8286154143153872371">Connettiti a una rete e ricarica la pagina per visualizzare lo sfondo.</translation>
diff --git a/chromeos/strings/chromeos_strings_ky.xtb b/chromeos/strings/chromeos_strings_ky.xtb index ec9ebbc1..3da84be 100644 --- a/chromeos/strings/chromeos_strings_ky.xtb +++ b/chromeos/strings/chromeos_strings_ky.xtb
@@ -63,6 +63,8 @@ <translation id="1759842336958782510">Chrome</translation> <translation id="1792647875738159689">Скандоо токтотулууда</translation> <translation id="1851218745569890714">Видео конференция</translation> +<translation id="1857850044054738019">Эгер түзмөк кайтарылып же жаңы кардарга берүү үчүн калыбына келтирилсе, ушул + параметрди тандаңыз.</translation> <translation id="1874612839560830905">MTU</translation> <translation id="1887850431809612466">Жабдыкты оңдоо</translation> <translation id="1905710495812624430">Аракеттер уруксат берилген чегинен ашты.</translation> @@ -200,6 +202,7 @@ <translation id="4244962993387259361">Эстутумду сыноо үчүн кеминде 500 Мб бош орун керек. Орун бошотуу үчүн Жөндөөлөр > Сактагычты башкаргычка өтүңүз.</translation> <translation id="4258281355379922695">HTTP күтүү убакыты</translation> <translation id="4271957103967917607">Толук экран режими</translation> +<translation id="4275799948641988986">Оңдолгондон кийин түзмөктү ким колдонот?</translation> <translation id="4297501883039923494">Токтоду – Белгисиз ката</translation> <translation id="4300073214558989"><ph name="IMAGE_COUNT" /> сүрөт</translation> <translation id="4378373042927530923">Иштетилген жок</translation> @@ -416,6 +419,7 @@ <translation id="7297226631177386107">HTTPS вебсайттарына тармактык коргоо аркылуу туташпай жатат</translation> <translation id="7302860742311162920">ICCID</translation> <translation id="7305884605064981971">EDGE</translation> +<translation id="7309920310754476121">Түзмөк башка адамга берилет</translation> <translation id="7319430975418800333">A3</translation> <translation id="7343649194310845056">Тармак түзмөктөрү</translation> <translation id="7359657277149375382">Файлдын түрү</translation> @@ -423,6 +427,9 @@ <translation id="7415801143053185905">HTTP күтүү убакыты өтө жогору</translation> <translation id="7427315641433634153">MSCHAP</translation> <translation id="7435977162516949853">{NUMBER_OF_PAGES,plural, =1{Скандалып бүттү. 1 бет скандалды}other{Скандалып бүттү. {NUMBER_OF_PAGES} бет скандалды}}</translation> +<translation id="7451112128070628323">Түзмөктүн ээси өзгөрбөсө, ушул параметрди тандаңыз. + Мисалы, түзмөк уюмдагы башка адамга өткөрүлүп + жатат.</translation> <translation id="7469648432129124067">Портал аныкталды</translation> <translation id="7487067081878637334">Технология</translation> <translation id="7490813197707563893">MAC дареги</translation> @@ -549,6 +556,7 @@ <translation id="9073281213608662541">PAP</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9088306295921699330">Учурдагы колдонулушу</translation> +<translation id="9095415590198785865">Түзмөк ошол эле адамга берилет</translation> <translation id="9095775724867566971">Pluginvm</translation> <translation id="910415269708673980"><ph name="PRINCIPAL_NAME" /> үчүн билетти жаңыртыңыз</translation> <translation id="9106415115617144481"><ph name="PAGE_NUMBER" />-бет скандалууда</translation>
diff --git a/chromeos/strings/chromeos_strings_lo.xtb b/chromeos/strings/chromeos_strings_lo.xtb index be1c877..627d1d31 100644 --- a/chromeos/strings/chromeos_strings_lo.xtb +++ b/chromeos/strings/chromeos_strings_lo.xtb
@@ -63,6 +63,8 @@ <translation id="1759842336958782510">Chrome</translation> <translation id="1792647875738159689">ກຳລັງຍົກເລີກການສະແກນ</translation> <translation id="1851218745569890714">ການປະຊຸມຜ່ານວິດີໂອ</translation> +<translation id="1857850044054738019">ເລືອກຕົວເລືອກນີ້ຫາກອຸປະກອນກຳລັງຖືກເກັບເຂົ້າສະຕັອກຄືນໃໝ່ ຫຼື ຣີເຟີບິດ + ເພື່ອການແຈກຈ່າຍໄປໃຫ້ລູກຄ້າໃໝ່.</translation> <translation id="1874612839560830905">MTU</translation> <translation id="1887850431809612466">ການປັບປຸງແກ້ໄຂຮາດແວ</translation> <translation id="1905710495812624430">ເກີນຈຳນວນຄວາມພະຍາຍາມສູງສຸດແລ້ວ.</translation> @@ -198,6 +200,7 @@ <translation id="4244962993387259361">ທ່ານຕ້ອງມີພື້ນທີ່ຫວ່າງຢ່າງໜ້ອຍ 500 MB ເພື່ອເປີດໃຊ້ການທົດສອບໜ່ວຍຄວາມຈຳ. ເພື່ອສ້າງພື້ນທີ່ຫວ່າງ, ໃຫ້ເຂົ້າໄປການຕັ້ງຄ່າ > ການຈັດການບ່ອນຈັດເກັບຂໍ້ມູນ.</translation> <translation id="4258281355379922695">ການຕອບສະໜອງ HTTP</translation> <translation id="4271957103967917607">ເບິ່ງແບບເຕັມຈໍ</translation> +<translation id="4275799948641988986">ຫຼັງຈາກການສ້ອມແປງ, ໃຜຈະເປັນຄົນໃຊ້ອຸປະກອນ?</translation> <translation id="4297501883039923494">ຢຸດພິມ, ບໍ່ຮູ້ຈັກຂໍ້ຜິດພາດ</translation> <translation id="4300073214558989"><ph name="IMAGE_COUNT" /> ຮູບ</translation> <translation id="4378373042927530923">ບໍ່ໄດ້ເອີ້ນໃຊ້</translation> @@ -415,6 +418,7 @@ <translation id="7297226631177386107">ບໍ່ສາມາດເຊື່ອມຕໍ່ຜ່ານ firewall ຫາເວັບໄຊ HTTPS ໄດ້</translation> <translation id="7302860742311162920">ICCID</translation> <translation id="7305884605064981971">EDGE</translation> +<translation id="7309920310754476121">ອຸປະກອນຈະໄປຫາເຈົ້າຂອງໃໝ່</translation> <translation id="7319430975418800333">A3</translation> <translation id="7343649194310845056">ອຸປະກອນເຄືອຂ່າຍ</translation> <translation id="7359657277149375382">ປະເພດໄຟລ໌</translation> @@ -422,6 +426,9 @@ <translation id="7415801143053185905">ການຕອບສະໜອງ HTTP ສູງຫຼາຍ</translation> <translation id="7427315641433634153">MSCHAP</translation> <translation id="7435977162516949853">{NUMBER_OF_PAGES,plural, =1{ສຳເລັດການສະແກນແລ້ວ. ສະແກນ 1 ໜ້າແລ້ວ}other{ສຳເລັດການສະແກນແລ້ວ. ສະແກນ {NUMBER_OF_PAGES} ໜ້າແລ້ວ}}</translation> +<translation id="7451112128070628323">ເລືອກຕົວເລືອກນີ້ຫາກຄວາມເປັນເຈົ້າຂອງອຸປະກອນບໍ່ມີການປ່ຽນແປງ. + ຕົວຢ່າງ: ອຸປະກອນກຳລັງຖືກໂອນຍ້າຍໄປໃຫ້ຄົນອື່ນ + ພາຍໃນອົງການດຽວກັນ.</translation> <translation id="7469648432129124067">ກວດພົບໜ້າເວັບ</translation> <translation id="7487067081878637334">ເທັກໂນໂລຢີ</translation> <translation id="7490813197707563893">ທີ່ຢູ່ MAC</translation> @@ -547,6 +554,7 @@ <translation id="9073281213608662541">PAP</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9088306295921699330">ການນຳໃຊ້ໃນປັດຈຸບັນ</translation> +<translation id="9095415590198785865">ອຸປະກອນຈະໄປຫາເຈົ້າຂອງດຽວກັນ</translation> <translation id="9095775724867566971">Pluginvm</translation> <translation id="910415269708673980">ໂຫຼດຂໍ້ມູນປີ້ສຳລັບ <ph name="PRINCIPAL_NAME" /> ໃໝ່</translation> <translation id="9106415115617144481">ກຳລັງສະແກນໜ້າ <ph name="PAGE_NUMBER" /></translation>
diff --git a/chromeos/strings/chromeos_strings_lv.xtb b/chromeos/strings/chromeos_strings_lv.xtb index b90ae40..f855dec 100644 --- a/chromeos/strings/chromeos_strings_lv.xtb +++ b/chromeos/strings/chromeos_strings_lv.xtb
@@ -63,6 +63,7 @@ <translation id="1759842336958782510">Chrome</translation> <translation id="1792647875738159689">Skenēšana tiek atcelta</translation> <translation id="1851218745569890714">Videokonferences</translation> +<translation id="1857850044054738019">Atlasiet šo opciju, ja ierīce tiek padarīta atkal pieejama vai atjaunota izplatīšanai jaunam klientam.</translation> <translation id="1874612839560830905">MTU</translation> <translation id="1887850431809612466">Aparatūras pārskatījums</translation> <translation id="1905710495812624430">Ir pārsniegts maksimālais atļautais mēģinājumu skaits.</translation> @@ -199,6 +200,7 @@ <translation id="4244962993387259361">Lai veiktu atmiņas pārbaudi, jābūt vismaz 500 MB brīvai vietai. Lai atbrīvotu vietu, pārejiet uz sadaļu Iestatījumi > Krātuves pārvaldnieks.</translation> <translation id="4258281355379922695">HTTP latentums</translation> <translation id="4271957103967917607">Skatīt pilnekrāna režīmā</translation> +<translation id="4275799948641988986">Kas izmantos ierīci pēc labošanas?</translation> <translation id="4297501883039923494">Apturēts — nezināma kļūda</translation> <translation id="4300073214558989"><ph name="IMAGE_COUNT" /> attēls(-i)</translation> <translation id="4378373042927530923">Nav veikta izpilde</translation> @@ -415,6 +417,7 @@ <translation id="7297226631177386107">Nevar izveidot savienojumu ar HTTPS vietnēm, ja ir iespējots ugunsmūris</translation> <translation id="7302860742311162920">ICCID</translation> <translation id="7305884605064981971">EDGE</translation> +<translation id="7309920310754476121">Ierīcei būs cits īpašnieks</translation> <translation id="7319430975418800333">A3</translation> <translation id="7343649194310845056">Tīkla ierīces</translation> <translation id="7359657277149375382">Faila tips</translation> @@ -422,6 +425,8 @@ <translation id="7415801143053185905">Ļoti liels HTTP latentums</translation> <translation id="7427315641433634153">MSCHAP</translation> <translation id="7435977162516949853">{NUMBER_OF_PAGES,plural, =1{Pārbaude pabeigta. Pārbaudīta 1 lapa.}zero{Pārbaude pabeigta. Pārbaudītas {NUMBER_OF_PAGES} lapas.}one{Pārbaude pabeigta. Pārbaudīta {NUMBER_OF_PAGES} lapa.}other{Pārbaude pabeigta. Pārbaudītas {NUMBER_OF_PAGES} lapas.}}</translation> +<translation id="7451112128070628323">Atlasiet šo opciju, ja ierīces īpašumtiesības netiek mainītas, + piemēram, ja ierīce tiek nodota citai personai tajā pašā organizācijā.</translation> <translation id="7469648432129124067">Konstatēts portāls</translation> <translation id="7487067081878637334">Tehnoloģijas</translation> <translation id="7490813197707563893">MAC adrese</translation> @@ -547,6 +552,7 @@ <translation id="9073281213608662541">PAP</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9088306295921699330">Pašreizējais lietojums</translation> +<translation id="9095415590198785865">Ierīcei būs tas pats īpašnieks</translation> <translation id="9095775724867566971">Pluginvm</translation> <translation id="910415269708673980">Atsvaidziniet <ph name="PRINCIPAL_NAME" /> biļeti</translation> <translation id="9106415115617144481">Notiek <ph name="PAGE_NUMBER" />. lapas skenēšana</translation>
diff --git a/chromeos/strings/chromeos_strings_mk.xtb b/chromeos/strings/chromeos_strings_mk.xtb index be44521..402e17fb 100644 --- a/chromeos/strings/chromeos_strings_mk.xtb +++ b/chromeos/strings/chromeos_strings_mk.xtb
@@ -159,6 +159,8 @@ <translation id="357889014807611375">Wi-Fi со ограничен интернет</translation> <translation id="3583278742022654445">Слаба јачина на сигналот. Обидете се да се приближите до изворот на сигналот за Wi-Fi.</translation> <translation id="3595596368722241419">Батеријата е полна</translation> +<translation id="360089215033199597">Се препорачува да се поврзете на Wi-Fi за да го олесните процесот на поправка. + Вашата мрежа ќе биде зачувана.</translation> <translation id="360565022852130722">Wi-Fi мрежата е обезбедена со слаб протокол WEP 802.1x</translation> <translation id="3606583719724308068">Висока латенција кон веб-сајтовите со HTTPS</translation> <translation id="3689839747745352263">Тест за <ph name="TEST_NAME" /></translation> @@ -482,6 +484,7 @@ <translation id="816013303019725643">Внесете го кодот за отклучување:</translation> <translation id="8206859287963243715">Мобилен</translation> <translation id="8208861521865154048">Поволности</translation> +<translation id="8217675307824400706">Поврзете се</translation> <translation id="8230672074305416752">Не успеа да се пингува стандардниот мрежен портал</translation> <translation id="8246209727385807362">Непознат оператор</translation> <translation id="8286154143153872371">Поврзете се на мрежа и повторно вчитајте ја страницата за да се прикаже тапетот.</translation>
diff --git a/chromeos/strings/chromeos_strings_nl.xtb b/chromeos/strings/chromeos_strings_nl.xtb index c078d1e..af1e282 100644 --- a/chromeos/strings/chromeos_strings_nl.xtb +++ b/chromeos/strings/chromeos_strings_nl.xtb
@@ -77,6 +77,7 @@ <translation id="2016697457005847575">Probeer de stappen voor probleemoplossing</translation> <translation id="202500043506723828">EID</translation> <translation id="2080070583977670716">Meer instellingen</translation> +<translation id="2104796393919810494">Reparatie afgerond</translation> <translation id="2119172414412204879"><ph name="BOARD_NAME" />, versie <ph name="MILESTONE_VERSION" /></translation> <translation id="2126937207024182736"><ph name="AVAILABLE_MEMORY" /> GB van <ph name="TOTAL_MEMORY" /> GB beschikbaar</translation> <translation id="2141644705054017895"><ph name="PERCENTAGE_VALUE" />%</translation>
diff --git a/chromeos/strings/chromeos_strings_pl.xtb b/chromeos/strings/chromeos_strings_pl.xtb index e5e7bb45..36947bd 100644 --- a/chromeos/strings/chromeos_strings_pl.xtb +++ b/chromeos/strings/chromeos_strings_pl.xtb
@@ -76,6 +76,7 @@ <translation id="2016697457005847575">Wykonaj czynności z instrukcji rozwiązywania problemów</translation> <translation id="202500043506723828">EID</translation> <translation id="2080070583977670716">Więcej ustawień</translation> +<translation id="2104796393919810494">Naprawa ukończona</translation> <translation id="2119172414412204879"><ph name="BOARD_NAME" />, wersja <ph name="MILESTONE_VERSION" /></translation> <translation id="2126937207024182736">Dostępne: <ph name="AVAILABLE_MEMORY" /> GB z <ph name="TOTAL_MEMORY" /> GB</translation> <translation id="2141644705054017895"><ph name="PERCENTAGE_VALUE" />%</translation> @@ -263,6 +264,7 @@ <translation id="5049856988445523908">Karta SIM zablokowana (<ph name="LOCK_TYPE" />)</translation> <translation id="5050042263972837708">Nazwa grupy</translation> <translation id="5051044138948155788">To jedyna strona. Pojawi się ekran rozpoczęcia skanowania.</translation> +<translation id="5061169534910302641">Aktualizuj wersję i uruchom ponownie</translation> <translation id="5088172560898466307">Nazwa hosta serwera</translation> <translation id="5089810972385038852">Stan</translation> <translation id="5142961317498132443">Uwierzytelnianie</translation>
diff --git a/chromeos/strings/chromeos_strings_pt-BR.xtb b/chromeos/strings/chromeos_strings_pt-BR.xtb index 4d2f1f5..230d21a 100644 --- a/chromeos/strings/chromeos_strings_pt-BR.xtb +++ b/chromeos/strings/chromeos_strings_pt-BR.xtb
@@ -63,6 +63,8 @@ <translation id="1759842336958782510">Chrome</translation> <translation id="1792647875738159689">Cancelando digitalização</translation> <translation id="1851218745569890714">Videoconferência</translation> +<translation id="1857850044054738019">Selecione esta opção caso o dispositivo volte para o estoque ou seja recondicionado e + distribuído para um novo cliente.</translation> <translation id="1874612839560830905">MTU</translation> <translation id="1887850431809612466">Revisão do hardware</translation> <translation id="1905710495812624430">O número máximo de tentativas permitidas foi excedido.</translation> @@ -197,6 +199,7 @@ <translation id="4244962993387259361">É necessário ter pelo menos 500 MB livres para executar um teste de memória. Para liberar espaço, acesse Configurações > Gerenciador de armazenamento.</translation> <translation id="4258281355379922695">Latência do HTTP</translation> <translation id="4271957103967917607">Ver em tela cheia</translation> +<translation id="4275799948641988986">Após o reparo, quem vai usar o dispositivo?</translation> <translation id="4297501883039923494">Parado (erro desconhecido)</translation> <translation id="4300073214558989"><ph name="IMAGE_COUNT" /> imagens</translation> <translation id="4378373042927530923">Não executada</translation> @@ -239,6 +242,7 @@ <translation id="4813345808229079766">Conexão</translation> <translation id="4832079907277790330">Selecionar a pasta no app Arquivos…</translation> <translation id="4835901797422965222">Não há redes ativas</translation> +<translation id="4839698083503556542">Crie seu próprio filme</translation> <translation id="484790837831576105">(Android) Resolução de DNS</translation> <translation id="4848429997038228357">EM EXECUÇÃO</translation> <translation id="4861758251032006121">{ATTEMPTS_LEFT,plural, =1{<ph name="ERROR_MESSAGE" /> {0} tentativa restante}one{<ph name="ERROR_MESSAGE" /> {0} tentativa restante}other{<ph name="ERROR_MESSAGE" /> {0} tentativas restantes}}</translation> @@ -412,6 +416,7 @@ <translation id="7297226631177386107">O firewall impediu a conexão a sites HTTPS</translation> <translation id="7302860742311162920">ICCID</translation> <translation id="7305884605064981971">EDGE</translation> +<translation id="7309920310754476121">O dispositivo vai mudar de proprietário</translation> <translation id="7319430975418800333">A3</translation> <translation id="7343649194310845056">Dispositivos de rede</translation> <translation id="7359657277149375382">Tipo de arquivo</translation> @@ -419,6 +424,9 @@ <translation id="7415801143053185905">A latência do HTTP está muito alta</translation> <translation id="7427315641433634153">MSCHAP</translation> <translation id="7435977162516949853">{NUMBER_OF_PAGES,plural, =1{Digitalização concluída. 1 página digitalizada}one{Digitalização concluída. {NUMBER_OF_PAGES} página digitalizada}other{Digitalização concluída. {NUMBER_OF_PAGES} páginas digitalizadas}}</translation> +<translation id="7451112128070628323">Selecione esta opção caso a propriedade do dispositivo continue a mesma. + Por exemplo, caso o dispositivo esteja sendo transferido para uma pessoa diferente + dentro da organização.</translation> <translation id="7469648432129124067">Portal detectado</translation> <translation id="7487067081878637334">Tecnologia</translation> <translation id="7490813197707563893">Endereço MAC</translation> @@ -544,6 +552,7 @@ <translation id="9073281213608662541">PAP</translation> <translation id="9074739597929991885">Bluetooth</translation> <translation id="9088306295921699330">Uso atual</translation> +<translation id="9095415590198785865">O dispositivo vai continuar com o mesmo proprietário</translation> <translation id="9095775724867566971">Pluginvm</translation> <translation id="910415269708673980">Atualizar tíquete para <ph name="PRINCIPAL_NAME" /></translation> <translation id="9106415115617144481">Digitalizando página <ph name="PAGE_NUMBER" /></translation>
diff --git a/chromeos/strings/chromeos_strings_pt-PT.xtb b/chromeos/strings/chromeos_strings_pt-PT.xtb index f58573b..83552950 100644 --- a/chromeos/strings/chromeos_strings_pt-PT.xtb +++ b/chromeos/strings/chromeos_strings_pt-PT.xtb
@@ -78,6 +78,7 @@ <translation id="2016697457005847575">Experimente passos de resolução de problemas</translation> <translation id="202500043506723828">EID</translation> <translation id="2080070583977670716">Mais definições</translation> +<translation id="2104796393919810494">Reparação concluída</translation> <translation id="2119172414412204879"><ph name="BOARD_NAME" />, versão <ph name="MILESTONE_VERSION" /></translation> <translation id="2126937207024182736"><ph name="AVAILABLE_MEMORY" /> GB de <ph name="TOTAL_MEMORY" /> GB disponíveis.</translation> <translation id="2141644705054017895"><ph name="PERCENTAGE_VALUE" />%</translation>
diff --git a/chromeos/strings/chromeos_strings_ru.xtb b/chromeos/strings/chromeos_strings_ru.xtb index 04d4692..6b740beb 100644 --- a/chromeos/strings/chromeos_strings_ru.xtb +++ b/chromeos/strings/chromeos_strings_ru.xtb
@@ -76,6 +76,7 @@ <translation id="2016697457005847575">Инструкции по устранению неполадок</translation> <translation id="202500043506723828">EID</translation> <translation id="2080070583977670716">Дополнительные настройки</translation> +<translation id="2104796393919810494">Неполадки устранены</translation> <translation id="2119172414412204879"><ph name="BOARD_NAME" />, версия <ph name="MILESTONE_VERSION" /></translation> <translation id="2126937207024182736">Доступно <ph name="AVAILABLE_MEMORY" /> из <ph name="TOTAL_MEMORY" /> ГБ.</translation> <translation id="2141644705054017895"><ph name="PERCENTAGE_VALUE" /> %</translation>
diff --git a/chromeos/strings/chromeos_strings_sv.xtb b/chromeos/strings/chromeos_strings_sv.xtb index ae5cdf1..1a5019e 100644 --- a/chromeos/strings/chromeos_strings_sv.xtb +++ b/chromeos/strings/chromeos_strings_sv.xtb
@@ -78,6 +78,7 @@ <translation id="2016697457005847575">Testa felsökningsstegen</translation> <translation id="202500043506723828">EID</translation> <translation id="2080070583977670716">Fler inställningar</translation> +<translation id="2104796393919810494">Reparationen är klar</translation> <translation id="2119172414412204879"><ph name="BOARD_NAME" />, version <ph name="MILESTONE_VERSION" /></translation> <translation id="2126937207024182736"><ph name="AVAILABLE_MEMORY" /> GB av <ph name="TOTAL_MEMORY" /> GB är tillgängligt</translation> <translation id="2141644705054017895"><ph name="PERCENTAGE_VALUE" /> %</translation>
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni index 11d788e..4324d4d 100644 --- a/chromeos/tast_control.gni +++ b/chromeos/tast_control.gni
@@ -70,10 +70,6 @@ "ui.DesktopControl", "ui.WindowControl", - # https://crbug.com/1269113: Flaky. - "graphics.KmsvncConnect", - "graphics.Smoke.chrome", - # https://crbug.com/1269876: Flaky. "arc.TextToSpeech",
diff --git a/components/BUILD.gn b/components/BUILD.gn index 1eead7dc..e896ae5e 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -471,7 +471,8 @@ if (is_chromeos_ash) { deps += [ - "//components/arc:unit_tests", + # TODO(b/206686476): Move this target to //ash/components:unit_tests + "//ash/components/arc:unit_tests", "//components/arc/mojom:unit_tests", "//components/arc/session:unit_tests", "//components/desks_storage:unit_tests",
diff --git a/components/OWNERS b/components/OWNERS index 1ff220e8..30f9fcb 100644 --- a/components/OWNERS +++ b/components/OWNERS
@@ -14,6 +14,7 @@ per-file autofill_strings.grdp=file://components/autofill/OWNERS per-file bookmark_bar_strings.grdp=file://components/bookmarks/OWNERS per-file browsing_data_strings.grdp=file://components/browsing_data/OWNERS +per-file content_creation_strings.grdp=file://components/content_creation/OWNERS per-file crash_strings.grdp=file://components/crash/OWNERS per-file dom_distiller_strings.grdp=file://components/dom_distiller/OWNERS per-file error_page_strings.grdp=file://components/error_page/OWNERS
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index 4bd5b81f..5ea3b0d2 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -7,45 +7,6 @@ static_library("arc") { sources = [ - "appfuse/arc_appfuse_bridge.cc", - "appfuse/arc_appfuse_bridge.h", - "audio/arc_audio_bridge.cc", - "audio/arc_audio_bridge.h", - "bluetooth/bluetooth_type_converters.cc", - "bluetooth/bluetooth_type_converters.h", - "camera/arc_camera_bridge.cc", - "camera/arc_camera_bridge.h", - "clipboard/arc_clipboard_bridge.cc", - "clipboard/arc_clipboard_bridge.h", - "compat_mode/arc_resize_lock_manager.cc", - "compat_mode/arc_resize_lock_manager.h", - "compat_mode/arc_resize_lock_pref_delegate.h", - "compat_mode/arc_splash_screen_dialog_view.cc", - "compat_mode/arc_splash_screen_dialog_view.h", - "compat_mode/arc_window_property_util.cc", - "compat_mode/arc_window_property_util.h", - "compat_mode/compat_mode_button_controller.cc", - "compat_mode/compat_mode_button_controller.h", - "compat_mode/metrics.cc", - "compat_mode/metrics.h", - "compat_mode/overlay_dialog.cc", - "compat_mode/overlay_dialog.h", - "compat_mode/resize_confirmation_dialog_view.cc", - "compat_mode/resize_confirmation_dialog_view.h", - "compat_mode/resize_toggle_menu.cc", - "compat_mode/resize_toggle_menu.h", - "compat_mode/resize_util.cc", - "compat_mode/resize_util.h", - "compat_mode/style/arc_color_provider.cc", - "compat_mode/style/arc_color_provider.h", - "compat_mode/touch_mode_mouse_rewriter.cc", - "compat_mode/touch_mode_mouse_rewriter.h", - "crash_collector/arc_crash_collector_bridge.cc", - "crash_collector/arc_crash_collector_bridge.h", - "dark_theme/arc_dark_theme_bridge.cc", - "dark_theme/arc_dark_theme_bridge.h", - "disk_quota/arc_disk_quota_bridge.cc", - "disk_quota/arc_disk_quota_bridge.h", "ime/arc_ime_bridge.h", "ime/arc_ime_bridge_impl.cc", "ime/arc_ime_bridge_impl.h", @@ -137,6 +98,7 @@ ] public_deps = [ + "//ash/components/arc:arc", "//ash/components/arc:arc_base", "//ash/components/arc:arc_metrics_constants", "//ash/components/arc:prefs", @@ -212,124 +174,3 @@ "//url:url", ] } - -source_set("unit_tests") { - testonly = true - sources = [ - "appfuse/arc_appfuse_bridge_unittest.cc", - "arc_features_parser_unittest.cc", - "arc_util_unittest.cc", - "audio/arc_audio_bridge_unittest.cc", - "bluetooth/bluetooth_mojom_traits_unittest.cc", - "bluetooth/bluetooth_type_converters_unittest.cc", - "camera/arc_camera_bridge_unittest.cc", - "clipboard/arc_clipboard_bridge_unittest.cc", - "compat_mode/arc_resize_lock_manager_unittest.cc", - "compat_mode/arc_splash_screen_dialog_view_unittest.cc", - "compat_mode/compat_mode_button_controller_unittest.cc", - "compat_mode/overlay_dialog_unittest.cc", - "compat_mode/resize_confirmation_dialog_view_unittest.cc", - "compat_mode/resize_toggle_menu_unittest.cc", - "compat_mode/resize_util_unittest.cc", - "compat_mode/touch_mode_mouse_rewriter_unittest.cc", - "crash_collector/arc_crash_collector_bridge_unittest.cc", - "dark_theme/arc_dark_theme_bridge_unittest.cc", - "disk_quota/arc_disk_quota_bridge_unittest.cc", - "enterprise/arc_data_remove_requested_pref_handler_unittest.cc", - "enterprise/arc_data_snapshotd_bridge_unittest.cc", - "enterprise/arc_data_snapshotd_manager_unittest.cc", - "enterprise/snapshot_hours_policy_service_unittest.cc", - "enterprise/snapshot_reboot_controller_unittest.cc", - "enterprise/snapshot_session_controller_unittest.cc", - "ime/arc_ime_service_unittest.cc", - "ime/key_event_result_receiver_unittest.cc", - "input_overlay/actions/action_move_key_unittest.cc", - "input_overlay/actions/action_tap_key_unittest.cc", - "input_overlay/actions/dependent_position_unittest.cc", - "input_overlay/actions/position_unittest.cc", - "input_overlay/arc_input_overlay_manager_unittest.cc", - "input_overlay/resources/input_overlay_resources_util_unittest.cc", - "input_overlay/touch_id_manager_unittest.cc", - "input_overlay/touch_injector_unittest.cc", - "intent_helper/activity_icon_loader_unittest.cc", - "intent_helper/arc_intent_helper_bridge_unittest.cc", - "intent_helper/custom_tab_unittest.cc", - "intent_helper/intent_filter_unittest.cc", - "intent_helper/link_handler_model_unittest.cc", - "lock_screen/arc_lock_screen_bridge_unittest.cc", - "media_session/arc_media_session_bridge_unittest.cc", - "memory/arc_memory_bridge_unittest.cc", - "memory_pressure/arc_memory_pressure_bridge_unittest.cc", - "metrics/arc_metrics_service_unittest.cc", - "metrics/stability_metrics_manager_unittest.cc", - "midis/arc_midis_bridge_unittest.cc", - "net/always_on_vpn_manager_unittest.cc", - "net/arc_net_host_impl_unittest.cc", - "pay/arc_payment_app_bridge_unittest.cc", - "power/arc_power_bridge_unittest.cc", - "property/arc_property_bridge_unittest.cc", - "rotation_lock/arc_rotation_lock_bridge_unittest.cc", - "sensor/arc_iio_sensor_bridge_unittest.cc", - "storage_manager/arc_storage_manager_unittest.cc", - "timer/arc_timer_bridge_unittest.cc", - "usb/usb_host_bridge_unittest.cc", - "video_accelerator/arc_video_accelerator_util_unittest.cc", - "volume_mounter/arc_volume_mounter_bridge_unittest.cc", - "wake_lock/arc_wake_lock_bridge_unittest.cc", - ] - - deps = [ - "//ash/components/arc:arc_test_support", - "//ash/constants", - "//ash/keyboard/ui", - "//ash/public/cpp", - "//base", - "//base/test:test_support", - "//chromeos/cryptohome:cryptohome", - "//chromeos/dbus:test_support", - "//chromeos/dbus/dlcservice", - "//chromeos/dbus/permission_broker", - "//chromeos/dbus/power", - "//chromeos/dbus/power:power_manager_proto", - "//chromeos/dbus/resourced:resourced", - "//chromeos/dbus/session_manager", - "//chromeos/dbus/session_manager:login_manager_proto", - "//chromeos/dbus/tpm_manager:tpm_manager", - "//chromeos/dbus/upstart", - "//chromeos/disks:test_support", - "//chromeos/network:test_support", - "//chromeos/policy:policy", - "//chromeos/ui/frame", - "//components/account_id", - "//components/arc/enterprise", - "//components/arc/media_session", - "//components/arc/video_accelerator:common", - "//components/exo", - "//components/exo:test_support", - "//components/keyed_service/content", - "//components/prefs:test_support", - "//components/session_manager/core:core", - "//components/user_manager", - "//components/user_manager:test_support", - "//content/public/common", - "//content/test:test_support", - "//device/bluetooth", - "//mojo/public/cpp/system:system", - "//services/device/public/cpp:test_support", - "//services/device/public/mojom", - "//testing/gmock", - "//testing/gtest", - "//ui/aura", - "//ui/aura:test_support", - "//ui/base:test_support", - "//ui/base/clipboard", - "//ui/base/ime", - "//ui/events", - "//ui/events:dom_keycode_converter", - "//ui/events:test_support", - "//ui/ozone", - "//ui/views", - "//ui/views:test_support", - "//url:url", - ] -}
diff --git a/components/arc/intent_helper/arc_intent_helper_bridge.cc b/components/arc/intent_helper/arc_intent_helper_bridge.cc index 78966554..d1b7a85 100644 --- a/components/arc/intent_helper/arc_intent_helper_bridge.cc +++ b/components/arc/intent_helper/arc_intent_helper_bridge.cc
@@ -8,6 +8,7 @@ #include <utility> #include "ash/components/arc/arc_browser_context_keyed_service_factory_base.h" +#include "ash/components/arc/audio/arc_audio_bridge.h" #include "ash/public/cpp/new_window_delegate.h" #include "ash/public/cpp/wallpaper/wallpaper_controller.h" #include "base/json/json_writer.h" @@ -17,7 +18,6 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "base/values.h" -#include "components/arc/audio/arc_audio_bridge.h" #include "components/arc/intent_helper/control_camera_app_delegate.h" #include "components/arc/intent_helper/intent_constants.h" #include "components/arc/intent_helper/open_url_delegate.h"
diff --git a/components/arc/mojom/BUILD.gn b/components/arc/mojom/BUILD.gn index 460f911..d131a67 100644 --- a/components/arc/mojom/BUILD.gn +++ b/components/arc/mojom/BUILD.gn
@@ -133,9 +133,9 @@ "//device/bluetooth/bluez/bluetooth_service_attribute_value_bluez.h", ] traits_private_headers = - [ "//components/arc/bluetooth/bluetooth_mojom_traits.h" ] + [ "//ash/components/arc/bluetooth/bluetooth_mojom_traits.h" ] traits_sources = - [ "//components/arc/bluetooth/bluetooth_mojom_traits.cc" ] + [ "//ash/components/arc/bluetooth/bluetooth_mojom_traits.cc" ] traits_public_deps = [ "//device/bluetooth", "//device/bluetooth/public/cpp",
diff --git a/components/autofill/core/browser/payments/payments_client_unittest.cc b/components/autofill/core/browser/payments/payments_client_unittest.cc index d55d07c..8abc5a7 100644 --- a/components/autofill/core/browser/payments/payments_client_unittest.cc +++ b/components/autofill/core/browser/payments/payments_client_unittest.cc
@@ -1545,6 +1545,7 @@ EXPECT_EQ(AutofillClient::PaymentsRpcResult::kSuccess, result_); assertIncludedInRequest("context_token"); + assertIncludedInRequest("external_customer_id"); assertIncludedInRequest("selected_idv_challenge_option"); assertIncludedInRequest("sms_otp_challenge_option"); // We should only set the challenge id. No need to send the masked phone
diff --git a/components/autofill/core/browser/payments/payments_requests/select_challenge_option_request.cc b/components/autofill/core/browser/payments/payments_requests/select_challenge_option_request.cc index def64a56..7494257 100644 --- a/components/autofill/core/browser/payments/payments_requests/select_challenge_option_request.cc +++ b/components/autofill/core/browser/payments/payments_requests/select_challenge_option_request.cc
@@ -39,6 +39,11 @@ base::Value context(base::Value::Type::DICTIONARY); context.SetKey("billable_service", base::Value(kUnmaskCardBillableServiceNumber)); + if (request_details_.billing_customer_number != 0) { + context.SetKey("customer_context", + BuildCustomerContextDictionary( + request_details_.billing_customer_number)); + } request_dict.SetKey("context", std::move(context)); base::Value selected_idv_method(base::Value::Type::DICTIONARY);
diff --git a/components/autofill_assistant/android/internal/java/res/layout/autofill_assistant_payment_request_section_divider.xml b/components/autofill_assistant/android/internal/java/res/layout/autofill_assistant_payment_request_section_divider.xml index 26910bf..e6982af 100644 --- a/components/autofill_assistant/android/internal/java/res/layout/autofill_assistant_payment_request_section_divider.xml +++ b/components/autofill_assistant/android/internal/java/res/layout/autofill_assistant_payment_request_section_divider.xml
@@ -7,6 +7,6 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="1dp" - android:background="@color/divider_line_bg_color" + android:background="@macro/divider_line_bg_color" android:layout_marginStart="@dimen/autofill_assistant_bottombar_horizontal_spacing" android:layout_marginEnd="@dimen/autofill_assistant_bottombar_horizontal_spacing"/>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_be.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_be.xtb index 795a2b5..8dd96de 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_be.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_be.xtb
@@ -56,6 +56,7 @@ <translation id="2402980924095424747"><ph name="MEGABYTES" /> МБ</translation> <translation id="2404630663942400771">{PERMISSIONS_SUMMARY_ALLOWED,plural, =1{Дазволены <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> і яшчэ <ph name="NUM_MORE" />}one{Дазволены <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> і яшчэ <ph name="NUM_MORE" />}few{Дазволены <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> і яшчэ <ph name="NUM_MORE" />}many{Дазволены <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> і яшчэ <ph name="NUM_MORE" />}other{Дазволены <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> і яшчэ <ph name="NUM_MORE" />}}</translation> <translation id="2434158240863470628">Спампоўванне завершана <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2442870161001914531">Заўсёды запытваць версію сайта для настольнага камп'ютара</translation> <translation id="2482878487686419369">Апавяшчэнні</translation> <translation id="2485422356828889247">Выдаліць</translation> <translation id="2490684707762498678">Пад кіраваннем праграмы "<ph name="APP_NAME" />"</translation> @@ -300,6 +301,7 @@ <translation id="8447861592752582886">Адклікаць дазвол на доступ да прылады</translation> <translation id="8451050538944905715">{NUM_SELECTED,plural, =1{Выкарыстоўваецца 1 файл cookie}one{Выкарыстоўваецца # файл cookie}few{Выкарыстоўваюцца # файлы cookie}many{Выкарыстоўваюцца # файлаў cookie}other{Выкарыстоўваюцца # файла cookie}}</translation> <translation id="8487700953926739672">Даступна па-за сеткай</translation> +<translation id="848952951823693243">Заўсёды запытваць версію сайта для мабільных прылад</translation> <translation id="851751545965956758">Блакіраваць сайтам падключэнне да прылад</translation> <translation id="8525306231823319788">Поўнаэкранны рэжым</translation> <translation id="857943718398505171">Дазволена (рэкамендуецца)</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_gl.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_gl.xtb index fc89816..0cf38c6 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_gl.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_gl.xtb
@@ -56,6 +56,7 @@ <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2404630663942400771">{PERMISSIONS_SUMMARY_ALLOWED,plural, =1{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> e <ph name="NUM_MORE" /> máis (permitidos)}other{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> e <ph name="NUM_MORE" /> máis (permitidos)}}</translation> <translation id="2434158240863470628">Completouse a descarga <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2442870161001914531">Solicitar sempre o sitio para ordenadores</translation> <translation id="2482878487686419369">Notificacións</translation> <translation id="2485422356828889247">Desinstalar</translation> <translation id="2490684707762498678">Xestionadas por <ph name="APP_NAME" /></translation> @@ -300,6 +301,7 @@ <translation id="8447861592752582886">Revoga o permiso do dispositivo</translation> <translation id="8451050538944905715">{NUM_SELECTED,plural, =1{1 cookie en uso}other{# cookies en uso}}</translation> <translation id="8487700953926739672">Dispoñible sen conexión</translation> +<translation id="848952951823693243">Solicitar sempre o sitio para móbiles</translation> <translation id="851751545965956758">Non permitir que os sitios se conecten aos dispositivos</translation> <translation id="8525306231823319788">Pantalla completa</translation> <translation id="857943718398505171">Permitido (recomendado)</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb index bdcac22..d6f48eb 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_hr.xtb
@@ -56,6 +56,7 @@ <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2404630663942400771">{PERMISSIONS_SUMMARY_ALLOWED,plural, =1{Odobrena su dopuštenja <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> i još <ph name="NUM_MORE" />}one{Odobrena su dopuštenja <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> i još <ph name="NUM_MORE" />}few{Odobrena su dopuštenja <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> i još <ph name="NUM_MORE" />}other{Odobrena su dopuštenja <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> i još <ph name="NUM_MORE" />}}</translation> <translation id="2434158240863470628">Preuzimanje je dovršeno: <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2442870161001914531">Uvijek zahtijevaj web-lokaciju za računalo</translation> <translation id="2482878487686419369">Obavijesti</translation> <translation id="2485422356828889247">Deinstaliraj</translation> <translation id="2490684707762498678">Upravlja: <ph name="APP_NAME" /></translation> @@ -300,6 +301,7 @@ <translation id="8447861592752582886">Opozovi odobrenje uređaja</translation> <translation id="8451050538944905715">{NUM_SELECTED,plural, =1{Koristi se jedan kolačić}one{Koristi se # kolačić}few{Koriste se # kolačića}other{Koristi se # kolačića}}</translation> <translation id="8487700953926739672">Dostupno izvanmrežno</translation> +<translation id="848952951823693243">Uvijek zahtijevaj web-lokaciju za mobilne uređaje</translation> <translation id="851751545965956758">Blokiraj povezivanje web-lokacija s uređajima</translation> <translation id="8525306231823319788">Cijeli zaslon</translation> <translation id="857943718398505171">Dopušteno (preporučeno)</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb index 846a4220..a642d81 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_iw.xtb
@@ -56,6 +56,7 @@ <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2404630663942400771">{PERMISSIONS_SUMMARY_ALLOWED,plural, =1{הוענקו ההרשאות <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> ועוד אחת (<ph name="NUM_MORE" />)}two{הוענקו ההרשאות <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> ועוד <ph name="NUM_MORE" />}many{הוענקו ההרשאות <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> ועוד <ph name="NUM_MORE" />}other{הוענקו ההרשאות <ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> ועוד <ph name="NUM_MORE" />}}</translation> <translation id="2434158240863470628">ההורדה הושלמה <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2442870161001914531">תמיד תוצג בקשה לגרסת האתר למחשב</translation> <translation id="2482878487686419369">התראות</translation> <translation id="2485422356828889247">הסרת התקנה</translation> <translation id="2490684707762498678">מנוהלות על-ידי <ph name="APP_NAME" /></translation> @@ -298,6 +299,7 @@ <translation id="8447861592752582886">שלילת הרשאות מכשיר</translation> <translation id="8451050538944905715">{NUM_SELECTED,plural, =1{קובץ cookie אחד נמצא בשימוש}two{# קובצי cookie נמצאים בשימוש}many{# קובצי cookie נמצאים בשימוש}other{# קובצי cookie נמצאים בשימוש}}</translation> <translation id="8487700953926739672">זמין אופליין</translation> +<translation id="848952951823693243">תמיד תוצג בקשה לגרסת האתר לנייד</translation> <translation id="851751545965956758">חסימת התחברות של אתרים אל התקנים</translation> <translation id="8525306231823319788">מסך מלא</translation> <translation id="857943718398505171">מותרת (מומלץ)</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb index 4c19c7c..bef3e19 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_pl.xtb
@@ -149,8 +149,10 @@ <translation id="5048398596102334565">Zezwalaj stronom na dostęp do czujników ruchu (zalecane)</translation> <translation id="5050380848339752099">Ta strona zamierza udostępnić informacje aplikacji poza trybem incognito.</translation> <translation id="5063480226653192405">Wykorzystanie</translation> +<translation id="509133520954049755">Żądaj wersji na komputery</translation> <translation id="5100237604440890931">Zwinięty – kliknij, by rozwinąć.</translation> <translation id="5123685120097942451">Karta incognito</translation> +<translation id="5134599672855298214">Żądaj wersji na urządzenia mobilne (zalecane)</translation> <translation id="5186036860380548585">Opcja dostępna u góry ekranu</translation> <translation id="5197729504361054390">Wybrane kontakty zostaną udostępnione witrynie <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" />.</translation> <translation id="5216942107514965959">Ostatnio używana dzisiaj</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_sv.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_sv.xtb index df73544..226b658 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_sv.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_sv.xtb
@@ -56,6 +56,7 @@ <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2404630663942400771">{PERMISSIONS_SUMMARY_ALLOWED,plural, =1{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> och <ph name="NUM_MORE" /> till tillåts}other{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> och <ph name="NUM_MORE" /> till tillåts}}</translation> <translation id="2434158240863470628">Nedladdningen är klar<ph name="SEPARATOR" /><ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2442870161001914531">Begär alltid datorversionen av webbplatsen</translation> <translation id="2482878487686419369">Aviseringar</translation> <translation id="2485422356828889247">Avinstallera</translation> <translation id="2490684707762498678">Hanteras av <ph name="APP_NAME" /></translation> @@ -300,6 +301,7 @@ <translation id="8447861592752582886">Återkalla enhetsbehörighet</translation> <translation id="8451050538944905715">{NUM_SELECTED,plural, =1{1 cookie används}other{# cookies används}}</translation> <translation id="8487700953926739672">Tillgänglig offline</translation> +<translation id="848952951823693243">Begär alltid mobilversionen</translation> <translation id="851751545965956758">Förhindra att webbplatser ansluter till enheter</translation> <translation id="8525306231823319788">Helskärm</translation> <translation id="857943718398505171">Tillåten (rekommenderas)</translation>
diff --git a/components/browser_ui/strings/android/translations/browser_ui_strings_tr.xtb b/components/browser_ui/strings/android/translations/browser_ui_strings_tr.xtb index c4762fb..13856a0 100644 --- a/components/browser_ui/strings/android/translations/browser_ui_strings_tr.xtb +++ b/components/browser_ui/strings/android/translations/browser_ui_strings_tr.xtb
@@ -56,6 +56,7 @@ <translation id="2402980924095424747"><ph name="MEGABYTES" /> MB</translation> <translation id="2404630663942400771">{PERMISSIONS_SUMMARY_ALLOWED,plural, =1{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> ve <ph name="NUM_MORE" /> tanesi için daha izin verildi}other{<ph name="PERMISSION_1" />, <ph name="PERMISSION_2" /> ve <ph name="NUM_MORE" /> tanesi için daha izin verildi}}</translation> <translation id="2434158240863470628">İndirme işlemi tamamlandı <ph name="SEPARATOR" /> <ph name="BYTES_DOWNLOADED" /></translation> +<translation id="2442870161001914531">Her zaman masaüstü sitesini iste</translation> <translation id="2482878487686419369">Bildirimler</translation> <translation id="2485422356828889247">Kaldır</translation> <translation id="2490684707762498678"><ph name="APP_NAME" /> tarafından yönetiliyor</translation> @@ -300,6 +301,7 @@ <translation id="8447861592752582886">Cihaz iznini iptal et</translation> <translation id="8451050538944905715">{NUM_SELECTED,plural, =1{1 çerez kullanımda}other{# çerez kullanımda}}</translation> <translation id="8487700953926739672">Çevrimdışı kullanılabilir</translation> +<translation id="848952951823693243">Her zaman mobil siteyi iste</translation> <translation id="851751545965956758">Sitelerin cihazlara bağlanmasını engelle</translation> <translation id="8525306231823319788">Tam ekran</translation> <translation id="857943718398505171">İzin verildi (önerilir)</translation>
diff --git a/components/browser_ui/styles/android/java/res/color/checkbox_tint.xml b/components/browser_ui/styles/android/java/res/color/checkbox_tint.xml index be2fd2c..0af044c6 100644 --- a/components/browser_ui/styles/android/java/res/color/checkbox_tint.xml +++ b/components/browser_ui/styles/android/java/res/color/checkbox_tint.xml
@@ -3,10 +3,11 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<!-- TODO(twellington): Add an item for disabled state. --> <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources" > + <item android:alpha="@dimen/default_disabled_alpha" + android:state_enabled="false" android:color="@color/control_normal_color" /> <item android:state_checked="true" android:color="@color/default_control_color_active" /> <item android:color="@color/control_normal_color"/> </selector>
diff --git a/components/browser_ui/styles/android/java/res/values-v27/styles.xml b/components/browser_ui/styles/android/java/res/values-v27/styles.xml index 84129ea..4cdb401 100644 --- a/components/browser_ui/styles/android/java/res/values-v27/styles.xml +++ b/components/browser_ui/styles/android/java/res/values-v27/styles.xml
@@ -6,7 +6,7 @@ <resources> <style name="ThemeOverlay.BrowserUI.Fullscreen" parent="Base.ThemeOverlay.BrowserUI.Fullscreen"> <item name="android:navigationBarColor">@color/bottom_system_nav_color</item> - <item name="android:navigationBarDividerColor">@color/bottom_system_nav_divider_color</item> + <item name="android:navigationBarDividerColor">@macro/bottom_system_nav_divider_color</item> <item name="android:windowLightNavigationBar">@bool/window_light_navigation_bar</item> </style> </resources>
diff --git a/components/browser_ui/styles/android/java/res/values/colors.xml b/components/browser_ui/styles/android/java/res/values/colors.xml index 055a22e4..865d6da 100644 --- a/components/browser_ui/styles/android/java/res/values/colors.xml +++ b/components/browser_ui/styles/android/java/res/values/colors.xml
@@ -29,7 +29,7 @@ <!-- Navigation bar colors --> <color name="bottom_system_nav_color">@color/toolbar_background_primary</color> - <color name="bottom_system_nav_divider_color">@color/divider_line_bg_color</color> + <macro name="bottom_system_nav_divider_color">@macro/divider_line_bg_color</macro> <color name="bottom_system_nav_divider_color_light">@color/divider_line_bg_color_light</color> <!-- This is the color that will appear on the system recents UI. It is a neutral background
diff --git a/components/browser_ui/styles/android/java/res/values/semantic_colors_dynamic.xml b/components/browser_ui/styles/android/java/res/values/semantic_colors_dynamic.xml index 39d96fe..7d21625 100644 --- a/components/browser_ui/styles/android/java/res/values/semantic_colors_dynamic.xml +++ b/components/browser_ui/styles/android/java/res/values/semantic_colors_dynamic.xml
@@ -8,7 +8,8 @@ <macro name="default_icon_color_accent1">?attr/colorPrimary</macro> <macro name="default_text_color">?attr/colorOnSurface</macro> <macro name="default_text_color_accent1">?attr/colorPrimary</macro> - <macro name="hairline_stroke_color">?attr/colorOutline</macro>--> + <macro name="hairline_stroke_color">?attr/colorOutline</macro> + <macro name="divider_line_bg_color">?attr/colorSurfaceVariant</macro>--> <!-- Temporarily holdback @color version. Use for checkin. --> <macro name="default_icon_color">@color/default_icon_color_baseline</macro> @@ -16,4 +17,5 @@ <macro name="default_text_color">@color/default_text_color_baseline</macro> <macro name="default_text_color_accent1">@color/default_text_color_blue</macro> <macro name="hairline_stroke_color">@color/hairline_stroke_color_baseline</macro> + <macro name="divider_line_bg_color">@color/divider_line_bg_color_baseline</macro> </resources>
diff --git a/components/browser_ui/styles/android/java/res/values/themes.xml b/components/browser_ui/styles/android/java/res/values/themes.xml index da988bb..4f931b6 100644 --- a/components/browser_ui/styles/android/java/res/values/themes.xml +++ b/components/browser_ui/styles/android/java/res/values/themes.xml
@@ -54,7 +54,6 @@ <!-- Custom semantic names --> <!-- Will support dynamic colors in the future. --> <item name="default_bg_color">@color/default_bg_color</item> - <item name="divider_line_bg_color">@color/divider_line_bg_color</item> <!-- Supports dynamic colors now. --> <item name="default_bg_color_dynamic">?attr/colorSurface</item> <item name="divider_line_bg_color_dynamic">?attr/colorSurfaceVariant</item> @@ -121,7 +120,6 @@ <item name="colorPrimaryContainer">@color/baseline_primary_100</item> <!-- Will support dynamic colors in the future. --> <item name="default_bg_color">@color/default_bg_color</item> - <item name="divider_line_bg_color">@color/divider_line_bg_color</item> <!-- Supports dynamic colors now. --> <item name="default_bg_color_dynamic">?attr/colorSurface</item> <item name="divider_line_bg_color_dynamic">?attr/colorSurfaceVariant</item>
diff --git a/components/browser_ui/styles/android/java/src/org/chromium/components/browser_ui/styles/SemanticColorUtils.java b/components/browser_ui/styles/android/java/src/org/chromium/components/browser_ui/styles/SemanticColorUtils.java index 0b6ad46..c540eea 100644 --- a/components/browser_ui/styles/android/java/src/org/chromium/components/browser_ui/styles/SemanticColorUtils.java +++ b/components/browser_ui/styles/android/java/src/org/chromium/components/browser_ui/styles/SemanticColorUtils.java
@@ -50,4 +50,24 @@ public static @ColorInt int getDefaultIconColorAccent1(Context context) { return resolve(R.attr.colorPrimary, R.color.default_icon_color_accent1_baseline, context); } + + /** Returns the semantic color value that corresponds to divider_line_bg_color. */ + public static @ColorInt int getDividerLineBgColor(Context context) { + return resolve(R.attr.colorSurfaceVariant, R.color.divider_line_bg_color_baseline, context); + } + + /** Returns the semantic color value that corresponds to bottom_system_nav_divider_color. */ + public static @ColorInt int getBottomSystemNavDividerColor(Context context) { + return getDividerLineBgColor(context); + } + + /** Returns the semantic color value that corresponds to overlay_panel_separator_line_color. */ + public static @ColorInt int getOverlayPanelSeparatorLineColor(Context context) { + return getDividerLineBgColor(context); + } + + /** Returns the semantic color value that corresponds to tab_grid_card_divider_tint_color. */ + public static @ColorInt int getTabGridCardDividerTintColor(Context context) { + return getDividerLineBgColor(context); + } }
diff --git a/components/components_strings.grd b/components/components_strings.grd index 5baff9f..61f4c20d 100644 --- a/components/components_strings.grd +++ b/components/components_strings.grd
@@ -321,7 +321,6 @@ <part file="printing_component_strings.grdp" /> <part file="privacy_sandbox_strings.grdp" /> <part file="reset_password_strings.grdp" /> - <part file="safe_browsing_strings.grdp" /> <part file="security_interstitials_strings.grdp" /> <part file="send_tab_to_self_strings.grdp" /> <part file="site_settings_strings.grdp" />
diff --git a/components/content_creation/reactions/DEPS b/components/content_creation/reactions/DEPS index f0bf3d9..354c1ba 100644 --- a/components/content_creation/reactions/DEPS +++ b/components/content_creation/reactions/DEPS
@@ -1,3 +1,5 @@ include_rules = [ "+components/keyed_service/core", + "+components/strings/grit", + "+ui/base", ]
diff --git a/components/content_creation/reactions/core/BUILD.gn b/components/content_creation/reactions/core/BUILD.gn index 7bdd74d7..a323a8b 100644 --- a/components/content_creation/reactions/core/BUILD.gn +++ b/components/content_creation/reactions/core/BUILD.gn
@@ -20,6 +20,8 @@ ":features", ":reaction_types", "//components/keyed_service/core", + "//components/strings:components_strings", + "//ui/base", ] }
diff --git a/components/content_creation/reactions/core/reaction_list_factory.cc b/components/content_creation/reactions/core/reaction_list_factory.cc index 22ee8e09..91883fd8 100644 --- a/components/content_creation/reactions/core/reaction_list_factory.cc +++ b/components/content_creation/reactions/core/reaction_list_factory.cc
@@ -7,6 +7,8 @@ #include "base/strings/stringprintf.h" #include "components/content_creation/reactions/core/reaction_metadata.h" #include "components/content_creation/reactions/core/reaction_types.h" +#include "components/strings/grit/components_strings.h" +#include "ui/base/l10n/l10n_util.h" namespace { @@ -28,30 +30,37 @@ namespace content_creation { std::vector<ReactionMetadata> BuildReactionMetadata() { - // TODO(crbug.com/1252182): Localize names. - // Note: All reactions will use the "clap" asset and thumbnail until the - // other assets have been uploaded to the server. return { - ReactionMetadata(ReactionType::CLAP, "Clap", MakeThumbnailUrl("clap"), - MakeReactionUrl("clap"), 24), - ReactionMetadata(ReactionType::GRIN, "Grin", MakeThumbnailUrl("grin"), - MakeReactionUrl("grin"), 48), - ReactionMetadata(ReactionType::FIRE, "Fire", MakeThumbnailUrl("fire"), - MakeReactionUrl("fire"), 48), - ReactionMetadata(ReactionType::EYES, "Eyes", MakeThumbnailUrl("eyes"), - MakeReactionUrl("eyes"), 48), - ReactionMetadata(ReactionType::EMOTIONAL, "Emotional", - MakeThumbnailUrl("emotional"), - MakeReactionUrl("emotional"), 48), - ReactionMetadata(ReactionType::SURPRISE, "Surprise", - MakeThumbnailUrl("surprise"), - MakeReactionUrl("surprise"), 48), - ReactionMetadata(ReactionType::THANKS, "Thanks", - MakeThumbnailUrl("thanks"), MakeReactionUrl("thanks"), - 24), - ReactionMetadata(ReactionType::UNSURE, "Unsure", - MakeThumbnailUrl("unsure"), MakeReactionUrl("unsure"), - 48), + ReactionMetadata( + ReactionType::CLAP, + l10n_util::GetStringUTF8(IDS_LIGHTWEIGHT_REACTIONS_CLAPPING), + MakeThumbnailUrl("clap"), MakeReactionUrl("clap"), 24), + ReactionMetadata( + ReactionType::GRIN, + l10n_util::GetStringUTF8(IDS_LIGHTWEIGHT_REACTIONS_GRINNING), + MakeThumbnailUrl("grin"), MakeReactionUrl("grin"), 48), + ReactionMetadata(ReactionType::FIRE, + l10n_util::GetStringUTF8(IDS_LIGHTWEIGHT_REACTIONS_FIRE), + MakeThumbnailUrl("fire"), MakeReactionUrl("fire"), 48), + ReactionMetadata(ReactionType::EYES, + l10n_util::GetStringUTF8(IDS_LIGHTWEIGHT_REACTIONS_EYES), + MakeThumbnailUrl("eyes"), MakeReactionUrl("eyes"), 48), + ReactionMetadata( + ReactionType::EMOTIONAL, + l10n_util::GetStringUTF8(IDS_LIGHTWEIGHT_REACTIONS_LOUDLY_CRYING), + MakeThumbnailUrl("emotional"), MakeReactionUrl("emotional"), 48), + ReactionMetadata( + ReactionType::SURPRISE, + l10n_util::GetStringUTF8(IDS_LIGHTWEIGHT_REACTIONS_FLUSHED), + MakeThumbnailUrl("surprise"), MakeReactionUrl("surprise"), 48), + ReactionMetadata( + ReactionType::THANKS, + l10n_util::GetStringUTF8(IDS_LIGHTWEIGHT_REACTIONS_FOLDED_HANDS), + MakeThumbnailUrl("thanks"), MakeReactionUrl("thanks"), 24), + ReactionMetadata( + ReactionType::UNSURE, + l10n_util::GetStringUTF8(IDS_LIGHTWEIGHT_REACTIONS_THINKING), + MakeThumbnailUrl("unsure"), MakeReactionUrl("unsure"), 48), }; }
diff --git a/components/content_creation_strings.grdp b/components/content_creation_strings.grdp index 7c97e48..cace242 100644 --- a/components/content_creation_strings.grdp +++ b/components/content_creation_strings.grdp
@@ -33,6 +33,39 @@ <message name="IDS_CONTENT_CREATION_NOTE_TEMPLATE_NAME_DREAMY" desc="Name for a styled template which creates a nice looking note from text. The name is loosely connected with the font and color of the template. [CHAR_LIMIT=25]"> Dreamy </message> + + <!-- Lightweight Reactions names, currently only used on Android. --> + <message name="IDS_LIGHTWEIGHT_REACTIONS_CLAPPING" is_accessibility_with_no_ui="true" desc="The accessibility text to read when the clapping reaction is selected."> + Clapping + </message> + + <message name="IDS_LIGHTWEIGHT_REACTIONS_GRINNING" is_accessibility_with_no_ui="true" desc="The accessibility text to read when the grinning reaction is selected."> + Grinning + </message> + + <message name="IDS_LIGHTWEIGHT_REACTIONS_FIRE" is_accessibility_with_no_ui="true" desc="The accessibility text to read when the fire reaction is selected."> + Fire + </message> + + <message name="IDS_LIGHTWEIGHT_REACTIONS_EYES" is_accessibility_with_no_ui="true" desc="The accessibility text to read when the eyes reaction is selected."> + Eyes + </message> + + <message name="IDS_LIGHTWEIGHT_REACTIONS_LOUDLY_CRYING" is_accessibility_with_no_ui="true" desc="The accessibility text to read when the loudly crying reaction is selected."> + Loudly Crying + </message> + + <message name="IDS_LIGHTWEIGHT_REACTIONS_FLUSHED" is_accessibility_with_no_ui="true" desc="The accessibility text to read when the flushed reaction is selected."> + Flushed + </message> + + <message name="IDS_LIGHTWEIGHT_REACTIONS_FOLDED_HANDS" is_accessibility_with_no_ui="true" desc="The accessibility text to read when the folded hands reaction is selected."> + Folded Hands + </message> + + <message name="IDS_LIGHTWEIGHT_REACTIONS_THINKING" is_accessibility_with_no_ui="true" desc="The accessibility text to read when the thinking reaction is selected."> + Thinking + </message> </if> </grit-part>
diff --git a/components/discardable_memory/client/client_discardable_shared_memory_manager.cc b/components/discardable_memory/client/client_discardable_shared_memory_manager.cc index f8141b23..46717897 100644 --- a/components/discardable_memory/client/client_discardable_shared_memory_manager.cc +++ b/components/discardable_memory/client/client_discardable_shared_memory_manager.cc
@@ -561,6 +561,11 @@ "ClientDiscardableSharedMemoryManager::" "AllocateLockedDiscardableSharedMemory", "size", size, "id", id); + static crash_reporter::CrashKeyString<24> + discardable_memory_ipc_requested_size( + "discardable-memory-ipc-requested-size"); + static crash_reporter::CrashKeyString<24> discardable_memory_ipc_error_cause( + "discardable-memory-ipc-error-cause"); base::UnsafeSharedMemoryRegion region; base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, @@ -578,14 +583,22 @@ // This is likely address space exhaustion in the the browser process. We // don't want to crash the browser process for that, which is why the check // is here, and not there. - if (!region.IsValid()) + if (!region.IsValid()) { + discardable_memory_ipc_error_cause.Set("browser side"); + discardable_memory_ipc_requested_size.Set(base::NumberToString(size)); return nullptr; + } auto memory = std::make_unique<base::DiscardableSharedMemory>(std::move(region)); - if (!memory->Map(size)) + if (!memory->Map(size)) { + discardable_memory_ipc_error_cause.Set("client side"); + discardable_memory_ipc_requested_size.Set(base::NumberToString(size)); return nullptr; + } + discardable_memory_ipc_error_cause.Clear(); + discardable_memory_ipc_requested_size.Clear(); return memory; }
diff --git a/components/exo/text_input.cc b/components/exo/text_input.cc index f50ce27..951d0743 100644 --- a/components/exo/text_input.cc +++ b/components/exo/text_input.cc
@@ -86,6 +86,11 @@ const gfx::Range& cursor_pos) { surrounding_text_ = text; cursor_pos_ = cursor_pos; + + // TODO(b/206068262): Consider introducing an API to notify surrounding text + // update explicitly. + if (input_method_) + input_method_->OnCaretBoundsChanged(this); } void TextInput::SetTypeModeFlags(ui::TextInputType type,
diff --git a/components/exo/text_input_unittest.cc b/components/exo/text_input_unittest.cc index d4b67bae..6c22965 100644 --- a/components/exo/text_input_unittest.cc +++ b/components/exo/text_input_unittest.cc
@@ -325,6 +325,8 @@ } TEST_F(TextInputTest, SurroundingText) { + TestingInputMethodObserver observer(GetInputMethod()); + gfx::Range range; EXPECT_FALSE(text_input()->GetTextRange(&range)); EXPECT_FALSE(text_input()->GetCompositionTextRange(&range)); @@ -332,6 +334,9 @@ std::u16string got_text; EXPECT_FALSE(text_input()->GetTextFromRange(gfx::Range(0, 1), &got_text)); + text_input()->Activate(surface()); + + EXPECT_CALL(observer, OnCaretBoundsChanged(text_input())).Times(1); std::u16string text = u"surrounding\u3000text"; text_input()->SetSurroundingText(text, gfx::Range(11, 12));
diff --git a/components/flags_ui/resources/flags.css b/components/flags_ui/resources/flags.css index 43dfef4..8ee6c6be 100644 --- a/components/flags_ui/resources/flags.css +++ b/components/flags_ui/resources/flags.css
@@ -463,18 +463,10 @@ /* Bottom padding should be greater than evaluated height of needs-restart */ padding-bottom: 200px; position: relative; - /* iOS does not show unsupported experiments. */ -<if expr="not is_ios"> - width: 200%; -</if> } -.tabs li:nth-child(2) .tab-content { - margin-inline-start: -100%; -} - -.selected .tab-content, -.selected .tab-content .template { +.tab-content.selected, +.tab-content.selected .template { display: block; }
diff --git a/components/flags_ui/resources/flags.html b/components/flags_ui/resources/flags.html index 2eedb39..25c867f 100644 --- a/components/flags_ui/resources/flags.html +++ b/components/flags_ui/resources/flags.html
@@ -76,149 +76,153 @@ <a href="https://chrome.com/dev">dev channel</a> </span> </p> - <ul class="tabs" role="tablist" aria-owns="tab-available tab-unavailable"> - <li class="selected"> + <ul class="tabs" role="tablist"> + <li class="selected" role="tab"> <a href="#tab-content-available" id="tab-available" class="tab" role="tab" aria-selected="true" aria-controls="panel1" tabindex="5">$i18n{available}</a> - <div id="tab-content-available" class="tab-content" - role="tabpanel" aria-labelledby="tab-available" aria-hidden="false"> - </div> - <div id="tab-content-available-template" class="template hidden"> - <!-- Non default experiments. --> - <div jsselect="supportedFeatures" - jsvalues="id:internal_name; class: is_default ? 'hidden' : 'experiment'" - jsdisplay="!is_default"> - <div class="experiment-default" - jsvalues="class: is_default ? 'experiment-default flex-container' - : 'experiment-switched flex-container'"> - <div class="flex"> - <h3 class="experiment-name" jscontent="name" - jsvalues="title: is_default ? '' : '$i18n{experiment-enabled}'; - id:internal_name + '_name'"></h3> - <p> - <span jsvalues=".textContent:description"></span> – - <span class="platforms" jscontent="supported_platforms.join(', ')"></span> - </p> - <div jsdisplay="origin_list_value!==null"> - <textarea class="experiment-origin-list-value" - jsvalues=".internal_name:internal_name; .value:origin_list_value; - aria-labelledby:internal_name + '_name'" - tabindex="7"></textarea> - </div> - <a class="permalink" jsvalues="href: '#' + internal_name" - jscontent="'#' + internal_name" tabindex="7"></a> - </div> - <div class="flex experiment-actions"> - <div jsdisplay="options && options.length > 0"> - <select class="experiment-select" tabindex="7" - jsvalues=".internal_name:internal_name;.disabled:!enabled; - aria-labelledby:internal_name + '_name'"> - <option jsvalues=".selected:selected;" - jsselect="options" - jscontent="description"> - </option> - </select> - </div> - <select class="experiment-enable-disable" tabindex="7" - jsdisplay="enabled !== undefined" - jsvalues=".internal_name:internal_name; - aria-labelledby:internal_name + '_name'"> - <option jsvalues=".selected:!enabled; data-default: enabled ? 1 : 0" - value="disabled">$i18n{disabled}</option> - <option jsvalues=".selected:enabled; data-default: !enabled ? 1 : 0" - value="enabled">$i18n{enabled}</option> - </select> - </div> - </div> - </div> - <!-- Experiments with default settings. --> - <div class="experiment" jsselect="supportedFeatures" - jsvalues="id:internal_name; class: is_default ? 'experiment' : 'hidden'" - jsdisplay="is_default"> - <div class="experiment-default" - jsvalues="class: is_default ? 'experiment-default flex-container' - : 'experiment-switched flex-container'"> - <div class="flex"> - <h3 class="experiment-name" jscontent="name" - jsvalues="title: is_default ? '' : '$i18n{experiment-enabled}'; - id:internal_name + '_name'"></h3> - <p> - <span jsvalues=".textContent:description"></span> – - <span class="platforms" jscontent="supported_platforms.join(', ')"></span> - </p> - <div jsdisplay="origin_list_value!==null"> - <textarea class="experiment-origin-list-value" - jsvalues=".internal_name:internal_name; .value:origin_list_value; - aria-labelledby:internal_name + '_name'" - tabindex="7"></textarea> - </div> - <a class="permalink" jsvalues="href: '#' + internal_name" - jscontent="'#' + internal_name" tabindex="7"></a> - </div> - <div class="flex experiment-actions"> - <div jsdisplay="options && options.length > 0"> - <select class="experiment-select" tabindex="7" - jsvalues=".internal_name:internal_name;.disabled:!enabled; - aria-labelledby:internal_name + '_name'"> - <option jsvalues=".selected:selected;" - jsselect="options" - jscontent="description"> - </option> - </select> - </div> - <!-- Represent enabled / disabled options in a drop down --> - <select class="experiment-enable-disable" tabindex="7" - jsdisplay="enabled !== undefined" - jsvalues=".internal_name:internal_name; - aria-labelledby:internal_name + '_name'"> - <option jsvalues=".selected:!enabled; data-default:!enabled ? 1 : 0" - value="disabled">$i18n{disabled}</option> - <option jsvalues=".selected:enabled; data-default: enabled ? 1 : 0" - value="enabled">$i18n{enabled}</option> - </select> - </div> - </div> - </div> - <div class="no-match hidden" role="alert">$i18n{no-results}</div> - </div> </li> <!-- Unsupported experiments are not shown on iOS --> <if expr="not is_ios"> - <li> + <li role="tab"> <a href="#tab-content-unavailable" id="tab-unavailable" class="tab" role="tab" aria-selected="false" aria-controls="panel2" tabindex="6">$i18n{unavailable}</a> - <div id="tab-content-unavailable" class="tab-content" - role="tabpanel" aria-labelledby="tab-unavailable" aria-hidden="false"> - <div class="experiment" - jsselect="unsupportedFeatures" - jsvalues="id:internal_name"> - <div class="experiment-default flex-container" - jsvalues="class: is_default ? 'experiment-default flex-container' - : 'experiment-switched flex-container'"> - <div class="flex"> - <h3 class="experiment-name" - jscontent="name"></h3> - <p> - <span jsvalues=".textContent:description"></span> - <span class="platforms" jscontent="supported_platforms.join(', ')"></span> - </p> - <a class="permalink" - jsvalues="href: '#' + internal_name" - jscontent="'#' + internal_name" tabindex="9"></a> - </div> - <div class="flex experiment-actions">$i18n{not-available-platform}</div> - </div> - </div> - <div class="no-match hidden" role="alert"> - $i18n{no-results} - </div> - </div> </li> </if> </ul> + <div id="tabpanels"> + <div id="tab-content-available" class="tab-content selected" + role="tabpanel" aria-labelledby="tab-available" aria-hidden="false"> + </div> + <div id="tab-content-available-template" class="template hidden"> + <!-- Non default experiments. --> + <div jsselect="supportedFeatures" + jsvalues="id:internal_name; class: is_default ? 'hidden' : 'experiment'" + jsdisplay="!is_default"> + <div class="experiment-default" + jsvalues="class: is_default ? 'experiment-default flex-container' + : 'experiment-switched flex-container'"> + <div class="flex"> + <h3 class="experiment-name" jscontent="name" + jsvalues="title: is_default ? '' : '$i18n{experiment-enabled}'; + id:internal_name + '_name'"></h3> + <p> + <span jsvalues=".textContent:description"></span> – + <span class="platforms" jscontent="supported_platforms.join(', ')"></span> + </p> + <div jsdisplay="origin_list_value!==null"> + <textarea class="experiment-origin-list-value" + jsvalues=".internal_name:internal_name; .value:origin_list_value; + aria-labelledby:internal_name + '_name'" + tabindex="7"></textarea> + </div> + <a class="permalink" jsvalues="href: '#' + internal_name" + jscontent="'#' + internal_name" tabindex="7"></a> + </div> + <div class="flex experiment-actions"> + <div jsdisplay="options && options.length > 0"> + <select class="experiment-select" tabindex="7" + jsvalues=".internal_name:internal_name;.disabled:!enabled; + aria-labelledby:internal_name + '_name'"> + <option jsvalues=".selected:selected;" + jsselect="options" + jscontent="description"> + </option> + </select> + </div> + <select class="experiment-enable-disable" tabindex="7" + jsdisplay="enabled !== undefined" + jsvalues=".internal_name:internal_name; + aria-labelledby:internal_name + '_name'"> + <option jsvalues=".selected:!enabled; data-default: enabled ? 1 : 0" + value="disabled">$i18n{disabled}</option> + <option jsvalues=".selected:enabled; data-default: !enabled ? 1 : 0" + value="enabled">$i18n{enabled}</option> + </select> + </div> + </div> + </div> + <!-- Experiments with default settings. --> + <div class="experiment" jsselect="supportedFeatures" + jsvalues="id:internal_name; class: is_default ? 'experiment' : 'hidden'" + jsdisplay="is_default"> + <div class="experiment-default" + jsvalues="class: is_default ? 'experiment-default flex-container' + : 'experiment-switched flex-container'"> + <div class="flex"> + <h3 class="experiment-name" jscontent="name" + jsvalues="title: is_default ? '' : '$i18n{experiment-enabled}'; + id:internal_name + '_name'"></h3> + <p> + <span jsvalues=".textContent:description"></span> – + <span class="platforms" jscontent="supported_platforms.join(', ')"></span> + </p> + <div jsdisplay="origin_list_value!==null"> + <textarea class="experiment-origin-list-value" + jsvalues=".internal_name:internal_name; .value:origin_list_value; + aria-labelledby:internal_name + '_name'" + tabindex="7"></textarea> + </div> + <a class="permalink" jsvalues="href: '#' + internal_name" + jscontent="'#' + internal_name" tabindex="7"></a> + </div> + <div class="flex experiment-actions"> + <div jsdisplay="options && options.length > 0"> + <select class="experiment-select" tabindex="7" + jsvalues=".internal_name:internal_name;.disabled:!enabled; + aria-labelledby:internal_name + '_name'"> + <option jsvalues=".selected:selected;" + jsselect="options" + jscontent="description"> + </option> + </select> + </div> + <!-- Represent enabled / disabled options in a drop down --> + <select class="experiment-enable-disable" tabindex="7" + jsdisplay="enabled !== undefined" + jsvalues=".internal_name:internal_name; + aria-labelledby:internal_name + '_name'"> + <option jsvalues=".selected:!enabled; data-default:!enabled ? 1 : 0" + value="disabled">$i18n{disabled}</option> + <option jsvalues=".selected:enabled; data-default: enabled ? 1 : 0" + value="enabled">$i18n{enabled}</option> + </select> + </div> + </div> + </div> + <div class="no-match hidden" role="alert">$i18n{no-results}</div> + </div> +<if expr="not is_ios"> + <div id="tab-content-unavailable" class="tab-content" + role="tabpanel" aria-labelledby="tab-unavailable" aria-hidden="false"> + <div class="experiment" + jsselect="unsupportedFeatures" + jsvalues="id:internal_name"> + <div class="experiment-default flex-container" + jsvalues="class: is_default ? 'experiment-default flex-container' + : 'experiment-switched flex-container'"> + <div class="flex"> + <h3 class="experiment-name" + jscontent="name"></h3> + <p> + <span jsvalues=".textContent:description"></span> + <span class="platforms" jscontent="supported_platforms.join(', ')"></span> + </p> + <a class="permalink" + jsvalues="href: '#' + internal_name" + jscontent="'#' + internal_name" tabindex="9"></a> + </div> + <div class="flex experiment-actions">$i18n{not-available-platform}</div> + </div> + </div> + <div class="no-match hidden" role="alert"> + $i18n{no-results} + </div> + </div> +</if> + </div> <div id="needs-restart" jsvalues="class:needsRestart ? 'show' : ''"> <div class="flex-container"> <div class="flex restart-notice" jstcache="0">$i18n{flagsRestartNotice}</div>
diff --git a/components/flags_ui/resources/flags.js b/components/flags_ui/resources/flags.js index 2646f78..f01e11fd 100644 --- a/components/flags_ui/resources/flags.js +++ b/components/flags_ui/resources/flags.js
@@ -28,6 +28,33 @@ experimentalFeaturesResolver = resolve; }); +/** @const {!Array<!Object<string, !HTMLElement>>} */ +const tabs = [ + { + tabEl: document.querySelector('#tab-available'), + panelEl: document.querySelector('#tab-content-available'), + }, + // <if expr="not is_ios"> + { + tabEl: document.querySelector('#tab-unavailable'), + panelEl: document.querySelector('#tab-content-unavailable'), + }, + // </if> +]; + +/** + * Toggles necessary attributes to display selected tab. + * @param {!HTMLElement} selectedTabEl + */ +function selectTab(selectedTabEl) { + for (const tab of tabs) { + const isSelectedTab = tab.tabEl === selectedTabEl; + tab.tabEl.parentNode.classList.toggle('selected', isSelectedTab); + tab.tabEl.setAttribute('aria-selected', isSelectedTab); + tab.panelEl.classList.toggle('selected', isSelectedTab); + } +} + /** * This variable structure is here to document the structure that the template * expects to correctly populate the page. @@ -104,21 +131,16 @@ } // Tab panel selection. - const tabEls = document.getElementsByClassName('tab'); - for (let i = 0; i < tabEls.length; ++i) { - tabEls[i].addEventListener('click', function(e) { + for (const tab of tabs) { + tab.tabEl.addEventListener('click', e => { e.preventDefault(); - for (let j = 0; j < tabEls.length; ++j) { - tabEls[j].parentNode.classList.toggle('selected', tabEls[j] === this); - tabEls[j].setAttribute('aria-selected', tabEls[j] === this); - } - FlagSearch.getInstance().announceSearchResults(); + selectTab(tab.tabEl); }); } const smallScreenCheck = window.matchMedia('(max-width: 480px)'); // Toggling of experiment description overflow content on smaller screens. - if(smallScreenCheck.matches){ + if (smallScreenCheck.matches) { elements = document.querySelectorAll('.experiment .flex:first-child'); for (const element of elements) { element.onclick = () => element.classList.toggle('expand'); @@ -172,13 +194,12 @@ // Highlight the referenced element. el.classList.add('referenced'); + // <if expr="not is_ios"> // Switch to unavailable tab if the flag is in this section. if ($('tab-content-unavailable').contains(el)) { - $('tab-available').parentNode.classList.remove('selected'); - $('tab-available').setAttribute('aria-selected', 'false'); - $('tab-unavailable').parentNode.classList.add('selected'); - $('tab-unavailable').setAttribute('aria-selected', 'true'); + selectTab(/** @type {!HTMLElement} */ ($('tab-unavailable'))); } + // </if> el.scrollIntoView(); } } @@ -201,7 +222,7 @@ /** * Cause a text string to be announced by screen readers * @param {string} text The text that should be announced. -*/ + */ function announceStatus(text) { $('screen-reader-status-message').textContent = ''; setTimeout(function() { @@ -230,10 +251,10 @@ $('needs-restart').classList.toggle('show', show); const restartButton = $('experiment-restart-button'); if (restartButton) { - restartButton.setAttribute("tabindex", show ? '9' : '-1'); + restartButton.setAttribute('tabindex', show ? '9' : '-1'); } if (show) { - $('needs-restart').setAttribute("role", "alert"); + $('needs-restart').setAttribute('role', 'alert'); } } @@ -640,16 +661,10 @@ return; } - let tabAvailable = true; - const tabEls = document.getElementsByClassName('tab'); - for (let i = 0; i < tabEls.length; ++i) { - if (tabEls[i].parentNode.classList.contains('selected')) { - tabAvailable = tabEls[i].id === 'tab-available'; - } - } - const seletedTabId = - tabAvailable ? '#tab-content-available' : '#tab-content-unavailable'; - const queryString = seletedTabId + ' .experiment:not(.hidden)'; + const selectedTab = + tabs.find(tab => tab.panelEl.classList.contains('selected')); + const selectedTabId = selectedTab.panelEl.id; + const queryString = `#${selectedTabId} .experiment:not(.hidden)`; const total = document.querySelectorAll(queryString).length; if (total) { announceStatus(
diff --git a/components/history/content/browser/web_contents_top_sites_observer.cc b/components/history/content/browser/web_contents_top_sites_observer.cc index 1e938e1..6e8389c 100644 --- a/components/history/content/browser/web_contents_top_sites_observer.cc +++ b/components/history/content/browser/web_contents_top_sites_observer.cc
@@ -31,9 +31,9 @@ // an existing navigation entry. if (top_sites_ && load_details.is_main_frame && (load_details.type == - content::NavigationType::NAVIGATION_TYPE_NEW_ENTRY || - load_details.type == - content::NavigationType::NAVIGATION_TYPE_EXISTING_ENTRY)) { + content::NavigationType::NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY || + load_details.type == content::NavigationType:: + NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY)) { // Only report the Virtual URL. The virtual URL, when it differs from the // actual URL that is loaded in the renderer, is the one meant to be shown // to the user in all UI.
diff --git a/components/messages/android/internal/java/res/layout/message_banner_view.xml b/components/messages/android/internal/java/res/layout/message_banner_view.xml index 984226f..b168483 100644 --- a/components/messages/android/internal/java/res/layout/message_banner_view.xml +++ b/components/messages/android/internal/java/res/layout/message_banner_view.xml
@@ -25,10 +25,9 @@ <ImageView android:id="@+id/message_icon" app:tint="@macro/default_icon_color_accent1" - android:paddingStart="@dimen/message_icon_padding" - android:paddingEnd="@dimen/message_icon_padding" + android:layout_marginHorizontal="@dimen/message_icon_margin" android:layout_width="wrap_content" - android:layout_height="24dp" + android:layout_height="@dimen/message_icon_size" android:importantForAccessibility="no" /> <LinearLayout @@ -72,7 +71,7 @@ android:id="@+id/message_divider" android:layout_marginTop="@dimen/message_divider_margin" android:layout_marginBottom="@dimen/message_divider_margin" - android:background="@color/divider_line_bg_color" + android:background="@macro/divider_line_bg_color" android:visibility="gone" android:importantForAccessibility="no" android:layout_width="1dp"
diff --git a/components/messages/android/internal/java/res/values/dimens.xml b/components/messages/android/internal/java/res/values/dimens.xml index 26b04f4..5b748f5e9 100644 --- a/components/messages/android/internal/java/res/values/dimens.xml +++ b/components/messages/android/internal/java/res/values/dimens.xml
@@ -12,7 +12,9 @@ <!-- Min width to ensure the min touchable size. --> <dimen name="message_banner_button_width">44dp</dimen> <dimen name="message_primary_button_max_width">100dp</dimen> - <dimen name="message_icon_padding">12dp</dimen> + <dimen name="message_icon_margin">12dp</dimen> + <dimen name="message_icon_size">24dp</dimen> + <dimen name="message_icon_size_large">36dp</dimen> <dimen name="message_divider_margin">12dp</dimen> <dimen name="message_shadow_lateral_margin">12dp</dimen> <dimen name="message_shadow_bottom_margin">16dp</dimen>
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerRenderTest.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerRenderTest.java index fa721c77..bd8332da 100644 --- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerRenderTest.java +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerRenderTest.java
@@ -5,7 +5,10 @@ package org.chromium.components.messages; import android.app.Activity; +import android.graphics.Bitmap; +import android.graphics.Color; import android.graphics.Typeface; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.text.SpannableString; import android.text.Spanned; @@ -188,4 +191,64 @@ () -> { getActivity().setContentView(view, params); }); mRenderTestRule.render(view, "message_banner_layout_after_clearing_description"); } + + @Test + @SmallTest + @Feature({"RenderTest", "Messages"}) + public void testLargeIcon() throws Exception { + Activity activity = getActivity(); + Drawable drawable = ApiCompatibilityUtils.getDrawable( + activity.getResources(), android.R.drawable.ic_delete); + PropertyModel model = new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS) + .with(MessageBannerProperties.MESSAGE_IDENTIFIER, + MessageIdentifier.TEST_MESSAGE) + .with(MessageBannerProperties.ICON, drawable) + .with(MessageBannerProperties.TITLE, "Primary Title") + .with(MessageBannerProperties.DESCRIPTION, "Secondary Title") + .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, "Action") + .with(MessageBannerProperties.LARGE_ICON, true) + .build(); + MessageBannerView view = (MessageBannerView) LayoutInflater.from(activity).inflate( + R.layout.message_banner_view, null, false); + PropertyModelChangeProcessor.create(model, view, MessageBannerViewBinder::bind); + LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, + activity.getResources().getDimensionPixelSize(R.dimen.message_banner_height)); + + TestThreadUtils.runOnUiThreadBlocking( + () -> { getActivity().setContentView(view, params); }); + mRenderTestRule.render(view, "message_banner_large_icon"); + } + + @Test + @SmallTest + @Feature({"RenderTest", "Messages"}) + public void testLargeIconWithRadius() throws Exception { + Activity activity = getActivity(); + Bitmap.Config conf = Bitmap.Config.ARGB_8888; + int w = activity.getResources().getDimensionPixelSize(R.dimen.message_icon_size_large); + Bitmap bmp = Bitmap.createBitmap(w, w, conf); + bmp.eraseColor(Color.RED); + BitmapDrawable drawable = new BitmapDrawable(bmp); + int radius = activity.getResources().getDimensionPixelSize(R.dimen.message_icon_size) / 2; + PropertyModel model = + new PropertyModel.Builder(MessageBannerProperties.ALL_KEYS) + .with(MessageBannerProperties.MESSAGE_IDENTIFIER, + MessageIdentifier.TEST_MESSAGE) + .with(MessageBannerProperties.ICON, drawable) + .with(MessageBannerProperties.TITLE, "Primary Title") + .with(MessageBannerProperties.DESCRIPTION, "Secondary Title") + .with(MessageBannerProperties.PRIMARY_BUTTON_TEXT, "Action") + .with(MessageBannerProperties.LARGE_ICON, true) + .with(MessageBannerProperties.ICON_ROUNDED_CORNER_RADIUS_PX, radius) + .build(); + MessageBannerView view = (MessageBannerView) LayoutInflater.from(activity).inflate( + R.layout.message_banner_view, null, false); + PropertyModelChangeProcessor.create(model, view, MessageBannerViewBinder::bind); + LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, + activity.getResources().getDimensionPixelSize(R.dimen.message_banner_height)); + + TestThreadUtils.runOnUiThreadBlocking( + () -> { getActivity().setContentView(view, params); }); + mRenderTestRule.render(view, "message_banner_large_icon_with_radius"); + } } \ No newline at end of file
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java index 04acab8..0470edc 100644 --- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerView.java
@@ -7,6 +7,7 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.res.ColorStateList; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.util.AttributeSet; @@ -17,6 +18,7 @@ import androidx.annotation.ColorInt; import androidx.annotation.Nullable; +import androidx.core.graphics.drawable.RoundedBitmapDrawable; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.components.browser_ui.widget.BoundedLinearLayout; @@ -27,6 +29,7 @@ import org.chromium.components.browser_ui.widget.listmenu.ListMenuButton; import org.chromium.components.browser_ui.widget.listmenu.ListMenuButtonDelegate; import org.chromium.components.browser_ui.widget.listmenu.ListMenuItemProperties; +import org.chromium.ui.base.ViewUtils; import org.chromium.ui.modelutil.MVCListAdapter; import org.chromium.ui.modelutil.PropertyModel; @@ -44,6 +47,7 @@ private Runnable mSecondaryActionCallback; private SwipeGestureListener mSwipeGestureDetector; private Runnable mOnTitleChanged; + private int mCornerRadius = -1; public MessageBannerView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); @@ -78,6 +82,8 @@ void setIcon(Drawable icon) { mIconView.setImageDrawable(icon); + // Reset radius to generate a new drawable with expected radius. + if (mCornerRadius >= 0) setIconCornerRadius(mCornerRadius); } void setIconTint(@ColorInt int color) { @@ -88,6 +94,17 @@ } } + void setIconCornerRadius(int cornerRadius) { + mCornerRadius = cornerRadius; + if (!(mIconView.getDrawable() instanceof BitmapDrawable)) { + return; + } + BitmapDrawable drawable = (BitmapDrawable) mIconView.getDrawable(); + RoundedBitmapDrawable bitmap = ViewUtils.createRoundedBitmapDrawable( + getResources(), drawable.getBitmap(), cornerRadius); + mIconView.setImageDrawable(bitmap); + } + void setPrimaryButtonText(String text) { mPrimaryButton.setVisibility(VISIBLE); mPrimaryButton.setText(text); @@ -123,6 +140,19 @@ mOnTitleChanged = runnable; } + void enableLargeIcon(boolean enabled) { + int smallSize = getResources().getDimensionPixelSize(R.dimen.message_icon_size); + int largeSize = getResources().getDimensionPixelSize(R.dimen.message_icon_size_large); + LayoutParams params = (LayoutParams) mIconView.getLayoutParams(); + if (enabled) { + params.height = params.width = largeSize; + } else { + params.width = LayoutParams.WRAP_CONTENT; + params.height = smallSize; + } + mIconView.setLayoutParams(params); + } + // TODO(crbug.com/1163302): For the M88 experiment we decided to display single item menu in // response to the tap on secondary button. The code below implements this logic. Past M88 it // will be replaced with modal dialog driven from the feature code.
diff --git a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewBinder.java b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewBinder.java index c4422ad7..6975e745 100644 --- a/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewBinder.java +++ b/components/messages/android/internal/java/src/org/chromium/components/messages/MessageBannerViewBinder.java
@@ -9,7 +9,9 @@ import static org.chromium.components.messages.MessageBannerProperties.DESCRIPTION_MAX_LINES; import static org.chromium.components.messages.MessageBannerProperties.ICON; import static org.chromium.components.messages.MessageBannerProperties.ICON_RESOURCE_ID; +import static org.chromium.components.messages.MessageBannerProperties.ICON_ROUNDED_CORNER_RADIUS_PX; import static org.chromium.components.messages.MessageBannerProperties.ICON_TINT_COLOR; +import static org.chromium.components.messages.MessageBannerProperties.LARGE_ICON; import static org.chromium.components.messages.MessageBannerProperties.ON_SECONDARY_BUTTON_CLICK; import static org.chromium.components.messages.MessageBannerProperties.ON_TOUCH_RUNNABLE; import static org.chromium.components.messages.MessageBannerProperties.PRIMARY_BUTTON_CLICK_LISTENER; @@ -52,6 +54,10 @@ AppCompatResources.getDrawable(view.getContext(), model.get(ICON_RESOURCE_ID))); } else if (propertyKey == ICON_TINT_COLOR) { view.setIconTint(model.get(ICON_TINT_COLOR)); + } else if (propertyKey == ICON_ROUNDED_CORNER_RADIUS_PX) { + view.setIconCornerRadius(model.get(ICON_ROUNDED_CORNER_RADIUS_PX)); + } else if (propertyKey == LARGE_ICON) { + view.enableLargeIcon(model.get(LARGE_ICON)); } else if (propertyKey == SECONDARY_ICON) { view.setSecondaryIcon(model.get(SECONDARY_ICON)); } else if (propertyKey == SECONDARY_ICON_RESOURCE_ID) {
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java index 6ce604d..7c7b55a2c 100644 --- a/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java +++ b/components/messages/android/java/src/org/chromium/components/messages/MessageBannerProperties.java
@@ -13,6 +13,7 @@ import org.chromium.base.Callback; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel.ReadableIntPropertyKey; +import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableFloatPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableIntPropertyKey; import org.chromium.ui.modelutil.PropertyModel.WritableLongPropertyKey; @@ -49,6 +50,11 @@ public static final WritableObjectPropertyKey<Drawable> ICON = new WritableObjectPropertyKey<>(); public static final WritableIntPropertyKey ICON_RESOURCE_ID = new WritableIntPropertyKey(); + // Large: 36 x 36dp; Default: 24dp (height) x wrap_content + public static final WritableBooleanPropertyKey LARGE_ICON = new WritableBooleanPropertyKey(); + // Default: 0dp + public static final WritableIntPropertyKey ICON_ROUNDED_CORNER_RADIUS_PX = + new WritableIntPropertyKey(); /** * If left unspecified, this will be default_icon_color_accent1. {@link #TINT_NONE} can be used @@ -89,8 +95,9 @@ public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {MESSAGE_IDENTIFIER, PRIMARY_BUTTON_TEXT, PRIMARY_BUTTON_CLICK_LISTENER, TITLE, DESCRIPTION, - DESCRIPTION_MAX_LINES, ICON, ICON_RESOURCE_ID, ICON_TINT_COLOR, SECONDARY_ICON, - SECONDARY_ICON_RESOURCE_ID, SECONDARY_BUTTON_MENU_TEXT, ON_SECONDARY_BUTTON_CLICK, + DESCRIPTION_MAX_LINES, ICON, ICON_RESOURCE_ID, ICON_TINT_COLOR, LARGE_ICON, + ICON_ROUNDED_CORNER_RADIUS_PX, SECONDARY_ICON, SECONDARY_ICON_RESOURCE_ID, + SECONDARY_BUTTON_MENU_TEXT, ON_SECONDARY_BUTTON_CLICK, SECONDARY_ICON_CONTENT_DESCRIPTION, DISMISSAL_DURATION, TRANSLATION_X, TRANSLATION_Y, ALPHA, ON_TOUCH_RUNNABLE, ON_PRIMARY_ACTION, ON_SECONDARY_ACTION, ON_DISMISSED}; }
diff --git a/components/messages/android/java/src/org/chromium/components/messages/MessageWrapper.java b/components/messages/android/java/src/org/chromium/components/messages/MessageWrapper.java index 4ed2796d..e2e761d 100644 --- a/components/messages/android/java/src/org/chromium/components/messages/MessageWrapper.java +++ b/components/messages/android/java/src/org/chromium/components/messages/MessageWrapper.java
@@ -123,6 +123,16 @@ } @CalledByNative + void setLargeIcon(boolean enabled) { + mMessageProperties.set(MessageBannerProperties.LARGE_ICON, enabled); + } + + @CalledByNative + void setIconRoundedCornerRadius(int radius) { + mMessageProperties.set(MessageBannerProperties.ICON_ROUNDED_CORNER_RADIUS_PX, radius); + } + + @CalledByNative void disableIconTint() { mMessageProperties.set( MessageBannerProperties.ICON_TINT_COLOR, MessageBannerProperties.TINT_NONE);
diff --git a/components/messages/android/message_wrapper.cc b/components/messages/android/message_wrapper.cc index eb73d57..09df1f7 100644 --- a/components/messages/android/message_wrapper.cc +++ b/components/messages/android/message_wrapper.cc
@@ -136,6 +136,17 @@ Java_MessageWrapper_setIcon(env, java_message_wrapper_, java_bitmap); } +void MessageWrapper::EnableLargeIcon(bool enabled) { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_MessageWrapper_setLargeIcon(env, java_message_wrapper_, enabled); +} + +void MessageWrapper::SetIconRoundedCornerRadius(int radius) { + JNIEnv* env = base::android::AttachCurrentThread(); + Java_MessageWrapper_setIconRoundedCornerRadius(env, java_message_wrapper_, + radius); +} + void MessageWrapper::DisableIconTint() { JNIEnv* env = base::android::AttachCurrentThread(); Java_MessageWrapper_disableIconTint(env, java_message_wrapper_);
diff --git a/components/messages/android/message_wrapper.h b/components/messages/android/message_wrapper.h index a7f4520..c40293a 100644 --- a/components/messages/android/message_wrapper.h +++ b/components/messages/android/message_wrapper.h
@@ -62,6 +62,8 @@ void SetIconResourceId(int resource_id); bool IsValidIcon(); void SetIcon(const SkBitmap& icon); + void EnableLargeIcon(bool enabled); + void SetIconRoundedCornerRadius(int radius); // The icon is tinted to default_icon_color_accent1 by default. // Call this method to display icons of original colors. void DisableIconTint();
diff --git a/components/mirroring/service/session.cc b/components/mirroring/service/session.cc index cfa573a..34b33f3 100644 --- a/components/mirroring/service/session.cc +++ b/components/mirroring/service/session.cc
@@ -415,7 +415,7 @@ gpu_channel_host_ = gpu_->EstablishGpuChannelSync(); if (gpu_channel_host_ && gpu_channel_host_->gpu_feature_info().status_values - [gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] == + [gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE] == gpu::kGpuFeatureStatusEnabled) { supported_profiles_ = media::GpuVideoAcceleratorUtil::ConvertGpuToMediaEncodeProfiles(
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index 855dda3..03b2510 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -331,6 +331,7 @@ ] deps = [ ":buildflags", + "//build:chromeos_buildflags", "//components/dom_distiller/core:core", "//components/search_engines", "//components/strings", @@ -342,6 +343,10 @@ "//ui/gfx", ] + if (is_chromeos_lacros) { + deps += [ "//chromeos/crosapi/cpp:cpp" ] + } + if ((!is_android || enable_vr) && !is_ios) { deps += [ ":vector_icons" ] }
diff --git a/components/omnibox/browser/DEPS b/components/omnibox/browser/DEPS index 02b844c..bdbd9e6 100644 --- a/components/omnibox/browser/DEPS +++ b/components/omnibox/browser/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+chromeos/crosapi/cpp/gurl_os_handler_utils.h", "+components/bookmarks/browser", "+components/bookmarks/test", "+components/browser_ui/widget/android/java",
diff --git a/components/omnibox/browser/autocomplete_input.cc b/components/omnibox/browser/autocomplete_input.cc index d6ea9d03..0c97d8c 100644 --- a/components/omnibox/browser/autocomplete_input.cc +++ b/components/omnibox/browser/autocomplete_input.cc
@@ -15,6 +15,7 @@ #include "base/trace_event/memory_usage_estimator.h" #include "base/trace_event/typed_macros.h" #include "build/build_config.h" +#include "build/chromeos_buildflags.h" #include "components/omnibox/browser/autocomplete_scheme_classifier.h" #include "components/url_formatter/url_fixer.h" #include "components/url_formatter/url_formatter.h" @@ -25,6 +26,10 @@ #include "url/url_canon_ip.h" #include "url/url_util.h" +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chromeos/crosapi/cpp/gurl_os_handler_utils.h" // nogncheck +#endif + namespace { // Hardcode constant to avoid any dependencies on content/. @@ -251,6 +256,20 @@ if (!canonicalized_url->is_valid()) return metrics::OmniboxInputType::QUERY; +#if BUILDFLAG(IS_CHROMEOS_LACROS) + if (crosapi::gurl_os_handler_utils::IsAshOsAsciiScheme(parsed_scheme_utf8)) { + // Lacros and Ash have a different set of internal chrome:// pages. + // However - once Lacros is the primary browser, the Ash browser cannot be + // reached anymore and many internal status / information / ... pages + // become inaccessible (e.g. the flags page which allows to disable Lacros). + // The os:// scheme is able to forward a keyed set of pages to Ash, hence + // making them accessible again. + // TODO(crbug/1269355): Treat all os:// input as valid destination and add + // 404 handler if Ash does not handle the request. + return metrics::OmniboxInputType::URL; + } +#endif + if (base::LowerCaseEqualsASCII(parsed_scheme_utf8, url::kFileScheme)) { // A user might or might not type a scheme when entering a file URL. In // either case, |parsed_scheme_utf8| will tell us that this is a file URL,
diff --git a/components/optimization_guide/content/browser/page_content_annotations_model_manager.cc b/components/optimization_guide/content/browser/page_content_annotations_model_manager.cc index 5a35dea..8fb829a 100644 --- a/components/optimization_guide/content/browser/page_content_annotations_model_manager.cc +++ b/components/optimization_guide/content/browser/page_content_annotations_model_manager.cc
@@ -50,8 +50,8 @@ void PretendToExecuteJob(base::OnceClosure callback, std::unique_ptr<PageContentAnnotationJob> job) { while (absl::optional<std::string> input = job->GetNextInput()) { - job->PostNewResult(BatchAnnotationResult::CreatePageTopicsResult( - *input, ExecutionStatus::kErrorInternalError, absl::nullopt)); + job->PostNewResult( + BatchAnnotationResult::CreatePageTopicsResult(*input, absl::nullopt)); } // Note to future self: The ordering of these callbacks being run will be // important once actually being run on an executor. @@ -500,7 +500,7 @@ if (job->type() == AnnotationType::kPageTopics) { if (!on_demand_page_topics_model_executor_) { - job->FillWithError(ExecutionStatus::kErrorModelFileNotAvailable); + job->FillWithNullOutputs(); job->OnComplete(); job.reset(); std::move(on_job_complete_callback).Run();
diff --git a/components/optimization_guide/content/browser/page_content_annotations_model_manager_unittest.cc b/components/optimization_guide/content/browser/page_content_annotations_model_manager_unittest.cc index be83dbd1..ccd8ff7 100644 --- a/components/optimization_guide/content/browser/page_content_annotations_model_manager_unittest.cc +++ b/components/optimization_guide/content/browser/page_content_annotations_model_manager_unittest.cc
@@ -508,7 +508,6 @@ ASSERT_EQ(result.size(), 1U); EXPECT_EQ(result[0].input(), "input"); EXPECT_EQ(result[0].type(), AnnotationType::kPageTopics); - EXPECT_EQ(result[0].status(), ExecutionStatus::kSuccess); EXPECT_EQ(result[0].topics(), absl::nullopt); EXPECT_EQ(result[0].entities(), absl::nullopt); EXPECT_EQ(result[0].visibility_score(), absl::nullopt); @@ -537,7 +536,6 @@ ASSERT_EQ(result.size(), 1U); EXPECT_EQ(result[0].input(), "input"); EXPECT_EQ(result[0].type(), AnnotationType::kPageTopics); - EXPECT_EQ(result[0].status(), ExecutionStatus::kErrorModelFileNotAvailable); EXPECT_EQ(result[0].topics(), absl::nullopt); EXPECT_EQ(result[0].entities(), absl::nullopt); EXPECT_EQ(result[0].visibility_score(), absl::nullopt); @@ -563,7 +561,6 @@ // run. ASSERT_EQ(result.size(), 1U); EXPECT_EQ(result[0].input(), "input"); - EXPECT_EQ(result[0].status(), ExecutionStatus::kErrorInternalError); EXPECT_EQ(result[0].topics(), absl::nullopt); EXPECT_EQ(result[0].entities(), absl::nullopt); EXPECT_EQ(result[0].visibility_score(), absl::nullopt); @@ -590,7 +587,6 @@ // run. ASSERT_EQ(result.size(), 1U); EXPECT_EQ(result[0].input(), "input"); - EXPECT_EQ(result[0].status(), ExecutionStatus::kErrorInternalError); EXPECT_EQ(result[0].topics(), absl::nullopt); EXPECT_EQ(result[0].entities(), absl::nullopt); EXPECT_EQ(result[0].visibility_score(), absl::nullopt); @@ -645,13 +641,11 @@ ASSERT_EQ(result1.size(), 1U); EXPECT_EQ(result1[0].input(), "input1"); EXPECT_EQ(result1[0].type(), AnnotationType::kPageTopics); - EXPECT_EQ(result1[0].status(), ExecutionStatus::kSuccess); EXPECT_EQ(result1[0].topics(), absl::nullopt); EXPECT_EQ(result1[0].entities(), absl::nullopt); EXPECT_EQ(result1[0].visibility_score(), absl::nullopt); ASSERT_EQ(result2.size(), 1U); EXPECT_EQ(result2[0].input(), "input2"); - EXPECT_EQ(result2[0].status(), ExecutionStatus::kErrorInternalError); EXPECT_EQ(result2[0].topics(), absl::nullopt); EXPECT_EQ(result2[0].entities(), absl::nullopt); EXPECT_EQ(result2[0].visibility_score(), absl::nullopt);
diff --git a/components/optimization_guide/content/browser/page_content_annotations_service.cc b/components/optimization_guide/content/browser/page_content_annotations_service.cc index 0fe44bbf..69b069a 100644 --- a/components/optimization_guide/content/browser/page_content_annotations_service.cc +++ b/components/optimization_guide/content/browser/page_content_annotations_service.cc
@@ -117,8 +117,7 @@ const std::vector<std::string>& inputs, AnnotationType annotation_type) { if (!annotator_) { - std::move(callback).Run(CreateEmptyBatchAnnotationResultsWithStatus( - inputs, ExecutionStatus::kErrorInternalError)); + std::move(callback).Run(CreateEmptyBatchAnnotationResults(inputs)); return; } annotator_->Annotate(std::move(callback), inputs, annotation_type);
diff --git a/components/optimization_guide/content/browser/test_page_content_annotator.cc b/components/optimization_guide/content/browser/test_page_content_annotator.cc index 3950a3a..5df206b 100644 --- a/components/optimization_guide/content/browser/test_page_content_annotator.cc +++ b/components/optimization_guide/content/browser/test_page_content_annotator.cc
@@ -12,12 +12,6 @@ void TestPageContentAnnotator::Annotate(BatchAnnotationCallback callback, const std::vector<std::string>& inputs, AnnotationType annotation_type) { - if (status_ != ExecutionStatus::kSuccess) { - std::move(callback).Run( - CreateEmptyBatchAnnotationResultsWithStatus(inputs, status_)); - return; - } - std::vector<BatchAnnotationResult> results; if (annotation_type == AnnotationType::kPageTopics) { @@ -27,8 +21,8 @@ if (it != topics_by_input_.end()) { output = it->second; } - results.emplace_back(BatchAnnotationResult::CreatePageTopicsResult( - input, status_, output)); + results.emplace_back( + BatchAnnotationResult::CreatePageTopicsResult(input, output)); } } @@ -39,8 +33,8 @@ if (it != entities_by_input_.end()) { output = it->second; } - results.emplace_back(BatchAnnotationResult::CreatePageEntitiesResult( - input, status_, output)); + results.emplace_back( + BatchAnnotationResult::CreatePageEntitiesResult(input, output)); } } @@ -51,18 +45,14 @@ if (it != visibility_scores_for_input_.end()) { output = it->second; } - results.emplace_back(BatchAnnotationResult::CreateContentVisibilityResult( - input, status_, output)); + results.emplace_back( + BatchAnnotationResult::CreateContentVisibilityResult(input, output)); } } std::move(callback).Run(results); } -void TestPageContentAnnotator::UseExecutionStatus(ExecutionStatus status) { - status_ = status; -} - void TestPageContentAnnotator::UsePageTopics( const base::flat_map<std::string, std::vector<WeightedString>>& topics_by_input) {
diff --git a/components/optimization_guide/content/browser/test_page_content_annotator.h b/components/optimization_guide/content/browser/test_page_content_annotator.h index 7d12569..dc52ac1 100644 --- a/components/optimization_guide/content/browser/test_page_content_annotator.h +++ b/components/optimization_guide/content/browser/test_page_content_annotator.h
@@ -20,10 +20,6 @@ TestPageContentAnnotator(); ~TestPageContentAnnotator() override; - // The given |status| is used in every BatchAnnotationResult. Only the success - // status will also populate any corresponding model output given below. - void UseExecutionStatus(ExecutionStatus status); - // The given page topics are used for the matching BatchAnnotationResults by // input string. If the input is not found, the output is left as nullopt. void UsePageTopics( @@ -47,7 +43,6 @@ AnnotationType annotation_type) override; private: - ExecutionStatus status_ = ExecutionStatus::kUnknown; base::flat_map<std::string, std::vector<WeightedString>> topics_by_input_; base::flat_map<std::string, std::vector<ScoredEntityMetadata>> entities_by_input_;
diff --git a/components/optimization_guide/core/BUILD.gn b/components/optimization_guide/core/BUILD.gn index 038d5aa..096e55a 100644 --- a/components/optimization_guide/core/BUILD.gn +++ b/components/optimization_guide/core/BUILD.gn
@@ -38,6 +38,8 @@ "command_line_top_host_provider.h", "decision_tree_prediction_model.cc", "decision_tree_prediction_model.h", + "execution_status.cc", + "execution_status.h", "hint_cache.cc", "hint_cache.h", "hints_component_info.h",
diff --git a/components/optimization_guide/core/base_model_executor.h b/components/optimization_guide/core/base_model_executor.h index 89d8df43..b4df71e 100644 --- a/components/optimization_guide/core/base_model_executor.h +++ b/components/optimization_guide/core/base_model_executor.h
@@ -6,6 +6,7 @@ #define COMPONENTS_OPTIMIZATION_GUIDE_CORE_BASE_MODEL_EXECUTOR_H_ #include "components/optimization_guide/core/base_model_executor_helpers.h" +#include "components/optimization_guide/core/execution_status.h" #include "components/optimization_guide/core/model_executor.h" #include "components/optimization_guide/core/tflite_op_resolver.h" #include "third_party/tflite_support/src/tensorflow_lite_support/cc/task/core/base_task_api.h" @@ -30,14 +31,16 @@ protected: absl::optional<OutputType> Execute(ModelExecutionTask* execution_task, + ExecutionStatus* out_status, InputTypes... args) override { return static_cast<GenericModelExecutionTask<OutputType, InputTypes...>*>( execution_task) - ->Execute(args...); + ->Execute(out_status, args...); } std::unique_ptr<ModelExecutionTask> BuildModelExecutionTask( - base::MemoryMappedFile* model_file) override { + base::MemoryMappedFile* model_file, + ExecutionStatus* out_status) override { std::unique_ptr<tflite::task::core::TfLiteEngine> tflite_engine = std::make_unique<tflite::task::core::TfLiteEngine>( std::make_unique<TFLiteOpResolver>()); @@ -46,6 +49,7 @@ model_file->length()); if (!model_load_status.ok()) { DLOG(ERROR) << "Failed to load model: " << model_load_status.ToString(); + *out_status = ExecutionStatus::kErrorModelFileNotValid; return nullptr; } @@ -55,6 +59,7 @@ if (!interpreter_status.ok()) { DLOG(ERROR) << "Failed to initialize model interpreter: " << interpreter_status.ToString(); + *out_status = ExecutionStatus::kErrorUnknown; return nullptr; }
diff --git a/components/optimization_guide/core/base_model_executor_helpers.h b/components/optimization_guide/core/base_model_executor_helpers.h index 496389f0..d4c661d 100644 --- a/components/optimization_guide/core/base_model_executor_helpers.h +++ b/components/optimization_guide/core/base_model_executor_helpers.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/check.h" +#include "components/optimization_guide/core/execution_status.h" #include "third_party/tflite_support/src/tensorflow_lite_support/cc/task/core/base_task_api.h" namespace optimization_guide { @@ -42,10 +43,14 @@ // Executes the model using |args| and returns the output if the model was // executed successfully. - absl::optional<OutputType> Execute(InputTypes... args) { + absl::optional<OutputType> Execute(ExecutionStatus* out_status, + InputTypes... args) { tflite::support::StatusOr<OutputType> maybe_output = this->Infer(args...); - if (maybe_output.ok()) + if (maybe_output.ok()) { + *out_status = ExecutionStatus::kSuccess; return maybe_output.value(); + } + *out_status = ExecutionStatus::kErrorUnknown; return absl::nullopt; }
diff --git a/components/optimization_guide/core/bert_model_executor.cc b/components/optimization_guide/core/bert_model_executor.cc index cf0e971..ab2b7306 100644 --- a/components/optimization_guide/core/bert_model_executor.cc +++ b/components/optimization_guide/core/bert_model_executor.cc
@@ -18,23 +18,31 @@ absl::optional<std::vector<tflite::task::core::Category>> BertModelExecutor::Execute(ModelExecutionTask* execution_task, + ExecutionStatus* out_status, const std::string& input) { + if (input.empty()) { + *out_status = ExecutionStatus::kErrorEmptyOrInvalidInput; + return absl::nullopt; + } TRACE_EVENT2("browser", "BertModelExecutor::Execute", "optimization_target", GetStringNameForOptimizationTarget(optimization_target_), "input_length", input.size()); + *out_status = ExecutionStatus::kSuccess; return static_cast<tflite::task::text::nlclassifier::BertNLClassifier*>( execution_task) ->Classify(input); } std::unique_ptr<BertModelExecutor::ModelExecutionTask> -BertModelExecutor::BuildModelExecutionTask(base::MemoryMappedFile* model_file) { +BertModelExecutor::BuildModelExecutionTask(base::MemoryMappedFile* model_file, + ExecutionStatus* out_status) { auto maybe_nl_classifier = tflite::task::text::nlclassifier::BertNLClassifier::CreateFromBuffer( reinterpret_cast<const char*>(model_file->data()), model_file->length(), std::make_unique<TFLiteOpResolver>()); if (maybe_nl_classifier.ok()) return std::move(maybe_nl_classifier.value()); + *out_status = ExecutionStatus::kErrorModelFileNotValid; DLOG(ERROR) << "Unable to load BERT model: " << maybe_nl_classifier.status().ToString(); return nullptr;
diff --git a/components/optimization_guide/core/bert_model_executor.h b/components/optimization_guide/core/bert_model_executor.h index 796d0fb..1d1127c 100644 --- a/components/optimization_guide/core/bert_model_executor.h +++ b/components/optimization_guide/core/bert_model_executor.h
@@ -25,9 +25,11 @@ // ModelExecutor: absl::optional<std::vector<tflite::task::core::Category>> Execute( ModelExecutionTask* execution_task, + ExecutionStatus* out_status, const std::string& input) override; std::unique_ptr<ModelExecutionTask> BuildModelExecutionTask( - base::MemoryMappedFile* model_file) override; + base::MemoryMappedFile* model_file, + ExecutionStatus* out_status) override; private: const proto::OptimizationTarget optimization_target_;
diff --git a/components/optimization_guide/core/execution_status.cc b/components/optimization_guide/core/execution_status.cc new file mode 100644 index 0000000..1da6829 --- /dev/null +++ b/components/optimization_guide/core/execution_status.cc
@@ -0,0 +1,30 @@ +// 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 "components/optimization_guide/core/execution_status.h" + +namespace optimization_guide { + +std::string ExecutionStatusToString(ExecutionStatus status) { + switch (status) { + case ExecutionStatus::kUnknown: + return "Unknown"; + case ExecutionStatus::kSuccess: + return "Success"; + case ExecutionStatus::kPending: + return "Pending"; + case ExecutionStatus::kErrorInternalError: + return "ErrorInternalError"; + case ExecutionStatus::kErrorModelFileNotAvailable: + return "ErrorModelFileNotAvailable"; + case ExecutionStatus::kErrorModelFileNotValid: + return "ErrorModelFileNotValid"; + case ExecutionStatus::kErrorEmptyOrInvalidInput: + return "ErrorEmptyOrInvalidInput"; + case ExecutionStatus::kErrorUnknown: + return "ErrorUnknown"; + } +} + +} // namespace optimization_guide \ No newline at end of file
diff --git a/components/optimization_guide/core/execution_status.h b/components/optimization_guide/core/execution_status.h new file mode 100644 index 0000000..f28a83a --- /dev/null +++ b/components/optimization_guide/core/execution_status.h
@@ -0,0 +1,49 @@ +// 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 COMPONENTS_OPTIMIZATION_GUIDE_CORE_EXECUTION_STATUS_H_ +#define COMPONENTS_OPTIMIZATION_GUIDE_CORE_EXECUTION_STATUS_H_ + +#include <string> + +namespace optimization_guide { + +// The status of a model execution. These values are logged to UMA histograms, +// do not change or reorder values. Make sure to update +// |OptimizationGuideExecutionStatus| in //tools/metrics/histograms/enums.xml. +enum class ExecutionStatus { + // Status is unknown. + kUnknown = 0, + + // Execution finished successfully. + kSuccess = 1, + + // Execution is still pending. + kPending = 2, + + // Execution failed for some reason internal to Opt Guide. These failures + // should not happen and result in a DCHECK in non-production builds. + kErrorInternalError = 3, + + // Execution failed because the model file is not available. + kErrorModelFileNotAvailable = 4, + + // Execution failed because the model file could not be loaded into TFLite. + kErrorModelFileNotValid = 5, + + // Execution failed because the input was empty or otherwise invalid. + kErrorEmptyOrInvalidInput = 6, + + // Execution failed because of an unknown error. + kErrorUnknown = 7, + + kMaxValue = kErrorUnknown, +}; + +// Returns a string representation of |status|. +std::string ExecutionStatusToString(ExecutionStatus status); + +} // namespace optimization_guide + +#endif // COMPONENTS_OPTIMIZATION_GUIDE_CORE_EXECUTION_STATUS_H_ \ No newline at end of file
diff --git a/components/optimization_guide/core/model_executor.h b/components/optimization_guide/core/model_executor.h index 14af8e0..93c8586 100644 --- a/components/optimization_guide/core/model_executor.h +++ b/components/optimization_guide/core/model_executor.h
@@ -16,6 +16,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" +#include "components/optimization_guide/core/execution_status.h" #include "components/optimization_guide/core/optimization_guide_enums.h" #include "components/optimization_guide/core/optimization_guide_util.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -26,23 +27,21 @@ namespace { -// Util class for recording the result of loading the detection model. The -// result is recorded when it goes out of scope and its destructor is called. -class ScopedModelExecutorLoadingResultRecorder { +// Util class for recording the result of the model execution. The result is +// recorded when it goes out of scope and its destructor is called. +class ScopedExecutionStatusResultRecorder { public: - ScopedModelExecutorLoadingResultRecorder( - proto::OptimizationTarget optimization_target, - ModelExecutorLoadingState model_loading_state) + explicit ScopedExecutionStatusResultRecorder( + proto::OptimizationTarget optimization_target) : optimization_target_(optimization_target), - model_loading_state_(model_loading_state), start_time_(base::TimeTicks::Now()) {} - ~ScopedModelExecutorLoadingResultRecorder() { + ~ScopedExecutionStatusResultRecorder() { base::UmaHistogramEnumeration( - "OptimizationGuide.ModelExecutor.ModelLoadingResult." + + "OptimizationGuide.ModelExecutor.ExecutionStatus." + optimization_guide::GetStringNameForOptimizationTarget( optimization_target_), - model_loading_state_); + status_); base::UmaHistogramTimes( "OptimizationGuide.ModelExecutor.ModelLoadingDuration." + @@ -51,16 +50,20 @@ base::TimeTicks::Now() - start_time_); } - void set_model_loading_state(ModelExecutorLoadingState model_executor_state) { - model_loading_state_ = model_executor_state; - } + ExecutionStatus* mutable_status() { return &status_; } + + ExecutionStatus status() const { return status_; } + + void set_status(ExecutionStatus status) { status_ = status; } private: - proto::OptimizationTarget optimization_target_; - ModelExecutorLoadingState model_loading_state_; + // The OptimizationTarget of the model being executed. + const proto::OptimizationTarget optimization_target_; // The time at which this instance was constructed. const base::TimeTicks start_time_; + + ExecutionStatus status_ = ExecutionStatus::kUnknown; }; } // namespace @@ -144,12 +147,18 @@ optimization_target_), task_scheduling_latency); + ScopedExecutionStatusResultRecorder status_recorder(optimization_target_); + // Attempt to load the model file if it isn't loaded yet, fail if loading is // unsuccessful or no model is available to load. - if (!loaded_model_ && !LoadModelFile()) { + if (!loaded_model_ && !LoadModelFile(status_recorder.mutable_status())) { reply_task_runner_->PostTask( FROM_HERE, base::BindOnce(std::move(ui_callback_on_complete), absl::nullopt)); + // Some error status is expected, and derived classes should have set the + // status. + DCHECK_NE(status_recorder.status(), ExecutionStatus::kUnknown); + DCHECK_NE(status_recorder.status(), ExecutionStatus::kSuccess); return; } @@ -171,7 +180,10 @@ optimization_guide::GetStringNameForOptimizationTarget( optimization_target_)); base::TimeTicks execute_start_time = base::TimeTicks::Now(); - output = Execute(loaded_model_.get(), args...); + output = Execute(loaded_model_.get(), status_recorder.mutable_status(), + args...); + DCHECK_NE(status_recorder.status(), ExecutionStatus::kUnknown); + // The max of this histogram is 1 hour because we want to understand // tail behavior and catch long running model executions. base::UmaHistogramLongTimes( @@ -213,13 +225,16 @@ using ModelExecutionTask = tflite::task::core::BaseTaskApi<OutputType, InputTypes...>; - // Executes the model using |execution_task| on |args|. + // Executes the model using |execution_task| on |args|, returning the model + // output and setting |out_status| with the status of the execution attempt. virtual absl::optional<OutputType> Execute(ModelExecutionTask* execution_task, + ExecutionStatus* out_status, InputTypes... args) = 0; // Builds a model execution task using |model_file|. virtual std::unique_ptr<ModelExecutionTask> BuildModelExecutionTask( - base::MemoryMappedFile* model_file) = 0; + base::MemoryMappedFile* model_file, + ExecutionStatus* out_status) = 0; // This method is run as a PostTask after every execution. By default, it will // unload the model from memory by calling |ResetLoadedModel|, but this can be @@ -234,7 +249,7 @@ private: // A true return value indicates the model was loaded successfully, false // otherwise. - bool LoadModelFile() { + bool LoadModelFile(ExecutionStatus* out_status) { TRACE_EVENT1("browser", "OptGuideModelExecutor::LoadModelFile", "OptimizationTarget", optimization_guide::GetStringNameForOptimizationTarget( @@ -242,9 +257,6 @@ DCHECK(background_task_runner_->RunsTasksInCurrentSequence()); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - ScopedModelExecutorLoadingResultRecorder scoped_model_loading_recorder( - optimization_target_, ModelExecutorLoadingState::kModelFileInvalid); - ResetLoadedModel(); base::UmaHistogramBoolean( @@ -252,21 +264,20 @@ GetStringNameForOptimizationTarget(optimization_target_), !!model_file_path_); - if (!model_file_path_) + if (!model_file_path_) { + *out_status = ExecutionStatus::kErrorModelFileNotAvailable; return false; + } std::unique_ptr<base::MemoryMappedFile> model_fb = std::make_unique<base::MemoryMappedFile>(); - if (!model_fb->Initialize(*model_file_path_)) + if (!model_fb->Initialize(*model_file_path_)) { + *out_status = ExecutionStatus::kErrorModelFileNotValid; return false; + } model_fb_ = std::move(model_fb); - loaded_model_ = BuildModelExecutionTask(model_fb_.get()); - if (loaded_model_) { - scoped_model_loading_recorder.set_model_loading_state( - ModelExecutorLoadingState::kModelFileValidAndMemoryMapped); - } - + loaded_model_ = BuildModelExecutionTask(model_fb_.get(), out_status); return !!loaded_model_; }
diff --git a/components/optimization_guide/core/model_executor_unittest.cc b/components/optimization_guide/core/model_executor_unittest.cc index 6add483..55607f1 100644 --- a/components/optimization_guide/core/model_executor_unittest.cc +++ b/components/optimization_guide/core/model_executor_unittest.cc
@@ -133,6 +133,11 @@ optimization_guide::GetStringNameForOptimizationTarget( proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD), false, 1); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.ModelExecutor.ExecutionStatus." + + optimization_guide::GetStringNameForOptimizationTarget( + proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD), + ExecutionStatus::kErrorModelFileNotAvailable, 1); } TEST_F(ModelExecutorTest, ExecuteWithLoadedModel) { @@ -184,6 +189,11 @@ optimization_guide::GetStringNameForOptimizationTarget( proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD), true, 1); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.ModelExecutor.ExecutionStatus." + + optimization_guide::GetStringNameForOptimizationTarget( + proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD), + ExecutionStatus::kSuccess, 1); } TEST_F(ModelExecutorTest, ExecuteTwiceWithLoadedModel) { @@ -220,6 +230,11 @@ optimization_guide::GetStringNameForOptimizationTarget( proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD), 0); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.ModelExecutor.ExecutionStatus." + + optimization_guide::GetStringNameForOptimizationTarget( + proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD), + ExecutionStatus::kSuccess, 1); // Second run. run_loop = std::make_unique<base::RunLoop>(); @@ -240,6 +255,11 @@ optimization_guide::GetStringNameForOptimizationTarget( proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD), true, 2); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.ModelExecutor.ExecutionStatus." + + optimization_guide::GetStringNameForOptimizationTarget( + proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD), + ExecutionStatus::kSuccess, 2); histogram_tester.ExpectTotalCount( "OptimizationGuide.ModelExecutor.TaskExecutionLatency." + @@ -317,6 +337,11 @@ optimization_guide::GetStringNameForOptimizationTarget( proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD), true, 1); + histogram_tester.ExpectUniqueSample( + "OptimizationGuide.ModelExecutor.ExecutionStatus." + + optimization_guide::GetStringNameForOptimizationTarget( + proto::OptimizationTarget::OPTIMIZATION_TARGET_PAINFUL_PAGE_LOAD), + ExecutionStatus::kSuccess, 1); // Run again and do not expect a second model load histogram count. run_loop = std::make_unique<base::RunLoop>();
diff --git a/components/optimization_guide/core/model_validator_unittest.cc b/components/optimization_guide/core/model_validator_unittest.cc index 13c8b5d..4232cb7 100644 --- a/components/optimization_guide/core/model_validator_unittest.cc +++ b/components/optimization_guide/core/model_validator_unittest.cc
@@ -116,11 +116,14 @@ .AppendASCII("simple_test.tflite"); ValidateModel(model_file_path); + // |ModelValidatorExecutor::Preprocess| returns an unimplemented error, + // resulting in an unknown error in the final execution step. histogram_tester().ExpectUniqueSample( - "OptimizationGuide.ModelExecutor.ModelLoadingResult." + + "OptimizationGuide.ModelExecutor.ExecutionStatus." + GetStringNameForOptimizationTarget( proto::OptimizationTarget::OPTIMIZATION_TARGET_MODEL_VALIDATION), - ModelExecutorLoadingState::kModelFileValidAndMemoryMapped, 1); + ExecutionStatus::kErrorUnknown, 1); + histogram_tester().ExpectTotalCount( "OptimizationGuide.ModelExecutor.ModelLoadingDuration." + GetStringNameForOptimizationTarget( @@ -139,10 +142,10 @@ ValidateModel(invalid_model_file_path); histogram_tester().ExpectUniqueSample( - "OptimizationGuide.ModelExecutor.ModelLoadingResult." + + "OptimizationGuide.ModelExecutor.ExecutionStatus." + GetStringNameForOptimizationTarget( proto::OptimizationTarget::OPTIMIZATION_TARGET_MODEL_VALIDATION), - ModelExecutorLoadingState::kModelFileInvalid, 1); + ExecutionStatus::kErrorModelFileNotValid, 1); histogram_tester().ExpectTotalCount( "OptimizationGuide.ModelExecutor.ModelLoadingDuration." + GetStringNameForOptimizationTarget(
diff --git a/components/optimization_guide/core/optimization_guide_enums.h b/components/optimization_guide/core/optimization_guide_enums.h index 639ffb31..d108fb0 100644 --- a/components/optimization_guide/core/optimization_guide_enums.h +++ b/components/optimization_guide/core/optimization_guide_enums.h
@@ -160,22 +160,6 @@ kMaxValue = kCouldNotCreateDirectory, }; -// The state of the model file needed for execution. -// -// Keep in sync with ModelExecutorLoadingState in enums.xml. -enum class ModelExecutorLoadingState { - // The model state is not known. - kUnknown = 0, - // The provided model file was not valid. - kModelFileInvalid = 1, - // The model is memory-mapped and available for - // use with TFLite. - kModelFileValidAndMemoryMapped = 2, - - // New values above this line. - kMaxValue = kModelFileValidAndMemoryMapped, -}; - // The status for the page content annotations being stored. // // Keep in sync with OptimizationGuidePageContentAnnotationsStorageStatus in
diff --git a/components/optimization_guide/core/page_content_annotation_job.cc b/components/optimization_guide/core/page_content_annotation_job.cc index 1b03c63..4ac77c00 100644 --- a/components/optimization_guide/core/page_content_annotation_job.cc +++ b/components/optimization_guide/core/page_content_annotation_job.cc
@@ -20,25 +20,25 @@ PageContentAnnotationJob::~PageContentAnnotationJob() = default; -void PageContentAnnotationJob::FillWithError(ExecutionStatus status) { +void PageContentAnnotationJob::FillWithNullOutputs() { while (auto input = GetNextInput()) { switch (type()) { case AnnotationType::kPageTopics: PostNewResult(BatchAnnotationResult::CreatePageTopicsResult( - *input, status, absl::nullopt)); + *input, absl::nullopt)); break; case AnnotationType::kPageEntities: PostNewResult(BatchAnnotationResult::CreatePageEntitiesResult( - *input, status, absl::nullopt)); + *input, absl::nullopt)); break; case AnnotationType::kContentVisibility: PostNewResult(BatchAnnotationResult::CreateContentVisibilityResult( - *input, status, absl::nullopt)); + *input, absl::nullopt)); break; case AnnotationType::kUnknown: NOTREACHED(); - PostNewResult(BatchAnnotationResult::CreateEmptyAnnotationsResult( - *input, status)); + PostNewResult( + BatchAnnotationResult::CreateEmptyAnnotationsResult(*input)); break; } }
diff --git a/components/optimization_guide/core/page_content_annotation_job.h b/components/optimization_guide/core/page_content_annotation_job.h index b195bfaf..989736d 100644 --- a/components/optimization_guide/core/page_content_annotation_job.h +++ b/components/optimization_guide/core/page_content_annotation_job.h
@@ -28,9 +28,8 @@ AnnotationType type); ~PageContentAnnotationJob(); - // Consumes every input, posting new results with the given error status and - // nullopt outputs. - void FillWithError(ExecutionStatus status); + // Consumes every input, posting new results with nullopt outputs. + void FillWithNullOutputs(); // Called when the Job has finished executing to call |on_complete_callback_|. void OnComplete();
diff --git a/components/optimization_guide/core/page_content_annotation_job_executor_unittest.cc b/components/optimization_guide/core/page_content_annotation_job_executor_unittest.cc index fcf894a..d16ffb6 100644 --- a/components/optimization_guide/core/page_content_annotation_job_executor_unittest.cc +++ b/components/optimization_guide/core/page_content_annotation_job_executor_unittest.cc
@@ -14,6 +14,10 @@ namespace optimization_guide { +namespace { +const std::vector<WeightedString> kOutput{WeightedString("output", 1.0)}; +} + class TestJobExecutor : public PageContentAnnotationJobExecutor { public: TestJobExecutor() = default; @@ -25,8 +29,8 @@ const std::string& input, base::OnceCallback<void(const BatchAnnotationResult&)> callback) override { - std::move(callback).Run(BatchAnnotationResult::CreatePageTopicsResult( - input, ExecutionStatus::kSuccess, absl::nullopt)); + std::move(callback).Run( + BatchAnnotationResult::CreatePageTopicsResult(input, kOutput)); } }; @@ -71,9 +75,9 @@ ASSERT_EQ(2U, results.size()); EXPECT_EQ(results[0].input(), "input1"); - EXPECT_EQ(results[0].status(), ExecutionStatus::kSuccess); + EXPECT_EQ(results[0].topics(), absl::make_optional(kOutput)); EXPECT_EQ(results[1].input(), "input2"); - EXPECT_EQ(results[1].status(), ExecutionStatus::kSuccess); + EXPECT_EQ(results[1].topics(), absl::make_optional(kOutput)); } } // namespace optimization_guide
diff --git a/components/optimization_guide/core/page_content_annotation_job_unittest.cc b/components/optimization_guide/core/page_content_annotation_job_unittest.cc index 1e20aa3..1acb275 100644 --- a/components/optimization_guide/core/page_content_annotation_job_unittest.cc +++ b/components/optimization_guide/core/page_content_annotation_job_unittest.cc
@@ -54,8 +54,7 @@ } BatchAnnotationResult expected = - BatchAnnotationResult::CreatePageTopicsResult( - "input", ExecutionStatus::kSuccess, absl::nullopt); + BatchAnnotationResult::CreatePageTopicsResult("input", absl::nullopt); job.PostNewResult(expected); job.OnComplete();
diff --git a/components/optimization_guide/core/page_content_annotations_common.cc b/components/optimization_guide/core/page_content_annotations_common.cc index 3289a71..08bd362 100644 --- a/components/optimization_guide/core/page_content_annotations_common.cc +++ b/components/optimization_guide/core/page_content_annotations_common.cc
@@ -13,25 +13,6 @@ namespace optimization_guide { -std::string ExecutionStatusToString(ExecutionStatus status) { - switch (status) { - case ExecutionStatus::kUnknown: - return "Unknown"; - case ExecutionStatus::kSuccess: - return "Success"; - case ExecutionStatus::kPending: - return "Pending"; - case ExecutionStatus::kErrorInternalError: - return "ErrorInternalError"; - case ExecutionStatus::kErrorModelFileNotAvailable: - return "ErrorModelFileNotAvailable"; - case ExecutionStatus::kErrorModelFileNotValid: - return "ErrorModelFileNotValid"; - case ExecutionStatus::kErrorEmptyOrInvalidInput: - return "ErrorEmptyOrInvalidInput"; - } -} - std::string AnnotationTypeToString(AnnotationType type) { switch (type) { case AnnotationType::kUnknown: @@ -94,11 +75,9 @@ return base::StringPrintf( "BatchAnnotationResult{" "\"<input with length %zu>\", " - "status: %s, " "type: %s, " "output: %s}", - input_.size(), ExecutionStatusToString(status_).c_str(), - AnnotationTypeToString(type_).c_str(), output.c_str()); + input_.size(), AnnotationTypeToString(type_).c_str(), output.c_str()); } std::ostream& operator<<(std::ostream& stream, @@ -110,11 +89,9 @@ // static BatchAnnotationResult BatchAnnotationResult::CreatePageTopicsResult( const std::string& input, - ExecutionStatus status, absl::optional<std::vector<WeightedString>> topics) { BatchAnnotationResult result; result.input_ = input; - result.status_ = status; result.topics_ = topics; result.type_ = AnnotationType::kPageTopics; @@ -132,11 +109,9 @@ // static BatchAnnotationResult BatchAnnotationResult::CreatePageEntitiesResult( const std::string& input, - ExecutionStatus status, absl::optional<std::vector<ScoredEntityMetadata>> entities) { BatchAnnotationResult result; result.input_ = input; - result.status_ = status; result.entities_ = entities; result.type_ = AnnotationType::kPageEntities; @@ -154,11 +129,9 @@ // static BatchAnnotationResult BatchAnnotationResult::CreateContentVisibilityResult( const std::string& input, - ExecutionStatus status, absl::optional<double> visibility_score) { BatchAnnotationResult result; result.input_ = input; - result.status_ = status; result.visibility_score_ = visibility_score; result.type_ = AnnotationType::kContentVisibility; return result; @@ -166,30 +139,26 @@ // static BatchAnnotationResult BatchAnnotationResult::CreateEmptyAnnotationsResult( - const std::string& input, - ExecutionStatus status) { + const std::string& input) { BatchAnnotationResult result; result.input_ = input; - result.status_ = status; return result; } bool BatchAnnotationResult::operator==( const BatchAnnotationResult& other) const { - return this->input_ == other.input_ && this->status_ == other.status_ && - this->type_ == other.type_ && this->topics_ == other.topics_ && - this->entities_ == other.entities_ && + return this->input_ == other.input_ && this->type_ == other.type_ && + this->topics_ == other.topics_ && this->entities_ == other.entities_ && this->visibility_score_ == other.visibility_score_; } -std::vector<BatchAnnotationResult> CreateEmptyBatchAnnotationResultsWithStatus( - const std::vector<std::string>& inputs, - ExecutionStatus status) { +std::vector<BatchAnnotationResult> CreateEmptyBatchAnnotationResults( + const std::vector<std::string>& inputs) { std::vector<BatchAnnotationResult> results; results.reserve(inputs.size()); for (const std::string& input : inputs) { results.emplace_back( - BatchAnnotationResult::CreateEmptyAnnotationsResult(input, status)); + BatchAnnotationResult::CreateEmptyAnnotationsResult(input)); } return results; }
diff --git a/components/optimization_guide/core/page_content_annotations_common.h b/components/optimization_guide/core/page_content_annotations_common.h index d1a5dc0..5679064 100644 --- a/components/optimization_guide/core/page_content_annotations_common.h +++ b/components/optimization_guide/core/page_content_annotations_common.h
@@ -14,31 +14,6 @@ namespace optimization_guide { -// The status of a page content annotation execution. -enum class ExecutionStatus { - // Status is unknown. - kUnknown = 0, - - // Execution finished successfully. - kSuccess = 1, - - // Execution is still pending. - kPending = 2, - - // Execution failed for some reason internal to Opt Guide. These failures - // should not happen and result in a DCHECK in non-production builds. - kErrorInternalError = 3, - - // Execution failed because the model file is not available. - kErrorModelFileNotAvailable = 4, - - // Execution failed because the model file could not be loaded into TFLite. - kErrorModelFileNotValid = 5, - - // Execution failed because the input was empty or otherwise invalid. - kErrorEmptyOrInvalidInput = 6, -}; - // The type of annotation that is being done on the given input. enum class AnnotationType { kUnknown, @@ -56,8 +31,6 @@ kPageEntities, }; -std::string ExecutionStatusToString(ExecutionStatus status); - std::string AnnotationTypeToString(AnnotationType type); // A weighted string value. @@ -90,32 +63,27 @@ // Creates a result for a page topics annotation. static BatchAnnotationResult CreatePageTopicsResult( const std::string& input, - ExecutionStatus status, absl::optional<std::vector<WeightedString>> topics); // Creates a result for a page entities annotation. static BatchAnnotationResult CreatePageEntitiesResult( const std::string& input, - ExecutionStatus status, absl::optional<std::vector<ScoredEntityMetadata>> entities); // Creates a result for a content visibility annotation. static BatchAnnotationResult CreateContentVisibilityResult( const std::string& input, - ExecutionStatus status, absl::optional<double> visibility_score); // Creates a result where the AnnotationType and output are not set. static BatchAnnotationResult CreateEmptyAnnotationsResult( - const std::string& input, - ExecutionStatus status); + const std::string& input); BatchAnnotationResult(const BatchAnnotationResult&); ~BatchAnnotationResult(); std::string input() const { return input_; } AnnotationType type() const { return type_; } - ExecutionStatus status() const { return status_; } absl::optional<std::vector<WeightedString>> topics() const { return topics_; } absl::optional<std::vector<ScoredEntityMetadata>> entities() const { return entities_; @@ -134,7 +102,6 @@ std::string input_; AnnotationType type_ = AnnotationType::kUnknown; - ExecutionStatus status_ = ExecutionStatus::kUnknown; // Output for page topics annotations, set only if the |type_| matches and the // execution was successful. @@ -155,9 +122,8 @@ // Creates a vector of |BatchAnnotationResult| from the given |inputs| where // each result's status is set to |status|. Useful for creating an Annotation // response with a single error. -std::vector<BatchAnnotationResult> CreateEmptyBatchAnnotationResultsWithStatus( - const std::vector<std::string>& inputs, - ExecutionStatus status); +std::vector<BatchAnnotationResult> CreateEmptyBatchAnnotationResults( + const std::vector<std::string>& inputs); } // namespace optimization_guide
diff --git a/components/optimization_guide/core/page_topics_model_executor.cc b/components/optimization_guide/core/page_topics_model_executor.cc index 51e16b58..fd839b60 100644 --- a/components/optimization_guide/core/page_topics_model_executor.cc +++ b/components/optimization_guide/core/page_topics_model_executor.cc
@@ -50,16 +50,12 @@ const absl::optional<std::vector<tflite::task::core::Category>>& output) { DCHECK_EQ(annotation_type, AnnotationType::kPageTopics); - // TODO(crbug/1249632): Plumb out a status from the executor. - ExecutionStatus status = ExecutionStatus::kUnknown; - absl::optional<std::vector<WeightedString>> categories; if (output) { - status = ExecutionStatus::kSuccess; categories = ExtractCategoriesFromModelOutput(*output); } std::move(callback).Run( - BatchAnnotationResult::CreatePageTopicsResult(input, status, categories)); + BatchAnnotationResult::CreatePageTopicsResult(input, categories)); } absl::optional<std::vector<WeightedString>>
diff --git a/components/optimization_guide/core/page_topics_model_executor_unittest.cc b/components/optimization_guide/core/page_topics_model_executor_unittest.cc index 0d87e76..7fefca3 100644 --- a/components/optimization_guide/core/page_topics_model_executor_unittest.cc +++ b/components/optimization_guide/core/page_topics_model_executor_unittest.cc
@@ -250,8 +250,7 @@ }; BatchAnnotationResult topics_result = - BatchAnnotationResult::CreateEmptyAnnotationsResult( - "", ExecutionStatus::kUnknown); + BatchAnnotationResult::CreateEmptyAnnotationsResult(""); model_executor()->PostprocessCategoriesToBatchAnnotationResult( base::BindOnce( [](BatchAnnotationResult* out_result, @@ -261,12 +260,11 @@ &topics_result), AnnotationType::kPageTopics, "input", model_output); EXPECT_EQ(topics_result, BatchAnnotationResult::CreatePageTopicsResult( - "input", ExecutionStatus::kSuccess, - std::vector<WeightedString>{ - WeightedString("0", 0.3), - WeightedString("1", 0.25), - WeightedString("2", 0.4), - })); + "input", std::vector<WeightedString>{ + WeightedString("0", 0.3), + WeightedString("1", 0.25), + WeightedString("2", 0.4), + })); } TEST_F(PageTopicsModelExecutorTest, @@ -281,8 +279,7 @@ SendPageTopicsModelToExecutor(any_metadata); BatchAnnotationResult topics_result = - BatchAnnotationResult::CreateEmptyAnnotationsResult( - "", ExecutionStatus::kUnknown); + BatchAnnotationResult::CreateEmptyAnnotationsResult(""); model_executor()->PostprocessCategoriesToBatchAnnotationResult( base::BindOnce( [](BatchAnnotationResult* out_result, @@ -290,10 +287,9 @@ *out_result = in_result; }, &topics_result), - AnnotationType::kPageTopics, "input", absl::nullopt); + AnnotationType::kPageTopics, "", absl::nullopt); EXPECT_EQ(topics_result, - BatchAnnotationResult::CreatePageTopicsResult( - "input", ExecutionStatus::kUnknown, absl::nullopt)); + BatchAnnotationResult::CreatePageTopicsResult("", absl::nullopt)); } } // namespace optimization_guide \ No newline at end of file
diff --git a/components/policy/resources/policy_templates_it.xtb b/components/policy/resources/policy_templates_it.xtb index 0089e04..f1c5fe72 100644 --- a/components/policy/resources/policy_templates_it.xtb +++ b/components/policy/resources/policy_templates_it.xtb
@@ -1667,6 +1667,10 @@ Se il criterio non viene configurato, si applica il criterio <ph name="ASK_GEOLOCATION_POLICY_NAME" />, ma gli utenti possono cambiare l'impostazione.</translation> <translation id="2922511125678964398">Consenti all'autenticazione captive portal di ignorare le impostazioni del proxy</translation> +<translation id="2931888116345994552">Se questo criterio non viene configurato o se viene impostato su Attivato, consente gli aggiornamenti di tutti i componenti di <ph name="PRODUCT_NAME" />. + + Se viene impostato su Disattivato, gli aggiornamenti dei componenti vengono disattivati. Tuttavia, alcuni componenti sono esclusi da questo criterio: gli aggiornamenti dei componenti che non contengono codice eseguibile e che sono critici per la sicurezza del browser non verranno disattivati. + Esempi di tali componenti includono gli elenchi revoche certificati e i filtri di sottorisorse.</translation> <translation id="2939988360019366928">Consenti la visualizzazione dei risultati di ricerca di <ph name="GOOGLE_SEARCH_PRODUCT_NAME" /> più recenti in un riquadro laterale del browser</translation> <translation id="2940127076681735544">Se per il criterio viene impostato un URL valido, <ph name="PRODUCT_NAME" /> scarica l'elenco dei siti da tale URL e applica le regole come se fossero state configurate con il criterio <ph name="SITELIST_POLICY_NAME" />. @@ -2717,6 +2721,7 @@ Se il criterio viene impostato su Disattivato, <ph name="PRODUCT_NAME" /> verrà disattivato.</translation> <translation id="4203879074082863035">Agli utenti vengono mostrate soltanto le stampanti indicate nella whitelist</translation> +<translation id="4204327073692415353">Non richiedere all'utente di selezionare un certificato client nella schermata di accesso</translation> <translation id="4205316772333487392">Viene forzato l'uso di SafeSearch nella Ricerca Google</translation> <translation id="4209297478239988291">Consente di attivare la funzione di accessibilità di clic automatico. @@ -5374,6 +5379,7 @@ <translation id="7477231245051133709">Attiva la funzione di accessibilità di audio in formato mono</translation> <translation id="7477239290070847560">Destinazioni protocolli (mDNS e DNS-SD) basate su configurazione automatica</translation> <translation id="7485481791539008776">Regole di selezione della stampante predefinita</translation> +<translation id="7486205887492534734">Mostra una richiesta in caso di corrispondenza tra più certificati nella schermata di accesso</translation> <translation id="7491720878670299691">La velocità di interrogazione e controllo della rete per eventi. Il valore minimo consentito è 1 minuto. Se il criterio non viene impostato, viene applicata la velocità predefinita di 1 minuto.</translation> @@ -5465,6 +5471,7 @@ Se il criterio è attivato o non impostato, la funzionalità di conversione delle unità di Risposte rapide sarà attiva. Se il criterio è disattivato, la funzionalità di conversione delle unità di Risposte rapide sarà disattivata.</translation> +<translation id="7587345076013230465">Richiedi all'utente di selezionare il certificato client quando il criterio di selezione automatica corrisponde a più certificati nella schermata di accesso</translation> <translation id="7590188804371204512">Controlla l'installazione delle estensioni esterne. L'attivazione di questa impostazione blocca l'installazione delle estensioni esterne.
diff --git a/components/policy/resources/policy_templates_nl.xtb b/components/policy/resources/policy_templates_nl.xtb index 64b5a3ae..29e7899 100644 --- a/components/policy/resources/policy_templates_nl.xtb +++ b/components/policy/resources/policy_templates_nl.xtb
@@ -714,6 +714,16 @@ <translation id="1862267110714201519">De functie voor ghostvenster uitzetten.</translation> <translation id="1865417998205858223">Rechten voor sleutels</translation> <translation id="186719019195685253">Actie die moet worden ondernomen wanneer de vertraging voor inactief wordt bereikt bij gebruik op netspanning</translation> +<translation id="1881649377321404593"> + Dit beleid is verwijderd in M80 omdat WebDriver nu werkt met alle bestaande beleidsregels, en het dus niet langer nodig is. + + Met dit beleid kunnen gebruikers van de WebDriver-functie beleidsregels overschrijven die problemen met de werking kunnen veroorzaken. + + Dit beleid zet momenteel de beleidsregels SitePerProcess en IsolateOrigins uit. + + Als het beleid wordt toegepast, kan WebDriver niet-geschikte beleidsregels overschrijven. + + Als het beleid niet wordt toegepast of niet is ingesteld, mag WebDriver niet-geschikte beleidsregels niet overschrijven.</translation> <translation id="1885782360784839335">Promotiecontent op volledig tabblad tonen</translation> <translation id="1888871729456797026">De inschrijvingstoken van het cloudbeleid op een desktop</translation> <translation id="1894790493260633497">Modus voor afdrukken met achtergrondbeelden standaard aanzetten</translation> @@ -2758,6 +2768,16 @@ Vanaf <ph name="PRODUCT_NAME" /> versie 92 wordt dit beleid ook ondersteund in de stand zonder interface. In <ph name="MS_WIN_NAME" /> is deze functionaliteit alleen beschikbaar voor instanties die zijn gekoppeld aan een <ph name="MS_AD_NAME" />-domein, die worden uitgevoerd in Windows 10 Pro of die zijn ingeschreven voor <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />. In <ph name="MAC_OS_NAME" /> is deze functionaliteit alleen beschikbaar voor instanties die via MDM worden beheerd of via MCX aan een domein zijn gekoppeld.</translation> +<translation id="4268014245533736105">Chrome blokkeert navigatie naar externe protocollen in iframes in sandboxes. Zie https://chromestatus.com/features/5680742077038592. + + Als dit is ingesteld op True, kan Chrome die navigatie blokkeren. + + Als dit is ingesteld op False, wordt voorkomen dat Chrome die navigatie blokkeert. + + Dit is standaard ingesteld op True: beveiligingsfunctie aan. + + Dit kan worden gebruikt door beheerders die meer tijd nodig hebben om hun interne website te updaten waarop deze nieuwe beperking van invloed is. Dit zakelijke beleid is tijdelijk. Het is de bedoeling het te verwijderen na <ph name="PRODUCT_NAME" /> versie 104. + </translation> <translation id="4268586991084547853">Meer compatibel met sitelijsten in de Microsoft IE-/Edge-bedrijfsmodus.</translation> <translation id="4269859918103560644">Toestaan dat gebruikers dit bepalen</translation> <translation id="4274691295133617461">Als je het beleid instelt op 3, kunnen websites leestoegang vragen tot bestanden en directory's in het bestandssysteem van het besturingssysteem van de host via de File System API. Als je het beleid instelt op 2, wordt toegang geblokkeerd. @@ -4113,6 +4133,12 @@ <translation id="5997543603646547632">Klok met 24-uursnotatie standaard gebruiken</translation> <translation id="5997846976342452720">Aangeven of de plug-inzoeker moet worden uitgezet (beëindigd)</translation> <translation id="5998198091336830580">Dit beleid maakt deel uit van de volgende atomische groep (alleen beleidsregels van de bron met de hoogste prioriteit in de groep worden toegepast):</translation> +<translation id="6004575267180297869"> + Geeft aan of WebAssembly-modules cross-origin kunnen worden verstuurd naar een ander venster of een andere werkrol. Het cross-origin delen van WebAssembly-modules wordt beëindigd als onderdeel van de activiteiten om document.domain te beëindigen, zie https://github.com/mikewest/deprecating-document-domain. Dit beleid staat toe dat het cross-origin delen van WebAssembly-modules opnieuw mogelijk wordt gemaakt om een langere overgangsperiode te bieden voor het beëindigingsproces. + + Als je dit beleid instelt op True, kunnen sites zonder beperkingen WebAssembly-modules cross-origin versturen. + + Als je dit beleid instelt op False of niet instelt, kunnen sites alleen WebAssembly-modules naar vensters en werkrollen in dezelfde oorsprong sturen.</translation> <translation id="6009062900206392980">Als het beleid is ingesteld op None, staat schermvergroting uit op het inlogscherm. Als je dit beleid instelt, kunnen gebruikers het vergrootglas tijdelijk aan- of uitzetten. Als het inlogscherm opnieuw wordt geladen of een minuut lang niet wordt gebruikt, wordt de oorspronkelijke status hersteld. @@ -4288,6 +4314,7 @@ Dit beleid is bedoeld om bedrijven de flexibiliteit te bieden om de audiosandbox uit te zetten als ze instellingen voor beveiligingssoftware gebruiken die de sandbox kunnen verstoren.</translation> <translation id="624818583115864448">poort 554 (blokkering kan worden opgeheven tot 15-10-2021)</translation> <translation id="6252773211180267325">Niet voorkomen dat <ph name="BOREALIS_NAME" /> wordt uitgevoerd voor een gebruiker</translation> +<translation id="6258658183356534534">De GREASE-updatefunctie voor User-Agent Client Hints beheren.</translation> <translation id="6261643884958898336">ID-gegevens van machine rapporteren</translation> <translation id="6265892395051519509">Toegang tot sensoren op deze sites toestaan</translation> <translation id="6273015149273504999"> @@ -4369,6 +4396,7 @@ De beleidswaarde moet worden gespecificeerd in milliseconden. De opgegeven waarden moeten kleiner dan of gelijk zijn aan de inactieve vertraging. Het waarschuwingsbericht wordt alleen getoond als de inactieve actie 'uitloggen' of 'afsluiten' is.</translation> +<translation id="6331943515692769234">Afdwingen dat het eerdere User-Agent GREASE-algoritme wordt gebruikt.</translation> <translation id="6332192586629642626">Geschiedenisclusters zijn niet zichtbaar op chrome://history/journeys.</translation> <translation id="6332489309596092806">Als je het beleid instelt, wordt een lijst met web-apps gespecificeerd die op de achtergrond worden geïnstalleerd zonder interactie met de gebruiker en die niet kunnen worden verwijderd of uitgezet door gebruikers. @@ -4725,6 +4753,12 @@ Opmerking: Dit beleid is ook van invloed op extensies en apps die afgedwongen geïnstalleerd worden met <ph name="EXTENSION_INSTALL_FORCELIST_POLICY_NAME" />.</translation> <translation id="6731757988219967594">Sites op hoofdniveau (maar geen ingesloten iframes) filteren op content voor volwassenen</translation> +<translation id="6733851879899284032"> + Geeft aan of SharedArrayBuffers kan worden gebruikt in een context zonder cross-origin-isolatie. Vanaf <ph name="PRODUCT_NAME" /> 91 (25-05-2021) vereist <ph name="PRODUCT_NAME" /> cross-origin-isolatie bij gebruik van SharedArrayBuffers vanwege redenen met webcompatibiliteit. Je kunt meer informatie bekijken op: https://developer.chrome.com/blog/enabling-shared-array-buffer/. + + Als dit beleid wordt toegepast, kunnen sites SharedArrayBuffer gebruiken zonder beperkingen. + + Als dit beleid niet wordt toegepast of niet is ingesteld, kunnen sites SharedArrayBuffers alleen gebruiken als ze cross-origin geïsoleerd zijn.</translation> <translation id="6735701345096330595">Spellingcontrole voor talen verplichten</translation> <translation id="6740611636377710500">Sta deze gebruiker toe om PluginVm uit te voeren. @@ -4914,6 +4948,9 @@ <translation id="6929746927224321095">Automatisch invullen uitzetten</translation> <translation id="6931242315485576290">Synchronisatie van gegevens met Google uitzetten</translation> <translation id="6940243892299228102">Niet toestaan dat gebruikers bureautemplates gebruiken</translation> +<translation id="694071740172924905">Als deze functie aanstaat, brengt de GREASE-updatefunctie voor User-Agent Client Hints het User-Agent GREASE-algoritme in lijn met de nieuwste specificaties. +De geüpdatete specificaties kunnen ervoor zorgen dat sommige websites niet meer werken die het aantal tekens beperken dat een verzoek mag bevatten. Bekijk de specificaties voor meer informatie: https://wicg.github.io/ua-client-hints/#grease +Als dit beleid wordt toegepast of niet is ingesteld, staat de GREASE-updatefunctie voor User-Agent Client Hints aan. Als het beleid niet wordt toegepast, wordt het eerdere User-Agent GREASE-algoritme gebruikt.</translation> <translation id="6943577887654905793">Voorkeursnaam voor Mac/Linux:</translation> <translation id="6946652757373377924">Dit beleid is verwijderd in M77. Dit beleid is van toepassing op het inlogscherm. Zie ook het beleid <ph name="ISOLATE_ORIGINS_POLICY_NAME" /> dat van toepassing is op de gebruikerssessie. @@ -5273,6 +5310,7 @@ Als dit beleid niet wordt ingesteld, geldt de standaardwaarde 'niet toegestaan' voor beheerde zakelijke gebruikers en 'toegestaan' voor niet-beheerde gebruikers.</translation> <translation id="7295019613773647480">Gebruikers met beperkte rechten aanzetten</translation> +<translation id="7297476773981993405">Toestaan dat het geüpdatete User-Agent GREASE-algoritme wordt uitgevoerd.</translation> <translation id="7302043767260300182">Vertraging van schermvergrendeling wanneer op netstroom wordt gewerkt</translation> <translation id="7303902834678570827">Gebruikers van beheerde gastsessies kunnen geen weergave-eigenschappen voor het hele apparaat opslaan</translation> <translation id="731208205557053914">VPD-gegevens rapporteren</translation> @@ -5381,6 +5419,12 @@ <translation id="7491720878670299691">Snelheid waarmee netwerkgegevens worden opgevraagd en gecheckt op gebeurtenissen. Het toegestane minimum is 1 minuut. Als je dit beleid niet instelt, is de standaardsnelheid van 1 minuut van toepassing.</translation> +<translation id="7498595166686106721"> + Het rechtenbeleid voor schermopname geeft toegang tot getDisplayMedia(), volgens deze specificatie: https://www.w3.org/TR/screen-capture/#feature-policy-integration. Maar als dit beleid niet wordt toegepast, wordt deze vereiste niet afgedwongen en wordt getDisplayMedia() toegestaan vanuit contexten die anders verboden zouden zijn. Dit zakelijke beleid is tijdelijk. Het is de bedoeling het te verwijderen na <ph name="PRODUCT_NAME" /> versie 100. Het is bedoeld om de blokkering van zakelijke gebruikers op te heffen wiens app niet aan de specificaties voldoet, maar tijd nodig heeft om te worden hersteld. + + Als dit beleid wordt toegepast of niet is ingesteld, kunnen sites getDisplayMedia() alleen aanroepen vanuit contexten die door het rechtenbeleid voor schermopname op de toelatingslijst zijn gezet. + + Als het beleid niet wordt toegepast, kunnen sites getDisplayMedia() ook aanroepen vanuit contexten die niet door het rechtenbeleid voor schermopname op de toelatingslijst zijn gezet. Er kunnen nog steeds andere beperkingen gelden.</translation> <translation id="7506745375479451616">Met dit beleid wordt bepaald welke opdracht wordt gebruikt om URL's te openen in <ph name="PRODUCT_NAME" /> bij overschakeling vanuit <ph name="IE_PRODUCT_NAME" />. Dit beleid kan worden ingesteld op een pad naar een uitvoerbaar bestand of op <ph name="PRODUCT_NAME_PLACEHOLDER" /> om de locatie van <ph name="PRODUCT_NAME" /> automatisch te detecteren. Als je het beleid niet instelt, detecteert <ph name="IE_PRODUCT_NAME" /> het eigen pad van <ph name="PRODUCT_NAME" /> naar een uitvoerbaar bestand als <ph name="PRODUCT_NAME" /> wordt gestart vanuit Internet Explorer. @@ -5997,6 +6041,18 @@ <translation id="8266778278542911985">Als je het beleid instelt op 3, kunnen websites toegang vragen tot seriële poorten. Als je het beleid instelt op 2, wordt de toegang tot seriële poorten geblokkeerd. Als je het beleid niet instelt, vragen websites om toegang maar kunnen gebruikers deze instelling wijzigen.</translation> +<translation id="8267887696930711948">Beëindigd in M69. Gebruik in plaats hiervan OverrideSecurityRestrictionsOnInsecureOrigin. + +Dit beleid specificeert een lijst met herkomsten (URL's) of hostnaampatronen (zoals *.example.com) waarop beveiligingsbeperkingen voor niet-beveiligde herkomsten niet van toepassing zijn. + +Het is de bedoeling organisaties de mogelijkheid te geven herkomsten toe te staan voor verouderde apps die geen TLS kunnen implementeren, of een staging server voor interne webontwikkelingen in te stellen, zodat de ontwikkelaars functies die een beveiligde context vereisen, kunnen testen zonder TLS te hoeven implementeren op de staging server. Dit beleid verhindert ook dat de herkomst wordt aangeduid als niet beveiligd in de omnibox. + +Als er een lijst met URL's wordt ingesteld in dit beleid, heeft dit hetzelfde effect als wanneer de opdrachtregelmarkering --unsafely-treat-insecure-origin-as-secure wordt ingesteld op een door komma's gescheiden lijst met dezelfde URL's. Als het beleid is ingesteld, wordt de opdrachtregelmarkering overschreven. + +Dit beleid is beëindigd in M69 en is vervangen door OverrideSecurityRestrictionsOnInsecureOrigin. Als beide beleidsregels aanwezig zijn, overschrijft OverrideSecurityRestrictionsOnInsecureOrigin dit beleid. + +Voor meer informatie over een beveiligde context ga je naar https://www.w3.org/TR/secure-contexts/ + </translation> <translation id="8270320981823560179">Drive</translation> <translation id="827054846390793641">Verbindingsgerelateerde UI aanzetten op hostdesktop bij een actieve verbinding</translation> <translation id="8274603902181597201">De eCryptfs-hoofdmap van de gebruiker wissen en beginnen met een nieuwe hoofdmap die is versleuteld met ext4</translation>
diff --git a/components/policy/resources/policy_templates_ru.xtb b/components/policy/resources/policy_templates_ru.xtb index 0d40c98..f35f7a54 100644 --- a/components/policy/resources/policy_templates_ru.xtb +++ b/components/policy/resources/policy_templates_ru.xtb
@@ -710,6 +710,17 @@ <translation id="1862267110714201519">Отключить окна в режиме конфиденциальности</translation> <translation id="1865417998205858223">Позволяет разрешать или запрещать использование ключей</translation> <translation id="186719019195685253">Действие в случае превышения времени бездействия при работе от сети.</translation> +<translation id="1881649377321404593"> + Это правило было удалено в версии M80. Оно больше не нужно, потому что теперь + WebDriver совместим со всеми существующими правилами. + + Это правило позволяет пользователям WebDriver переопределять правила, которые могут мешать его работе. + + В настоящее время оно отключает правила SitePerProcess и IsolateOrigins. + + Если это правило включено, WebDriver может переопределять несовместимые правила. + + Если правило отключено или не настроено, WebDriver не может переопределять несовместимые правила.</translation> <translation id="1885782360784839335">Показывать коммерческие материалы, занимающие всю вкладку</translation> <translation id="1888871729456797026">Токен регистрации облачного правила на компьютере</translation> <translation id="1894790493260633497">Включить режим печати фоновых цветов и изображений по умолчанию</translation> @@ -2765,6 +2776,17 @@ Начиная с <ph name="PRODUCT_NAME" /> версии 92 оно также поддерживается в режиме консольного браузера. В <ph name="MS_WIN_NAME" /> это правило можно настроить только на устройствах из домена <ph name="MS_AD_NAME" />, на которых установлена ОС Windows 10 Pro или которые зарегистрированы в программе "<ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME" />". В <ph name="MAC_OS_NAME" /> правило поддерживается только на устройствах, которые контролируются с помощью ПО для управления мобильными устройствами или добавлены в домен через MCX.</translation> +<translation id="4268014245533736105">Chrome будет блокировать переходы на внешние протоколы в изолированном + окне iframe. Подробная информация доступна на странице https://chromestatus.com/features/5680742077038592. + + Если задано значение True, Chrome будет блокировать такие переходы. + + Если установлено значение False, Chrome не сможет блокировать такие переходы. + + По умолчанию выбрано значение True (функция безопасности включена). + + Это правило могут использовать администраторы, которым нужно больше времени, чтобы обновить внутренние сайты, затронутые этим новым ограничением. Это корпоративное правило введено на время и будет удалено после выхода <ph name="PRODUCT_NAME" /> версии 104. + </translation> <translation id="4268586991084547853">Повышенная совместимость со списками сайтов в режиме предприятия Microsoft IE/Edge</translation> <translation id="4269859918103560644">Предоставить выбор пользователю</translation> <translation id="4274691295133617461">Если задано значение 3, сайтам будет разрешено запрашивать доступ для чтения к файлам и каталогам операционной системы хоста через File System API, а если задано значение 2, – запрещено. @@ -4129,6 +4151,12 @@ <translation id="5997543603646547632">Использовать по умолчанию 24-часовой формат времени</translation> <translation id="5997846976342452720">Отключение поиска плагинов (устаревшее)</translation> <translation id="5998198091336830580">Это правило входит в следующую мини-группу (применяются только правила из источника с максимальным приоритетом):</translation> +<translation id="6004575267180297869"> + Определяет, можно ли передавать модули WebAssembly в другое окно или скрипт Worker, если у них разные источники. Поддержка совместного использования модулей WebAssembly разными источниками будет прекращена в рамках отказа от применения параметра document.domain. Подробную информацию вы найдете на странице https://github.com/mikewest/deprecating-document-domain. Это правило позволяет снова разрешить совместное использование модулей WebAssembly разными источниками, чтобы получить дополнительное время на переход. + + Если задано значение True, сайты могут передавать модули WebAssembly между разными источниками без ограничений. + + Если правило не настроено или для него указано значение False, сайтам разрешается отправлять модули WebAssembly в скрипты Worker и окна, только если у них один источник.</translation> <translation id="6009062900206392980">Если для правила задано значение None, экранная лупа будет выключена на экране входа. Если вы настроите это правило, пользователи смогут временно включить или выключить экранную лупу. При перезагрузке экрана входа или после одной минуты бездействия будет восстановлено исходное состояние этой функции. @@ -4305,6 +4333,7 @@ Это правило дает компаниям возможность отключать тестовую среду для звука, если ее не позволяют использовать настройки ПО для обеспечения безопасности.</translation> <translation id="624818583115864448">порт 554 (можно разблокировать до 15.10.2021)</translation> <translation id="6252773211180267325">Разрешить запуск <ph name="BOREALIS_NAME" /> для пользователя</translation> +<translation id="6258658183356534534">Управление обновлением алгоритма GREASE в подсказках агента пользователя клиента</translation> <translation id="6261643884958898336">Сообщать данные, идентифицирующие компьютер</translation> <translation id="6265892395051519509">Разрешение указанным сайтам доступа к датчикам</translation> <translation id="6273015149273504999"> @@ -4387,6 +4416,7 @@ Значение указывается в миллисекундах и не должно превышать время задержки при переходе в режим бездействия. Предупреждение будет появляться только в том случае, если в режиме бездействия происходит выход из аккаунта или отключение устройства.</translation> +<translation id="6331943515692769234">Использовать предыдущий алгоритм GREASE в агенте пользователя</translation> <translation id="6332192586629642626">Скрывать кластеры истории на странице chrome://history/journeys</translation> <translation id="6332489309596092806">Это правило позволяет указать список веб-приложений, которые устанавливаются без участия пользователя и которые нельзя удалить или отключить. @@ -4764,6 +4794,12 @@ Это правило также влияет на расширения и приложения, которые принудительно устанавливаются в соответствии с правилом <ph name="EXTENSION_INSTALL_FORCELIST_POLICY_NAME" />.</translation> <translation id="6731757988219967594">Фильтровать сайты верхнего уровня (кроме встроенных окон iframe), содержащие контент для взрослых</translation> +<translation id="6733851879899284032"> + Определяет, можно ли использовать объекты SharedArrayBuffer в контексте без изоляции от междоменных источников. Чтобы обеспечивать совместимость в интернете, при использовании объектов SharedArrayBuffer в <ph name="PRODUCT_NAME" /> 91 (25.05.2021) и более поздних версиях <ph name="PRODUCT_NAME" /> будет требоваться изоляция от междоменных источников. Дополнительную информацию можно найти на странице https://developer.chrome.com/blog/enabling-shared-array-buffer/. + + Если правило включено, сайты могут использовать объекты SharedArrayBuffer без ограничений. + + Если правило не настроено или отключено, для использования объектов SharedArrayBuffer требуется изоляция от междоменных источников.</translation> <translation id="6735701345096330595">Принудительная проверка правописания для определенных языков</translation> <translation id="6740611636377710500">Разрешает этому пользователю запускать Plugin VM. @@ -4954,6 +4990,9 @@ <translation id="6929746927224321095">Отключить автозаполнение</translation> <translation id="6931242315485576290">Отключить синхронизацию данных с Google</translation> <translation id="6940243892299228102">Запретить пользователям применять шаблоны для рабочего стола</translation> +<translation id="694071740172924905">Если правило включено, применяется последняя версия алгоритма из спецификации. + Это может вызывать ошибки в работе некоторых сайтов, где действуют ограничения на допустимые символы в запросах. Дополнительную информацию можно найти в спецификации на странице https://wicg.github.io/ua-client-hints/#grease. + Если правило включено или не настроено, обновление алгоритма GREASE в подсказках агента пользователя клиента включено. Если правило отключено, в агенте пользователя используется прежний алгоритм GREASE.</translation> <translation id="6943577887654905793">Предпочтительное название для Mac и Linux:</translation> <translation id="6946652757373377924"> Это правило было удалено в версии M77. @@ -5313,6 +5352,7 @@ Если правило не настроено, по умолчанию функция отключена для корпоративных аккаунтов и включена для остальных пользователей.</translation> <translation id="7295019613773647480">Включить контролируемые профили</translation> +<translation id="7297476773981993405">Разрешить применение обновленного алгоритма GREASE в агенте пользователя</translation> <translation id="7302043767260300182">Задержка блокировки экрана при работе от сети</translation> <translation id="7303902834678570827">В управляемом гостевом сеансе пользователи не могут сохранять параметры экрана на уровне устройства</translation> <translation id="731208205557053914">Передача информации о VPD</translation> @@ -5419,6 +5459,12 @@ <translation id="7491720878670299691">Частота, с которой выполняется запрос сетевых данных и проверяется возникновение событий. Минимальное значение – 1 минута. Если значение не указано, частота по умолчанию составляет 1 минуту.</translation> +<translation id="7498595166686106721"> + Правило разрешений для захвата экрана ограничивает доступ к методу getDisplayMedia() в соответствии с этой спецификацией: https://www.w3.org/TR/screen-capture/#feature-policy-integration. Однако если правило отключено, разрешение не запрашивается и вызывать метод getDisplayMedia() можно из контекстов, которые в противном случае были бы запрещены. Это корпоративное правило введено на время и будет удалено после выхода <ph name="PRODUCT_NAME" /> версии 100. Оно предназначено для разблокировки корпоративных пользователей, приложения которых не соответствуют спецификации и требуют времени на исправление. + + Если правило включено или не настроено, сайты могут вызывать метод getDisplayMedia() только из разрешенных контекстов. + + Если правило отключено, сайты могут вызывать метод getDisplayMedia() даже из тех контекстов, которые запрещены правилом разрешений для захвата экрана. Обратите внимание, что могут применяться и другие ограничения.</translation> <translation id="7506745375479451616">Это правило определяет, какая команда должна использоваться для открытия страниц при переключении с браузера <ph name="IE_PRODUCT_NAME" /> на <ph name="PRODUCT_NAME" />. Вы можете указать путь к исполняемому файлу или же настроить автоматическое обнаружение файла <ph name="PRODUCT_NAME" /> (для этого нужно ввести <ph name="PRODUCT_NAME_PLACEHOLDER" />). Если правило не задано, <ph name="IE_PRODUCT_NAME" /> автоматически находит путь к исполняемому файлу <ph name="PRODUCT_NAME" /> при запуске браузера <ph name="PRODUCT_NAME" /> через Internet Explorer. @@ -6030,6 +6076,19 @@ <translation id="8266778278542911985">Если в этом правиле указано значение "3", то сайтам разрешено запрашивать доступ к последовательным портам, а если "2", то запрещено. Если правило не задано, запрашивать доступ разрешено, но пользователи могут изменить эту настройку.</translation> +<translation id="8267887696930711948">Поддержка этого правила прекращена в версии M69. Используйте вместо него правило + OverrideSecurityRestrictionsOnInsecureOrigin. + + В этом правиле определяется список источников (URL) или шаблонов имен хостов (например, "*.example.com"), которые будут считаться безопасными. + + Таким образом, у организаций появится возможность составлять списки источников для приложений, не использующих TLS, или настроить вспомогательный сервер для внутренней веб-разработки и тестировать функции, требующие безопасного контекста, без развертывания TLS. Кроме того, указанные в этом правиле адреса не будут помечаться как небезопасные в омнибоксе. + + Применение правила аналогично указанию параметра --unsafely-treat-insecure-origin-as-secure для списка URL, разделенных запятыми. Если правило настроено, оно переопределяет параметр --unsafely-treat-insecure-origin-as-secure. + + Поддержка этого правила прекращена в версии M69. Вместо него используется правило OverrideSecurityRestrictionsOnInsecureOrigin. Если настроены оба правила, применяется новое. + + Подробную информацию о безопасном контексте можно найти на странице https://www.w3.org/TR/secure-contexts/. + </translation> <translation id="8270320981823560179">Диск</translation> <translation id="827054846390793641">Разрешить показ интерфейса, связанного с подключением, на главном рабочем столе, когда подключение установлено</translation> <translation id="8274603902181597201">Заменить исходный каталог пользователя, зашифрованный с помощью ecryptfs, каталогом, зашифрованным с помощью ext4</translation>
diff --git a/components/policy/resources/policy_templates_tr.xtb b/components/policy/resources/policy_templates_tr.xtb index d0fa4083..5c5c85e 100644 --- a/components/policy/resources/policy_templates_tr.xtb +++ b/components/policy/resources/policy_templates_tr.xtb
@@ -272,6 +272,13 @@ <translation id="1352799151662469739">AC gücüyle çalışırken, ekran kilitlenmeden önce kullanıcı girişi olmadan geçecek süre (milisaniye olarak)</translation> <translation id="1353416417709895349">DNS müdahale kontrollerini ve bunu mu demek istediniz "http://intranetsite/" bilgi çubuklarını devre dışı bırak.</translation> <translation id="1354424209129232709">Maksimum:</translation> +<translation id="1355050231181289439"> Bu politika, eşleştirmeleri iyileştirilen uluslararası klavye kısayollarının etkinleştirilip etkinleştirilmeyeceğini kontrol eder. + Bu özellik, klavye kısayollarının uluslararası klavye düzenlerinde tutarlı bir şekilde çalışmasını sağlar ve eski kısayolları kullanımdan kaldırır. + + Bu politika devre dışı bırakılırsa iyileştirilmiş uluslararası klavye kısayolları devre dışı bırakılır. + Bu politika etkinleştirilirse iyileştirilmiş uluslararası klavye kısayolları etkinleştirilir. + Bu politika ayarlanmadan bırakılırsa hem yönetilen cihazlar için hem de tüketiciye ait cihazlar için etkin olur. + Bunun, yönetilen kullanıcıların kullanımdan kaldırılmış eski kısayolları kullanmaya devam edebilmelerini sağlamaya yönelik geçici bir politika olduğunu unutmayın. Bu politika, özelleştirilmiş klavye kısayolları kullanıma sunulduktan sonra kullanımdan kaldırılacaktır.</translation> <translation id="1359553908012294236">Bu politika doğru seçeneğine ayarlanırsa veya yapılandırılmazsa <ph name="PRODUCT_NAME" />, misafir modunda giriş yapılmasına izin verir. Misafir modunda girişler, tüm pencerelerin gizli modda açıldığı <ph name="PRODUCT_NAME" /> profilleridir. Bu politika yanlış seçeneğine ayarlanırsa, <ph name="PRODUCT_NAME" /> misafir profillerinin başlatılmasına izin vermez.</translation> @@ -2150,6 +2157,7 @@ Politika, Devre Dışı değerine ayarlanır veya ayarlanmadan bırakılırsa DTC kapatılır. Cihazdan telemetri ve teşhis verilerini toplayamaz, işleyemez veya raporlayamaz.</translation> <translation id="3450649825886735618">Yazım hatalarının düzeltilmesine yardımcı olması için herhangi bir Google web hizmeti kullanma</translation> +<translation id="3451422488938880786"> Yeniden eşleştirilen uluslararası klavye kısayollarının etkinleştirilmesine/devre dışı bırakılmasına olanak tanır</translation> <translation id="3451901387456196887">Kullanıcılara <ph name="PRODUCT_NAME" /> menüsünde erişim kodu kullanarak veya QR kodu tarayarak yayın cihazı seçme olanağı verilir.</translation> <translation id="3456292544936505775">Bu politika, <ph name="PRODUCT_OS_NAME" /> cihazının güncellemeleri otomatik olarak denetlemesine izin verilmeyen zaman aralıklarını kontrol eder. Bu politika, boş olmayan bir zaman aralıkları listesine ayarlandığında: @@ -2187,6 +2195,7 @@ Engellenenler listesi değerinin <ph name="ALL_EXTENSIONS" /> olması, tüm uzantıların engellendiği ve kullanıcıların yalnızca izin verilenler listesindeki uzantıları yükleyebileceği anlamına gelir. Varsayılan olarak tüm uzantılara izin verilir. Ancak uzantıları politikaya göre yasakladıysanız bu politikayı değiştirmek için izin verilen uzantılar listesini kullanın.</translation> +<translation id="3501606938635483637">Uluslararası klavye kısayolları, tuşların klavyedeki yeriyle değil glifiyle eşleştirilir.</translation> <translation id="3502555714327823858">Tüm dupleks modlara izin ver</translation> <translation id="350443680860256679">ARC'yi yapılandır</translation> <translation id="350797926066071931">Google Çeviri'yi etkinleştir</translation> @@ -3137,6 +3146,7 @@ <translation id="4802905909524200151"><ph name="TPM_FIRMWARE_UPDATE_TPM" /> donanım yazılımını güncelleme davranışını yapılandır</translation> <translation id="4804828344300125154">Kullanıcı oturumu kapatıldığında her zaman cihazı yeniden başlat.</translation> <translation id="4807950475297505572">Yeterli boş alan sağlanıncaya kadar en seyrek kullanılan kullanıcılar kaldırılır</translation> +<translation id="4811210934875253713">Arama yolculukları chrome://history/journeys adresinde görülebilir.</translation> <translation id="4812270373673968774">Politikayı Always (Her zaman) değerine ayarlamak, <ph name="PRODUCT_OS_NAME" /> rafını otomatik gizler. Politikayı Never (Hiçbir zaman) değerine ayarlamak, rafın otomatik gizlenmesine hiçbir zaman izin vermez. Bu politikayı ayarlarsanız kullanıcılar değiştiremez. Ayarlanmazsa rafın otomatik gizlenip gizlenmeyeceğine kullanıcı karar verir.</translation> @@ -4402,6 +4412,30 @@ Uyarı mesajı yalnızca boşta kalma işlemi, çıkış yapma veya cihazı kapatma olduğunda gösterilir.</translation> <translation id="6331943515692769234">Önceki kullanıcı aracısı GREASE algoritmasını kullanmaya zorla.</translation> +<translation id="6332192586629642626">Arama yolculukları chrome://history/journeys adresinde görülemez.</translation> +<translation id="6332489309596092806">Politikayı ayarlamak, kullanıcı etkileşimi olmadan sessizce yüklenen, kullanıcıların kaldıramadığı veya kapatamadığı web uygulamalarının listesini belirtir. + + Politikanın her liste öğesi, zorunlu üyeye sahip bir nesnedir: + <ph name="URL_LABEL" /> (yüklenecek web uygulamasının URL'si) + + ve isteğe bağlı 5 üye: + - <ph name="DEFAULT_LAUNCH_CONTAINER_LABEL" /> + (web uygulamasının açılma yöntemini belirlemek için — varsayılan yeni sekmedir) + + - <ph name="CREATE_DESKTOP_SHORTCUT_LABEL" /> + (<ph name="LINUX_OS_NAME" /> ve + <ph name="MS_WIN_NAME" /> masaüstü kısayolları oluşturulmak istenirse doğru değerine ayarlanmalıdır). + + - <ph name="FALLBACK_APP_NAME_LABEL" /> + (<ph name="PRODUCT_NAME" /> sürüm 90'dan başlayarak, Progresif Web Uygulaması (PWA) değilse uygulama adını veya PWA ise ancak yüklemenin tamamlanabilmesi için kimlik doğrulama gerekiyorsa geçici olarak yüklenen uygulama adını geçersiz kılmanıza olanak tanır.) Hem <ph name="CUSTOM_NAME_LABEL" /> hem de <ph name="FALLBACK_APP_NAME_LABEL" /> sağlanmışsa ikincisi dikkate alınmaz.) + + - <ph name="OVERRIDE_APP_NAME_LABEL" /> + (<ph name="PRODUCT_NAME" /> sürüm 96'dan itibaren tüm web uygulamaları ve PWA'lar için uygulama adını kalıcı olarak geçersiz kılmanıza olanak tanır. Şu anda yalnızca <ph name="PRODUCT_OS_NAME" /> işletim sisteminde desteklenmektedir.) + + - <ph name="CUSTOM_ICON_LABEL" /> + (<ph name="PRODUCT_NAME" /> sürüm 96'dan itibaren yüklü uygulamaların uygulama simgesini geçersiz kılmanıza olanak tanır. Simgeler; kare şeklinde, maksimum 1 MB boyutunda ve jpeg, png, gif, webp, ico biçimlerinden birinde olmalıdır. Karma değeri, simge dosyasının SHA256 karma değeri olmalıdır.) Şu anda yalnızca <ph name="PRODUCT_OS_NAME" /> işletim sisteminde desteklenmektedir.) + + Uygulamaları <ph name="PRODUCT_OS_NAME" /> rafına sabitlemek için <ph name="PINNED_LAUNCHER_APPS_POLICY_NAME" /> politikasına bakın.</translation> <translation id="6332546092866098577">Bu sitelerde File System API üzerinden okuma erişimini engelle</translation> <translation id="6334330017384340264">Bu politika, uygulama başına kullanım kısıtlamaları için hangi uygulamalara ve URL'lere izin verilmesi gerektiğini belirtir. Yapılandırılmış izin verilenler listesi, uygulama başına süre sınırlarına sahip belirtilen kullanıcı için <ph name="PRODUCT_OS_NAME" /> üzerinde yüklü uygulamalara uygulanır. @@ -5844,6 +5878,7 @@ Bu politika Etkin değerine ayarlanırsa kullanıcı <ph name="LACROS_NAME" /> tarayıcıyı kullanabilir.</translation> <translation id="802147957407376460">Ekranı 0 derece döndür</translation> +<translation id="8025620823136567878">Uluslararası klavye kısayolları, tuşların glifiyle değil klavyedeki yeriyle eşleştirilir.</translation> <translation id="802776363472387903"><ph name="PLUGIN_VM_NAME" /> resminin SHA-256 karması.</translation> <translation id="8028814157747157754">Varsayılan arama sağlayıcısını etkinleştir ve kullanıcıların arama sağlayıcısı listesini değiştirmesine izin ver</translation> <translation id="8029201909194194377">Uzaktan erişim bağlantıları için izin verilen maksimum oturum süresi</translation> @@ -6620,6 +6655,7 @@ <translation id="8931555638815157255">Politika Etkin değerine ayarlanır veya ayarlanmadan bırakılırsa kayıtlı cihazlar düzenli olarak işletim sistemi ve donanım yazılımı sürümlerini bildirir. Politika Devre Dışı değerine ayarlanırsa kayıtlı cihazlar sürüm bilgisi vermez.</translation> +<translation id="8934618237639919190">Arama yolculukları varsayılan olarak chrome://history/journeys adresinde görülebilir ve kullanıcılar, arama yolculuklarının görünürlüğünü değiştirebilir.</translation> <translation id="8937282917198525844"> M81'den başlayarak, standart form kontrol öğelerine (ör. <select>, <button>, <input type=date>) iyileştirilmiş erişilebilirlik ve daha iyi platform bütünlüğü ile yenilenmiş bir görünüm ve tarz sağlandı. Bu politika, M84'e kadar "eski" form kontrol öğelerini geri yükler. Bu politika True (Doğru) değerine ayarlanırsa tüm siteler için "eski" form kontrol öğeleri kullanılır.
diff --git a/components/printing/renderer/print_render_frame_helper.cc b/components/printing/renderer/print_render_frame_helper.cc index f9c43096..650b555 100644 --- a/components/printing/renderer/print_render_frame_helper.cc +++ b/components/printing/renderer/print_render_frame_helper.cc
@@ -124,7 +124,8 @@ std::string json; base::JSONWriter::Write(parameters, &json); std::string script = base::StringPrintf(script_format, json.c_str()); - frame->ExecuteScript(blink::WebString::FromUTF8(script)); + frame->ExecuteScript( + blink::WebScriptSource(blink::WebString::FromUTF8(script))); } int GetDPI(const mojom::PrintParams& print_params) {
diff --git a/components/reporting/proto/synced/record.proto b/components/reporting/proto/synced/record.proto index b3d812f7..48d04e2 100644 --- a/components/reporting/proto/synced/record.proto +++ b/components/reporting/proto/synced/record.proto
@@ -103,7 +103,7 @@ // If missing, the record is either not encrypted or missing. optional EncryptionInfo encryption_info = 2; - // Sequencing information (required). Must be present to allow + // Sequence information (required). Must be present to allow // tracking and confirmation of the events by server. optional SequenceInformation sequence_information = 3;
diff --git a/components/reporting/storage/missive_storage_module.h b/components/reporting/storage/missive_storage_module.h index a6f3c62..bc9d8b1 100644 --- a/components/reporting/storage/missive_storage_module.h +++ b/components/reporting/storage/missive_storage_module.h
@@ -65,7 +65,7 @@ void Flush(Priority priority, base::OnceCallback<void(Status)> callback) override; - // Once a record has been successfully uploaded, the sequencing information + // Once a record has been successfully uploaded, the sequence information // can be passed back to the StorageModule here for record deletion. // If |force| is false (which is used in most cases), |sequence_information| // only affects Storage if no higher sequencing was confirmed before;
diff --git a/components/reporting/storage/storage.cc b/components/reporting/storage/storage.cc index 39a6f68..f38e473 100644 --- a/components/reporting/storage/storage.cc +++ b/components/reporting/storage/storage.cc
@@ -160,10 +160,10 @@ void ProcessRecord(EncryptedRecord encrypted_record, base::OnceCallback<void(bool)> processed_cb) override { - // Update sequencing information: add Priority. - SequenceInformation* const sequencing_info = + // Update sequence information: add Priority. + SequenceInformation* const sequence_info = encrypted_record.mutable_sequence_information(); - sequencing_info->set_priority(priority_); + sequence_info->set_priority(priority_); storage_interface_->ProcessRecord(std::move(encrypted_record), std::move(processed_cb)); } @@ -171,7 +171,7 @@ void ProcessGap(SequenceInformation start, uint64_t count, base::OnceCallback<void(bool)> processed_cb) override { - // Update sequencing information: add Priority. + // Update sequence information: add Priority. start.set_priority(priority_); storage_interface_->ProcessGap(std::move(start), count, std::move(processed_cb));
diff --git a/components/reporting/storage/storage_module.h b/components/reporting/storage/storage_module.h index 0c917d7..9e9f675 100644 --- a/components/reporting/storage/storage_module.h +++ b/components/reporting/storage/storage_module.h
@@ -49,7 +49,7 @@ void Flush(Priority priority, base::OnceCallback<void(Status)> callback) override; - // Once a record has been successfully uploaded, the sequencing information + // Once a record has been successfully uploaded, the sequence information // can be passed back to the StorageModule here for record deletion. // If |force| is false (which is used in most cases), |sequence_information| // only affects Storage if no higher sequencing was confirmed before;
diff --git a/components/reporting/storage/storage_module_interface.h b/components/reporting/storage/storage_module_interface.h index 290015e..f597b0b 100644 --- a/components/reporting/storage/storage_module_interface.h +++ b/components/reporting/storage/storage_module_interface.h
@@ -35,7 +35,7 @@ virtual void Flush(Priority priority, base::OnceCallback<void(Status)> callback) = 0; - // Once a record has been successfully uploaded, the sequencing information + // Once a record has been successfully uploaded, the sequence information // can be passed back to the StorageModuleInterface here for record deletion. // If |force| is false (which is used in most cases), |sequence_information| // only affects Storage if no higher sequencing was confirmed before;
diff --git a/components/reporting/storage/storage_queue.cc b/components/reporting/storage/storage_queue.cc index bcb516d9..0912af1 100644 --- a/components/reporting/storage/storage_queue.cc +++ b/components/reporting/storage/storage_queue.cc
@@ -304,7 +304,7 @@ } if (!files_.emplace(file_sequencing_id, file_or_status.ValueOrDie()).second) { return Status(error::ALREADY_EXISTS, - base::StrCat({"Sequencing duplicated: '", + base::StrCat({"Sequencing id duplicated: '", full_name.MaybeAsASCII(), "'"})); } return file_sequencing_id; @@ -848,13 +848,13 @@ // Fill in initial sequencing information to track progress: // use minimum of first_sequencing_id_ and first_unconfirmed_sequencing_id_ // if the latter has been recorded. - sequencing_info_.set_generation_id(storage_queue_->generation_id_); + sequence_info_.set_generation_id(storage_queue_->generation_id_); if (storage_queue_->first_unconfirmed_sequencing_id_.has_value()) { - sequencing_info_.set_sequencing_id( + sequence_info_.set_sequencing_id( std::min(storage_queue_->first_unconfirmed_sequencing_id_.value(), storage_queue_->first_sequencing_id_)); } else { - sequencing_info_.set_sequencing_id(storage_queue_->first_sequencing_id_); + sequence_info_.set_sequencing_id(storage_queue_->first_sequencing_id_); } // If there are no files in the queue, do nothing and return success right @@ -876,7 +876,7 @@ // Collect and set aside the files in the set that might have data // for the Upload. files_ = - storage_queue_->CollectFilesForUpload(sequencing_info_.sequencing_id()); + storage_queue_->CollectFilesForUpload(sequence_info_.sequencing_id()); if (files_.empty()) { Response(Status(error::OUT_OF_RANGE, "Sequencing id not found in StorageQueue.")); @@ -910,9 +910,9 @@ // If the first record we need to upload is unavailable, produce Gap record // instead. - if (sequencing_info_.sequencing_id() < current_file_->first) { + if (sequence_info_.sequencing_id() < current_file_->first) { CallGapUpload(/*count=*/current_file_->first - - sequencing_info_.sequencing_id()); + sequence_info_.sequencing_id()); // Resume at ScheduleNextRecord. return; } @@ -924,7 +924,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_); // Read from it until the specified sequencing id is found. for (int64_t sequencing_id = current_file_->first; - sequencing_id < sequencing_info_.sequencing_id(); ++sequencing_id) { + sequencing_id < sequence_info_.sequencing_id(); ++sequencing_id) { auto blob = EnsureBlob(sequencing_id); if (blob.status().error_code() == error::OUT_OF_RANGE) { // Reached end of file, switch to the next one (if present). @@ -934,7 +934,7 @@ return; } current_pos_ = 0; - blob = EnsureBlob(sequencing_info_.sequencing_id()); + blob = EnsureBlob(sequence_info_.sequencing_id()); } if (!blob.ok()) { // File found to be corrupt. Produce Gap record till the start of next @@ -944,15 +944,15 @@ uint64_t count = static_cast<uint64_t>( (current_file_ == files_.end()) ? 1 - : current_file_->first - sequencing_info_.sequencing_id()); + : current_file_->first - sequence_info_.sequencing_id()); CallGapUpload(count); // Resume at ScheduleNextRecord. return; } } - // Read and upload sequencing_info_.sequencing_id(). - CallRecordOrGap(sequencing_info_.sequencing_id()); + // Read and upload sequence_info_.sequencing_id(). + CallRecordOrGap(sequence_info_.sequencing_id()); // Resume at ScheduleNextRecord. } @@ -967,11 +967,10 @@ // retry the upload. if (storage_queue_ && !storage_queue_->options_.upload_retry_delay().is_zero()) { - ScheduleAfter( - storage_queue_->options_.upload_retry_delay(), - base::BindOnce( - &StorageQueue::CheckBackUpload, storage_queue_, status, - /*next_sequencing_id=*/sequencing_info_.sequencing_id())); + ScheduleAfter(storage_queue_->options_.upload_retry_delay(), + base::BindOnce( + &StorageQueue::CheckBackUpload, storage_queue_, status, + /*next_sequencing_id=*/sequence_info_.sequencing_id())); } } @@ -994,7 +993,7 @@ EncryptedRecord encrypted_record; if (!encrypted_record.ParseFromZeroCopyStream(&blob_stream)) { LOG(ERROR) << "Failed to parse record, seq=" - << sequencing_info_.sequencing_id(); + << sequence_info_.sequencing_id(); CallGapUpload(/*count=*/1); // Resume at ScheduleNextRecord. return; @@ -1002,7 +1001,7 @@ CallRecordUpload(std::move(encrypted_record)); } - // Completes sequencing information and makes a call to UploaderInterface + // Completes sequence information and makes a call to UploaderInterface // instance provided by user, which can place processing of the record on any // thread(s). Once it returns, it will schedule NextRecord to execute on the // sequential thread runner of this StorageQueue. If |encrypted_record| is @@ -1011,20 +1010,20 @@ void CallRecordUpload(EncryptedRecord encrypted_record) { DCHECK_CALLED_ON_VALID_SEQUENCE(read_sequence_checker_); if (encrypted_record.has_sequence_information()) { - LOG(ERROR) << "Sequencing information already present, seq=" - << sequencing_info_.sequencing_id(); + LOG(ERROR) << "Sequence information already present, seq=" + << sequence_info_.sequencing_id(); CallGapUpload(/*count=*/1); // Resume at ScheduleNextRecord. return; } - // Fill in sequencing information. + // Fill in sequence information. // Priority is attached by the Storage layer. - *encrypted_record.mutable_sequence_information() = sequencing_info_; + *encrypted_record.mutable_sequence_information() = sequence_info_; uploader_->ProcessRecord(std::move(encrypted_record), base::BindOnce(&ReadContext::ScheduleNextRecord, base::Unretained(this))); - // Move sequencing forward (ScheduleNextRecord will see this). - sequencing_info_.set_sequencing_id(sequencing_info_.sequencing_id() + 1); + // Move sequencing id forward (ScheduleNextRecord will see this). + sequence_info_.set_sequencing_id(sequence_info_.sequencing_id() + 1); } void CallGapUpload(uint64_t count) { @@ -1034,12 +1033,11 @@ NextRecord(/*more_records=*/true); return; } - uploader_->ProcessGap(sequencing_info_, count, + uploader_->ProcessGap(sequence_info_, count, base::BindOnce(&ReadContext::ScheduleNextRecord, base::Unretained(this))); - // Move sequencing forward (ScheduleNextRecord will see this). - sequencing_info_.set_sequencing_id(sequencing_info_.sequencing_id() + - count); + // Move sequence id forward (ScheduleNextRecord will see this). + sequence_info_.set_sequencing_id(sequence_info_.sequencing_id() + count); } // Schedules NextRecord to execute on the StorageQueue sequential task runner. @@ -1065,8 +1063,8 @@ Response(Status::StatusOK()); return; } - // sequencing_info_.sequencing_id() blob is ready. - CallRecordOrGap(sequencing_info_.sequencing_id()); + // sequence_info_.sequencing_id() blob is ready. + CallRecordOrGap(sequence_info_.sequencing_id()); // Resume at ScheduleNextRecord. } @@ -1170,7 +1168,7 @@ Response(Status(error::UNAVAILABLE, "StorageQueue shut down")); return; } - auto blob = EnsureBlob(sequencing_info_.sequencing_id()); + auto blob = EnsureBlob(sequence_info_.sequencing_id()); if (blob.status().error_code() == error::OUT_OF_RANGE) { // Reached end of file, switch to the next one (if present). ++current_file_; @@ -1179,7 +1177,7 @@ return; } current_pos_ = 0; - blob = EnsureBlob(sequencing_info_.sequencing_id()); + blob = EnsureBlob(sequence_info_.sequencing_id()); } if (!blob.ok()) { // File found to be corrupt. Produce Gap record till the start of next @@ -1189,7 +1187,7 @@ uint64_t count = static_cast<uint64_t>( (current_file_ == files_.end()) ? 1 - : current_file_->first - sequencing_info_.sequencing_id()); + : current_file_->first - sequence_info_.sequencing_id()); CallGapUpload(count); // Resume at ScheduleNextRecord. return; @@ -1243,7 +1241,7 @@ // Files that will be read (in order of sequencing ids). std::map<int64_t, scoped_refptr<SingleFile>> files_; - SequenceInformation sequencing_info_; + SequenceInformation sequence_info_; uint32_t current_pos_; std::map<int64_t, scoped_refptr<SingleFile>>::iterator current_file_; const AsyncStartUploaderCb async_start_upload_cb_;
diff --git a/components/reporting/storage/storage_queue.h b/components/reporting/storage/storage_queue.h index d5581a4b..8c2b2ac 100644 --- a/components/reporting/storage/storage_queue.h +++ b/components/reporting/storage/storage_queue.h
@@ -216,7 +216,7 @@ scoped_refptr<CompressionModule> compression_module); // Initializes the object by enumerating files in the assigned directory - // and determines the sequencing information of the last record. + // and determines the sequence information of the last record. // Must be called once and only once after construction. // Returns OK or error status, if anything failed to initialize. // Called once, during initialization.
diff --git a/components/safe_browsing/core/common/web_ui_constants.cc b/components/safe_browsing/core/common/web_ui_constants.cc index f0a0ff0..e7c6c6a 100644 --- a/components/safe_browsing/core/common/web_ui_constants.cc +++ b/components/safe_browsing/core/common/web_ui_constants.cc
@@ -8,8 +8,6 @@ const char kChromeUISafeBrowsingURL[] = "chrome://safe-browsing/"; const char kChromeUISafeBrowsingHost[] = "safe-browsing"; -const char kSbUnderConstruction[] = - "The safe browsing page is under construction."; const char kChromeUISafeBrowsingMatchBillingUrl[] = "chrome://safe-browsing/match?type=billing"; const char kChromeUISafeBrowsingMatchMalwareUrl[] =
diff --git a/components/safe_browsing/core/common/web_ui_constants.h b/components/safe_browsing/core/common/web_ui_constants.h index b58401d..87233e4 100644 --- a/components/safe_browsing/core/common/web_ui_constants.h +++ b/components/safe_browsing/core/common/web_ui_constants.h
@@ -9,7 +9,6 @@ extern const char kChromeUISafeBrowsingURL[]; extern const char kChromeUISafeBrowsingHost[]; -extern const char kSbUnderConstruction[]; extern const char kChromeUISafeBrowsingMatchBillingUrl[]; extern const char kChromeUISafeBrowsingMatchMalwareUrl[]; extern const char kChromeUISafeBrowsingMatchPhishingUrl[];
diff --git a/components/safe_browsing_strings.grdp b/components/safe_browsing_strings.grdp deleted file mode 100644 index 92bb0ae..0000000 --- a/components/safe_browsing_strings.grdp +++ /dev/null
@@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<grit-part> - <message name="IDS_SB_UNDER_CONSTRUCTION" desc="A message that the Safe Browsing page is under construction."> - The Safe Browsing page is under construction. - </message> -</grit-part>
diff --git a/components/soda/soda_installer.cc b/components/soda/soda_installer.cc index 1dcbbe7..90e9295 100644 --- a/components/soda/soda_installer.cc +++ b/components/soda/soda_installer.cc
@@ -24,6 +24,14 @@ constexpr int kSodaCleanUpDelayInDays = 30; +#if BUILDFLAG(IS_CHROMEOS_ASH) + +inline std::string GetProjectorLanguageCode(PrefService* pref_service) { + return pref_service->GetString(ash::prefs::kProjectorCreationFlowLanguage); +} + +#endif // IS_CHROMEOS_ASH + } // namespace namespace speech { @@ -92,8 +100,11 @@ .empty()) { // TODO(crbug.com/1200667): Register the default language used by // Dictation on ChromeOS. - // TODO(crbug.com/1165437): Register the default language used by - // Projector on ChromeOS. + +#if BUILDFLAG(IS_CHROMEOS_ASH) + RegisterLanguage(GetProjectorLanguageCode(profile_prefs), global_prefs); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + RegisterLanguage(prefs::GetLiveCaptionLanguageCode(profile_prefs), global_prefs); }
diff --git a/components/soda/soda_installer_impl_chromeos_unittest.cc b/components/soda/soda_installer_impl_chromeos_unittest.cc index 953e602..faa2f1f 100644 --- a/components/soda/soda_installer_impl_chromeos_unittest.cc +++ b/components/soda/soda_installer_impl_chromeos_unittest.cc
@@ -40,6 +40,8 @@ pref_service_->registry()->RegisterBooleanPref( ash::prefs::kProjectorCreationFlowEnabled, true); pref_service_->registry()->RegisterStringPref( + ash::prefs::kProjectorCreationFlowLanguage, kUsEnglishLocale); + pref_service_->registry()->RegisterStringPref( prefs::kLiveCaptionLanguageCode, kUsEnglishLocale); chromeos::DBusThreadManager::Initialize();
diff --git a/components/strings/components_strings_be.xtb b/components/strings/components_strings_be.xtb index 93f601f..de86a2a5 100644 --- a/components/strings/components_strings_be.xtb +++ b/components/strings/components_strings_be.xtb
@@ -82,6 +82,7 @@ <translation id="124116460088058876">Іншыя мовы</translation> <translation id="1243027604378859286">Аўтар:</translation> <translation id="1246424317317450637">Паўтлусты</translation> +<translation id="1248573052514400575"><ph name="MANAGE_CHROMEOS_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />. Каб персаналізаваць інструменты даступнасці ў наладах Chrome OS, націсніце Tab, затым Enter</translation> <translation id="1250759482327835220">Каб наступны раз плаціць хутчэй, захавайце картку, імя і адрас для выстаўлення рахункаў ва Уліковым запісе Google.</translation> <translation id="1252799212227771492">Кнопка "Стварыць табліцу". Каб хутка стварыць новую табліцу Google, націсніце Enter</translation> <translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (сінхранізаваныя)</translation> @@ -156,6 +157,7 @@ <translation id="1422930527989633628">Сайт можа запытваць дазвол выяўляць прылады з Bluetooth паблізу</translation> <translation id="1426410128494586442">Так</translation> <translation id="1428146450423315676">Укладчык 7</translation> +<translation id="142858679511221695">Карыстальнік воблачнага сэрвісу</translation> <translation id="1428729058023778569">Гэта папярэджанне паказана вам, бо дадзены сайт не падтрымлівае HTTPS. <ph name="BEGIN_LEARN_MORE_LINK" />Даведацца больш<ph name="END_LEARN_MORE_LINK" /></translation> <translation id="1430915738399379752">Друк</translation> <translation id="1432581352905426595">Кіраваць пошукавымі сістэмамі</translation> @@ -322,6 +324,7 @@ <translation id="192020519938775529">{COUNT,plural, =0{Няма}=1{1 сайт}one{# сайт}few{# сайты}many{# сайтаў}other{# сайта}}</translation> <translation id="1923390796829649802">Кнопка "Кіраваць наладамі спецыяльных магчымасцей". Каб персаналізаваць адпаведныя інструменты ў наладах Chrome OS, націсніце Enter</translation> <translation id="1924727005275031552">Новая форма</translation> +<translation id="1927439593081478069">Кнопка "Запусціць праверку бяспекі Chrome", націсніце Enter, каб выканаць праверку бяспекі ў наладах Chrome</translation> <translation id="1939175642807587452">Сайт можа запытваць дазвол на адпраўку апавяшчэнняў</translation> <translation id="1945968466830820669">Вы можаце страціць доступ да ўліковага запісу арганізацыі, або ў вас могуць скрасці асабістыя даныя. Chromium рэкамендуе змяніць пароль.</translation> <translation id="1947454675006758438">Скаба зверху справа</translation> @@ -341,6 +344,7 @@ <translation id="2003709556000175978">Скіньце свой пароль</translation> <translation id="2003775180883135320">Чатыры дзіркі зверху</translation> <translation id="201174227998721785">Кіруйце дазволамі і данымі, якія захоўваюцца на сайтах, праз налады Chrome</translation> +<translation id="2019607688127825327">Кнопка "Кіраваць наладамі спецыяльных магчымасцей". Каб персаналізаваць інструменты даступнасці ў наладах Chrome, націсніце Enter</translation> <translation id="2025115093177348061">Дапоўненая рэальнасць</translation> <translation id="2025186561304664664">Для проксі-сервера ўказана аўтаматычнае наладжванне.</translation> <translation id="2025891858974379949">Небяспечнае змесціва</translation> @@ -506,6 +510,7 @@ <translation id="2556876185419854533">&Адрабіць змену</translation> <translation id="2570734079541893434">Кіраваць наладамі</translation> <translation id="257674075312929031">Група</translation> +<translation id="2576880857912732701">Кнопка "Кіраваць наладамі бяспекі". Каб кіраваць параметрамі Бяспечнага прагляду і выконваць іншыя дзеянні праз налады Chrome, націсніце Enter</translation> <translation id="2586657967955657006">Буфер абмену</translation> <translation id="2587730715158995865">Крыніца: <ph name="ARTICLE_PUBLISHER" />. Вы можаце прачытаць гэты і яшчэ <ph name="OTHER_ARTICLE_COUNT" /> артыкулаў.</translation> <translation id="2587841377698384444">Ідэнтыфікатар API каталога:</translation> @@ -550,6 +555,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="2723669454293168317">Запусціць праверку бяспекі ў наладах Chrome</translation> <translation id="2726001110728089263">Бакавы латок</translation> <translation id="2728127805433021124">Сертыфікат сервера падпісаны з выкарыстаннем ненадзейнага алгарытму.</translation> <translation id="2730326759066348565"><ph name="BEGIN_LINK" />Запусціць дыягностыку падключэння<ph name="END_LINK" />.</translation> @@ -580,6 +586,7 @@ <translation id="2859806420264540918">Гэты сайт паказвае назойлівую рэкламу або рэкламу, якая ўводзіць у зман.</translation> <translation id="287596039013813457">Таварыскі</translation> <translation id="2876489322757410363">Адбудзецца выхад з рэжыму інкогніта для плацяжу праз знешнюю праграму. Працягнуць?</translation> +<translation id="2876949457278336305"><ph name="MANAGE_SECURITY_SETTINGS_FOCUSED_FRIENDLY_MATCH_TEXT" />. Каб кіраваць параметрамі Бяспечнага прагляду і выконваць іншыя дзеянні праз налады Chrome, націсніце Tab, затым Enter</translation> <translation id="2878197950673342043">Плакатны згіб</translation> <translation id="2878424575911748999">A1</translation> <translation id="2880660355386638022">Размяшчэнне вокнаў</translation> @@ -685,6 +692,7 @@ <translation id="3229041911291329567">Звесткі пра версію прылады і браўзера</translation> <translation id="323107829343500871">Увядзіце CVC-код карткі <ph name="CREDIT_CARD" /></translation> <translation id="3234666976984236645">Заўсёды выяўляць важнае змесціва на гэтым сайце</translation> +<translation id="3240683217920639535"><ph name="MANAGE_CHROME_THEMES_FOCUSED_FRIENDLY_MATCH_TEXT" />. Каб наладзіць выгляд браўзера, націсніце Tab, затым Enter</translation> <translation id="3240791268468473923">Быў адкрыты аркуш, які паказваецца пры адсутнасці супадзення ўліковых даных для бяспечных плацяжоў</translation> <translation id="3249845759089040423">Стыльны</translation> <translation id="3252266817569339921">Французская</translation> @@ -712,6 +720,7 @@ <translation id="3329013043687509092">Насычанасць</translation> <translation id="3333762389743153920">Нумар не падыходзіць для віртуальнай карткі</translation> <translation id="3338095232262050444">Бяспечны сайт</translation> +<translation id="3339446062576134663">Воблака (Ash)</translation> <translation id="3355823806454867987">Змяніць налады проксі-сервера...</translation> <translation id="3360103848165129075">Аркуш апрацоўшчыка плацяжоў</translation> <translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />не будзе захоўваць<ph name="END_EMPHASIS" /> наступную інфармацыю: @@ -728,12 +737,14 @@ • стварыць 3D-карту вашага асяроддзя і адсочваць становішча камеры; • выкарыстоўваць камеру.</translation> <translation id="337363190475750230">Ініцыялізацыя скасавана</translation> +<translation id="3375754925484257129">Запусціць праверку бяспекі Chrome</translation> <translation id="3377144306166885718">Сервер выкарыстоўвае ўстарэлую версію пратакола TLS.</translation> <translation id="3377188786107721145">Памылка аналізу палітыкі</translation> <translation id="3377736046129930310">Выкарыстоўваць блакіроўку экрана для хутчэйшага пацвярджэння картак</translation> <translation id="3380365263193509176">Невядомая памылка</translation> <translation id="3380864720620200369">Ідэнтыфікатар кліента:</translation> <translation id="3381668585148405088">Пацвердзіце куплю</translation> +<translation id="3383566085871012386">Бягучы парадак прыярытэту</translation> <translation id="3387261909427947069">Спосабы аплаты</translation> <translation id="3391030046425686457">Адрас дастаўкі</translation> <translation id="3391482648489541560">змяненне файлаў</translation> @@ -768,6 +779,7 @@ <translation id="3462200631372590220">Схаваць дадатковую інфармацыю</translation> <translation id="3467763166455606212">Патрабуецца імя ўладальніка карткі</translation> <translation id="3468054117417088249"><ph name="TAB_SWITCH_SUFFIX" />, укладка адкрытая, каб перайсці на адкрытую ўкладку, націсніце Tab, затым Enter</translation> +<translation id="3470563864795286535"><ph name="CLOSE_INCOGNITO_WINDOWS_FOCUSED_FRIENDLY_MATCH_TEXT" />. Каб закрыць усе адкрытыя вокны ў рэжыме інкогніта, націсніце Tab, затым Enter</translation> <translation id="3479552764303398839">Не зараз</translation> <translation id="3484560055331845446">Вы можаце страціць доступ да свайго Уліковага запісу Google. Chrome рэкамендуе змяніць пароль. Вас папросяць увайсці ва ўліковы запіс.</translation> <translation id="3487845404393360112">Латок 4</translation> @@ -805,6 +817,7 @@ <translation id="3611395257124510155">Віртуальная картка (<ph name="CARD_IDENTIFIER" />)</translation> <translation id="3614103345592970299">Памер 2</translation> <translation id="361438452008624280">Элемент спіса "<ph name="LANGUAGE_ID" />": мова невядомая або не падтрымліваецца.</translation> +<translation id="3614934205542186002"><ph name="RUN_CHROME_SAFETY_CHECK_FOCUSED_FRIENDLY_MATCH_TEXT" />. Каб выканаць праверку бяспекі ў наладах Chrome, націсніце Tab, затым Enter</translation> <translation id="3615877443314183785">Увядзіце сапраўдную дату заканчэння тэрміну дзеяння</translation> <translation id="36224234498066874">Выдаліць гісторыю праглядаў...</translation> <translation id="362276910939193118">Паказаць усю гісторыю</translation> @@ -1400,6 +1413,7 @@ <translation id="5478437291406423475">B6/C4 (канверт)</translation> <translation id="5481076368049295676">Праз гэта змесціва на вашу прыладу можа ўсталявацца небяспечнае праграмнае забеспячэнне, якое будзе красці або выдаляць інфармацыю. <ph name="BEGIN_LINK" />Усе роўна паказаць<ph name="END_LINK" /></translation> <translation id="54817484435770891">Дадайце сапраўдны адрас</translation> +<translation id="5485973315555778056">Машына воблака</translation> <translation id="5490432419156082418">Адрасы і іншае</translation> <translation id="5492298309214877701">У інтранэце кампаніі, арганізацыі або школы гэты сайт мае той жа URL-адрас, што і знешні вэб-сайт. <ph name="LINE_BREAK" /> @@ -1429,6 +1443,7 @@ <translation id="5571083550517324815">З гэтага адраса забраць нельга – выберыце іншы.</translation> <translation id="5580958916614886209">Праверце месяц заканчэння тэрміну дзеяння і паўтарыце спробу</translation> <translation id="5586446728396275693">Няма захаваных адрасоў</translation> +<translation id="5587987780934666589">Карыстальнік платформы</translation> <translation id="5593349413089863479">Падключэнне не цалкам бяспечнае</translation> <translation id="5595485650161345191">Рэдагаваць адрас</translation> <translation id="5598944008576757369">Выбраць спосаб аплаты</translation> @@ -1600,6 +1615,7 @@ <translation id="6218753634732582820">Выдаліць адрас з Chromium?</translation> <translation id="622039917539443112">Паралельны згіб</translation> <translation id="6221345481584921695">Google Бяспечны прагляд толькі што <ph name="BEGIN_LINK" />выявіў шкоднае ПЗ<ph name="END_LINK" /> на сайце <ph name="SITE" />. Сайты, якія звычайна з'яўляюцца надзейнымі, часам заражаюцца шкодным ПЗ. Шкоднае змесціва паходзіць з хоста <ph name="SUBRESOURCE_HOST" />, вядомай крыніцы шкоднага ПЗ.</translation> +<translation id="6226163402662242066"><ph name="MANAGE_CHROME_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />. Каб персаналізаваць інструменты даступнасці ў наладах Chrome, націсніце Tab, затым Enter</translation> <translation id="6234122620015464377">Абрэзка пасля кожнага дакумента</translation> <translation id="6240447795304464094">Лагатып Google Pay</translation> <translation id="6241121617266208201">Схаваць прапановы</translation> @@ -1618,6 +1634,7 @@ <translation id="6279098320682980337">Не ўказаны нумар віртуальнай карткі? Скапіруйце рэквізіты карткі, націснуўшы на іх</translation> <translation id="6280223929691119688">Немагчыма адправіць на гэты адрас. Выберыце іншы адрас.</translation> <translation id="6282194474023008486">Паштовы індэкс</translation> +<translation id="6285507000506177184">Кнопка "Кіраваць спампоўкамі ў Chrome". Каб кіраваць файламі, якія вы спампавалі ў браўзеры Chrome, націсніце Enter</translation> <translation id="6289939620939689042">Колер старонкі</translation> <translation id="6290238015253830360">Рэкамендаваныя вам артыкулы з'явяцца тут</translation> <translation id="6293309776179964942">JIS B5</translation> @@ -1733,6 +1750,7 @@ <translation id="6689249931105087298">Адносны са сцісканнем чорных пунктаў</translation> <translation id="6689271823431384964">Chrome прапаноўвае захоўваць карткі ва Уліковым запісе Google, бо вы ўвайшлі ў сістэму. Гэту функцыю можна выключыць у наладах. Імя ўладальніка карткі ўзята з вашага ўліковага запісу.</translation> <translation id="6694681292321232194"><ph name="FIND_MY_PHONE_FOCUSED_FRIENDLY_MATCH_TEXT" />. Каб знайсці сваю прыладу ва Уліковым запісе Google, націсніце Tab, затым Enter</translation> +<translation id="6696588630955820014">Кнопка "Абагуліць гэту ўкладку". Каб абагуліць гэту ўкладку (абагуліць спасылку, стварыць QR-код, трансліраваць яе і г. д.), націсніце Enter</translation> <translation id="6698381487523150993">Створаны:</translation> <translation id="6702919718839027939">Прэзентацыя</translation> <translation id="6710213216561001401">Назад</translation> @@ -1938,6 +1956,7 @@ <translation id="7392089738299859607">Абнавіць адрас</translation> <translation id="7399802613464275309">Праверка бяспекі</translation> <translation id="7400418766976504921">URL-адрас</translation> +<translation id="7403392780200267761">Абагуліць гэту ўкладку (абагуліць спасылку, стварыць QR-код, трансліраваць яе і г. д.)</translation> <translation id="7403591733719184120">Прылада "<ph name="DEVICE_NAME" />" знаходзіцца пад кіраваннем</translation> <translation id="7407424307057130981"><p>Вы бачыце гэту памылку, бо на вашым камп'ютары з сістэмай Windows усталявана праграмнае забеспячэнне Superfish.</p> <p>Каб часова выключыць гэта праграмнае забеспячэнне і атрымаць магчымасць падключыцца да сеткі, выканайце наступныя крокі. Пры гэтым вам спатрэбяцца правы адміністратара.</p> @@ -2114,6 +2133,7 @@ <translation id="7953569069500808819">Сшыванне па краі зверху</translation> <translation id="7956713633345437162">Мабільныя закладкі</translation> <translation id="7961015016161918242">Ніколі</translation> +<translation id="7962467575542381659">Машына платформы</translation> <translation id="7966803981046576691">Тып уліковага запісу задання</translation> <translation id="79682505114836835">Значэнне <ph name="VALUE" /> не з'яўляецца правільным шаснаццатковым кодам колеру.</translation> <translation id="7968982339740310781">Паказаць падрабязныя звесткі</translation> @@ -2168,6 +2188,7 @@ <translation id="810875025413331850">Прылад паблізу не знойдзена.</translation> <translation id="8116925261070264013">Без гуку</translation> <translation id="8118489163946903409">Спосаб аплаты</translation> +<translation id="8124639700796374294">Кнопка "Наладзіць Chrome". Каб наладзіць выгляд браўзера, націсніце Enter</translation> <translation id="8127301229239896662">Праграма "<ph name="SOFTWARE_NAME" />" не была належным чынам усталявана на камп'ютар або ў сетцы: папрасіце IT-адміністратара вырашыць гэту праблему.</translation> <translation id="8131740175452115882">Пацвердзіць</translation> <translation id="8148608574971654810">Версія PDF:</translation> @@ -2350,6 +2371,7 @@ <translation id="87601671197631245">Гэты сайт выкарыстоўвае ўстарэлую канфігурацыю бяспекі, таму звесткі пра вас (напрыклад, паролі, паведамленні або нумары крэдытных картак) пры іх адпраўцы на гэты сайт могуць быць раскрыты.</translation> <translation id="8761567432415473239">Google Бяспечны прагляд нядаўна <ph name="BEGIN_LINK" />выявіў шкодныя праграмы<ph name="END_LINK" /> на сайце <ph name="SITE" />.</translation> <translation id="8763927697961133303">Прылада USB</translation> +<translation id="8763986294015493060">Закрыць усе адкрытыя вокны ў рэжыме інкогніта</translation> <translation id="8766943070169463815">Аркуш аўтэнтыфікацыі ўліковых даных для бяспечных плацяжоў адкрыты</translation> <translation id="877985182522063539">A4</translation> <translation id="8790007591277257123">&Узнавіць выдаленне</translation> @@ -2363,6 +2385,7 @@ <translation id="8816395686387277279"><ph name="UPDATE_CHROME_FOCUSED_FRIENDLY_MATCH_TEXT" />. Каб абнавіць браўзер Chrome праз яго налады, націсніце Tab, затым Enter</translation> <translation id="8820817407110198400">Закладкі</translation> <translation id="882338992931677877">Слот ручной падачы</translation> +<translation id="8834380158646307944">Кнопка "Закрыць вокны ў рэжыме інкогніта". Каб закрыць усе адкрытыя вокны ў рэжыме інкогніта, націсніце Enter</translation> <translation id="883848425547221593">Іншыя закладкі</translation> <translation id="884264119367021077">Адрас дастаўкі</translation> <translation id="884923133447025588">Механізм адклікання не знойдзены.</translation> @@ -2416,6 +2439,7 @@ <translation id="9020200922353704812">Патрабуецца адрас для выстаўлення рахункаў па крэдытнай картцы</translation> <translation id="9020542370529661692">Гэта старонка была перакладзена на наступную мову: <ph name="TARGET_LANGUAGE" /></translation> <translation id="9020742383383852663">A8</translation> +<translation id="9021429684248523859"><ph name="SHARE_THIS_PAGE_FOCUSED_FRIENDLY_MATCH_TEXT" />. Каб абагуліць гэту ўкладку (абагуліць спасылку, стварыць QR-код, трансліраваць яе і г. д.), націсніце Tab, затым Enter</translation> <translation id="9025348182339809926">(Несапраўдны)</translation> <translation id="9030265603405983977">Манахромны</translation> <translation id="9035022520814077154">Памылка бяспекі</translation>
diff --git a/components/strings/components_strings_et.xtb b/components/strings/components_strings_et.xtb index 3873453..bd8b0d21 100644 --- a/components/strings/components_strings_et.xtb +++ b/components/strings/components_strings_et.xtb
@@ -157,6 +157,7 @@ <translation id="1422930527989633628">Saab küsida luba läheduses asuvate Bluetooth-seadmete tuvastamiseks</translation> <translation id="1426410128494586442">Jah</translation> <translation id="1428146450423315676">Virnastaja 7</translation> +<translation id="142858679511221695">Pilves olev kasutaja</translation> <translation id="1428729058023778569">Näete seda hoiatust, kuna see sait ei toeta HTTPS-i. <ph name="BEGIN_LEARN_MORE_LINK" />Lisateave<ph name="END_LEARN_MORE_LINK" /></translation> <translation id="1430915738399379752">Printimine</translation> <translation id="1432581352905426595">Halda otsingumootoreid</translation> @@ -718,6 +719,7 @@ <translation id="3329013043687509092">Küllastus</translation> <translation id="3333762389743153920">Ei saa virtuaalkaardina kasutada</translation> <translation id="3338095232262050444">Turvaline</translation> +<translation id="3339446062576134663">Pilv (Ash)</translation> <translation id="3355823806454867987">Muuda puhverserveri seadeid ...</translation> <translation id="3360103848165129075">Maksetöötleja leht</translation> <translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />ei salvesta<ph name="END_EMPHASIS" /> järgmist teavet: @@ -741,6 +743,7 @@ <translation id="3380365263193509176">Tundmatu viga</translation> <translation id="3380864720620200369">Kliendi ID:</translation> <translation id="3381668585148405088">Kinnitage oma ost</translation> +<translation id="3383566085871012386">Praegune tähtsuse järjekord</translation> <translation id="3387261909427947069">Makseviisid</translation> <translation id="3391030046425686457">Kohaletoimetamise aadress</translation> <translation id="3391482648489541560">failide muutmine</translation> @@ -1410,6 +1413,7 @@ <translation id="5478437291406423475">B6/C4 (ümbrik)</translation> <translation id="5481076368049295676">See sisu võib üritada installida teie seadmesse ohtlikku tarkvara, mis varastab või kustutab teie teavet. <ph name="BEGIN_LINK" />Kuva ikkagi<ph name="END_LINK" />.</translation> <translation id="54817484435770891">Sisestage sobiv aadress</translation> +<translation id="5485973315555778056">Pilveseade</translation> <translation id="5490432419156082418">Aadressid ja muu</translation> <translation id="5492298309214877701">Sellel ettevõtte, organisatsiooni või kooli intranetis oleval saidil on sama URL mis välisel veebisaidil. <ph name="LINE_BREAK" /> @@ -1439,6 +1443,7 @@ <translation id="5571083550517324815">Sellelt aadressilt ei saa kaupa kätte. Valige mõni teine aadress.</translation> <translation id="5580958916614886209">Kontrollige aegumiskuud ja proovige uuesti</translation> <translation id="5586446728396275693">Salvestatud aadresse pole</translation> +<translation id="5587987780934666589">Platvormi kasutaja</translation> <translation id="5593349413089863479">Ühendus pole täiesti turvaline</translation> <translation id="5595485650161345191">Muuda aadressi</translation> <translation id="5598944008576757369">Valige makseviis</translation> @@ -2127,6 +2132,7 @@ <translation id="7953569069500808819">Õmblus ülaservas</translation> <translation id="7956713633345437162">Mobiili järjehoidjad</translation> <translation id="7961015016161918242">Mitte kunagi</translation> +<translation id="7962467575542381659">Platvormi seade</translation> <translation id="7966803981046576691">Töökonto tüüp</translation> <translation id="79682505114836835">Väärtus „<ph name="VALUE" />“ on sobimatu kuueteistkümnendsüsteemis värvikood.</translation> <translation id="7968982339740310781">Kuva üksikasjad</translation>
diff --git a/components/strings/components_strings_gl.xtb b/components/strings/components_strings_gl.xtb index e34fc38c..05b7f1e0 100644 --- a/components/strings/components_strings_gl.xtb +++ b/components/strings/components_strings_gl.xtb
@@ -82,6 +82,7 @@ <translation id="124116460088058876">Máis idiomas</translation> <translation id="1243027604378859286">Autor:</translation> <translation id="1246424317317450637">Negra</translation> +<translation id="1248573052514400575"><ph name="MANAGE_CHROMEOS_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />. Para personalizar as ferramentas de accesibilidade na configuración de Chrome OS, preme Tabulador e, a continuación, Introducir</translation> <translation id="1250759482327835220">Para pagar máis rápido a próxima vez, garda a túa tarxeta, o nome e o enderezo de facturación na túa Conta de Google.</translation> <translation id="1252799212227771492">Botón Crear folla. Preme Introducir para crear rapidamente unha nova folla de cálculo de Google</translation> <translation id="1253921432148366685"><ph name="TYPE_1" /> e <ph name="TYPE_2" /> (sincronizado)</translation> @@ -322,6 +323,7 @@ <translation id="192020519938775529">{COUNT,plural, =0{Ningún}=1{1 sitio}other{# sitios}}</translation> <translation id="1923390796829649802">Botón para xestionar a configuración de accesibilidade. Para personalizar as túas ferramentas de accesibilidade na configuración de Chrome OS, preme Introducir</translation> <translation id="1924727005275031552">Novo</translation> +<translation id="1927439593081478069">Botón para executar a comprobación de seguranza de Chrome. Se queres executar unha comprobación de seguranza na configuración de Chrome, preme Introducir</translation> <translation id="1939175642807587452">Pode pedirche permiso para enviar notificacións</translation> <translation id="1945968466830820669">Poderías perder o acceso á conta da túa organización ou alguén podería roubarche a identidade. Chromium recoméndache que cambies de contrasinal agora.</translation> <translation id="1947454675006758438">Grampa na parte superior dereita</translation> @@ -341,6 +343,7 @@ <translation id="2003709556000175978">Restablecer o teu contrasinal agora</translation> <translation id="2003775180883135320">Catro perforacións na parte superior</translation> <translation id="201174227998721785">Xestiona na configuración de Chrome os permisos e os datos almacenados dos sitios</translation> +<translation id="2019607688127825327">Botón para xestionar a configuración de accesibilidade. Se queres personalizar as ferramentas de accesibilidade na configuración de Chrome, preme Introducir</translation> <translation id="2025115093177348061">Realidade aumentada</translation> <translation id="2025186561304664664">O proxy está establecido como configurado automaticamente.</translation> <translation id="2025891858974379949">Contido inseguro</translation> @@ -506,6 +509,7 @@ <translation id="2556876185419854533">&Desfacer modificación</translation> <translation id="2570734079541893434">Xestionar configuración</translation> <translation id="257674075312929031">Grupo</translation> +<translation id="2576880857912732701">Botón para xestionar a configuración de seguranza. Se queres xestionar na configuración de Chrome a Navegación segura e outras opcións, preme Introducir</translation> <translation id="2586657967955657006">Portapapeis</translation> <translation id="2587730715158995865">De <ph name="ARTICLE_PUBLISHER" />. Le esta e <ph name="OTHER_ARTICLE_COUNT" /> noticias máis.</translation> <translation id="2587841377698384444">ID de API de directorio:</translation> @@ -550,6 +554,7 @@ <translation id="2713444072780614174">Branco</translation> <translation id="2715612312510870559"><ph name="UPDATE_CREDIT_CARD_FOCUSED_FRIENDLY_MATCH_TEXT" />. Preme Tab e, a continuación, Intro para xestionar os teus métodos de pago e a información das tarxetas de crédito desde a configuración de Chrome</translation> <translation id="2721148159707890343">Solicitude correcta</translation> +<translation id="2723669454293168317">Executar unha comprobación de seguranza na configuración de Chrome</translation> <translation id="2726001110728089263">Bandexa lateral</translation> <translation id="2728127805433021124">O certificado do servidor está asinado cun algoritmo de sinatura débil.</translation> <translation id="2730326759066348565"><ph name="BEGIN_LINK" />Executar diagnósticos de conectividade<ph name="END_LINK" /></translation> @@ -580,6 +585,7 @@ <translation id="2859806420264540918">Este sitio mostra anuncios intrusivos ou enganosos.</translation> <translation id="287596039013813457">Amigable</translation> <translation id="2876489322757410363">Sairás do modo de incógnito para pagar a través dunha aplicación externa. Queres continuar?</translation> +<translation id="2876949457278336305"><ph name="MANAGE_SECURITY_SETTINGS_FOCUSED_FRIENDLY_MATCH_TEXT" />. Para xestionar na configuración de Chrome a Navegación segura e outras opcións, preme Tabulador e, a continuación, Introducir</translation> <translation id="2878197950673342043">Dobrez de póster</translation> <translation id="2878424575911748999">A1</translation> <translation id="2880660355386638022">Colocación das ventás</translation> @@ -685,6 +691,7 @@ <translation id="3229041911291329567">Información sobre a versión do dispositivo e do navegador</translation> <translation id="323107829343500871">Introduce o código CVC da tarxeta <ph name="CREDIT_CARD" /></translation> <translation id="3234666976984236645">Detectar sempre contido importante neste sitio</translation> +<translation id="3240683217920639535"><ph name="MANAGE_CHROME_THEMES_FOCUSED_FRIENDLY_MATCH_TEXT" />. Para personalizar o aspecto do navegador, preme Tabulador e, a continuación, Introducir</translation> <translation id="3240791268468473923">A folla da credencial de pagos seguros correspondente ás credenciais non coincidentes está aberta</translation> <translation id="3249845759089040423">Moderno</translation> <translation id="3252266817569339921">Francés</translation> @@ -729,6 +736,7 @@ • Crear un mapa 3D do que te rodea e facer un seguimento da posición da cámara • Usar a túa cámara</translation> <translation id="337363190475750230">Desaprovisionado</translation> +<translation id="3375754925484257129">Executar comprobación de seguranza de Chrome</translation> <translation id="3377144306166885718">O servidor utilizou unha versión obsoleta de TLS.</translation> <translation id="3377188786107721145">Erro de análise da política</translation> <translation id="3377736046129930310">Usar o bloqueo de pantalla para confirmar as tarxetas máis rápido</translation> @@ -770,6 +778,7 @@ <translation id="3462200631372590220">Ocultar detalles</translation> <translation id="3467763166455606212">Precísase o nome do titular da tarxeta</translation> <translation id="3468054117417088249">A pestana <ph name="TAB_SWITCH_SUFFIX" /> está aberta actualmente, preme o tabulador e despois Intro para cambiar á pestana aberta</translation> +<translation id="3470563864795286535"><ph name="CLOSE_INCOGNITO_WINDOWS_FOCUSED_FRIENDLY_MATCH_TEXT" />. Para pechar todas as ventás do modo de incógnito que estean abertas, preme Tabulador e, a continuación, Introducir</translation> <translation id="3479552764303398839">Agora non</translation> <translation id="3484560055331845446">Poderías perder o acceso á túa Conta de Google. Chrome recoméndache que cambies de contrasinal agora. Deberás iniciar sesión.</translation> <translation id="3487845404393360112">Bandexa 4</translation> @@ -808,6 +817,7 @@ <translation id="3611395257124510155">Tarxeta virtual para <ph name="CARD_IDENTIFIER" /></translation> <translation id="3614103345592970299">Tamaño 2</translation> <translation id="361438452008624280">Entrada da lista "<ph name="LANGUAGE_ID" />": idioma descoñecido ou non compatible.</translation> +<translation id="3614934205542186002"><ph name="RUN_CHROME_SAFETY_CHECK_FOCUSED_FRIENDLY_MATCH_TEXT" />. Se queres executar unha comprobación de seguranza na configuración de Chrome, preme Tabulador e, a continuación, Introducir</translation> <translation id="3615877443314183785">Introduce unha data de caducidade válida</translation> <translation id="36224234498066874">Borrar datos de navegación...</translation> <translation id="362276910939193118">Mostrar historial completo</translation> @@ -1605,6 +1615,7 @@ <translation id="6218753634732582820">Queres eliminar o enderezo de Chromium?</translation> <translation id="622039917539443112">Dobrez en paralelo</translation> <translation id="6221345481584921695">A navegación segura de Google <ph name="BEGIN_LINK" />detectou software malicioso<ph name="END_LINK" /> en <ph name="SITE" /> recentemente. Ás veces, os sitios web que adoitan ser seguros inféctanse con software malicioso. O contido malicioso procede de <ph name="SUBRESOURCE_HOST" />, un coñecido distribuidor de software malicioso.</translation> +<translation id="6226163402662242066"><ph name="MANAGE_CHROME_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />. Para personalizar as ferramentas de accesibilidade na configuración de Chrome, preme Tabulador e, a continuación, Introducir</translation> <translation id="6234122620015464377">Recorte despois de cada documento</translation> <translation id="6240447795304464094">Logotipo de Google Pay</translation> <translation id="6241121617266208201">Ocultar suxestións</translation> @@ -1623,6 +1634,7 @@ <translation id="6279098320682980337">Non se autocompletou o número da tarxeta virtual? Para copialo, fai clic nos detalles da tarxeta</translation> <translation id="6280223929691119688">Non se pode realizar a entrega neste enderezo. Selecciona un diferente.</translation> <translation id="6282194474023008486">Código postal</translation> +<translation id="6285507000506177184">Botón para xestionar as descargas en Chrome. Se queres xestionar os ficheiros que descargaches en Chrome, preme Introducir</translation> <translation id="6289939620939689042">Cor das páxinas</translation> <translation id="6290238015253830360">Os teus artigos suxeridos aparecerán aquí</translation> <translation id="6293309776179964942">JIS B5</translation> @@ -1738,6 +1750,7 @@ <translation id="6689249931105087298">Relativo con compresión de puntos negros</translation> <translation id="6689271823431384964">Chrome permíteche gardar as túas tarxetas na túa Conta de Google porque tes a sesión iniciada. Podes cambiar esta opción na configuración cando queiras. O nome do titular da tarxeta procede da túa conta.</translation> <translation id="6694681292321232194"><ph name="FIND_MY_PHONE_FOCUSED_FRIENDLY_MATCH_TEXT" />. Para acceder á función da Conta de Google Localizar o meu dispositivo, preme Tabulador e, a continuación, Introducir</translation> +<translation id="6696588630955820014">Botón para compartir esta pestana. Se queres compartir esta pestana mediante unha ligazón, a través da creación dun código QR, coa súa emisión e outras opcións, preme Introducir</translation> <translation id="6698381487523150993">Creada:</translation> <translation id="6702919718839027939">Presentar</translation> <translation id="6710213216561001401">Anterior</translation> @@ -1943,6 +1956,7 @@ <translation id="7392089738299859607">Actualizar enderezo</translation> <translation id="7399802613464275309">Revisión de seguranza</translation> <translation id="7400418766976504921">URL</translation> +<translation id="7403392780200267761">Compartir esta pestana mediante unha ligazón, a través da creación dun código QR, coa súa emisión e outras opcións</translation> <translation id="7403591733719184120">O teu <ph name="DEVICE_NAME" /> está xestionado</translation> <translation id="7407424307057130981"><p>Verás este erro se tes o software Superfish no teu ordenador Windows.</p> <p>Sigue estes pasos para desactivar temporalmente o software e poder acceder á web. Precisarás privilexios de administrador.</p> @@ -2173,6 +2187,7 @@ <translation id="810875025413331850">Non se encontraron dispositivos cerca.</translation> <translation id="8116925261070264013">Silenciados</translation> <translation id="8118489163946903409">Método de pago</translation> +<translation id="8124639700796374294">Botón para personalizar Chrome. Se queres personalizar o aspecto do navegador, preme Introducir</translation> <translation id="8127301229239896662"><ph name="SOFTWARE_NAME" /> non se instalou correctamente no teu ordenador ou na rede. Pídelle ao administrador de TI que solucione este problema.</translation> <translation id="8131740175452115882">Confirmar</translation> <translation id="8148608574971654810">Versión do PDF:</translation> @@ -2355,6 +2370,7 @@ <translation id="87601671197631245">Este sitio utiliza unha configuración de seguranza obsoleta que pode poñer en risco a túa información (por exemplo, contrasinais, mensaxes ou números de tarxetas de crédito) cando se lle envía.</translation> <translation id="8761567432415473239">A navegación segura de Google <ph name="BEGIN_LINK" />atopou programas prexudiciais<ph name="END_LINK" /> recentemente en <ph name="SITE" />.</translation> <translation id="8763927697961133303">Dispositivo USB</translation> +<translation id="8763986294015493060">Pechar todas as ventás do modo de incógnito que estean abertas</translation> <translation id="8766943070169463815">A folla de autenticación da credencial de pagos seguros está aberta</translation> <translation id="877985182522063539">A4</translation> <translation id="8790007591277257123">&Refacer eliminación</translation> @@ -2368,6 +2384,7 @@ <translation id="8816395686387277279"><ph name="UPDATE_CHROME_FOCUSED_FRIENDLY_MATCH_TEXT" />. Preme Tab e, a continuación, Intro para actualizar Chrome desde a configuración do navegador</translation> <translation id="8820817407110198400">Marcadores</translation> <translation id="882338992931677877">Oco manual</translation> +<translation id="8834380158646307944">Botón para pechar as ventás do modo de incógnito. se queres pechar todas as ventás do modo de incógnito que estean abertas, preme Introducir</translation> <translation id="883848425547221593">Outros marcadores</translation> <translation id="884264119367021077">Enderezo de envío</translation> <translation id="884923133447025588">Non se atopou ningún mecanismo de revogación.</translation> @@ -2421,6 +2438,7 @@ <translation id="9020200922353704812">É obrigatorio introducir o enderezo de facturación da tarxeta</translation> <translation id="9020542370529661692">Traduciuse esta páxina ao <ph name="TARGET_LANGUAGE" /></translation> <translation id="9020742383383852663">A8</translation> +<translation id="9021429684248523859"><ph name="SHARE_THIS_PAGE_FOCUSED_FRIENDLY_MATCH_TEXT" />. Para compartir esta pestana mediante unha ligazón, a través da creación dun código QR, coa súa emisión e outras opcións, preme Tabulador e, a continuación, Introducir</translation> <translation id="9025348182339809926">(Non válido)</translation> <translation id="9030265603405983977">Monocromo</translation> <translation id="9035022520814077154">Erro de seguranza</translation>
diff --git a/components/strings/components_strings_hr.xtb b/components/strings/components_strings_hr.xtb index 1be3831..6bfd154 100644 --- a/components/strings/components_strings_hr.xtb +++ b/components/strings/components_strings_hr.xtb
@@ -82,6 +82,7 @@ <translation id="124116460088058876">Više jezika</translation> <translation id="1243027604378859286">Autor:</translation> <translation id="1246424317317450637">Podebljano</translation> +<translation id="1248573052514400575"><ph name="MANAGE_CHROMEOS_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da biste prilagodili svoje alate za pristupačnost u postavkama OS-a Chrome</translation> <translation id="1250759482327835220">Da biste sljedeći put platili brže, spremite karticu, ime i adresu za naplatu na svoj Google račun.</translation> <translation id="1252799212227771492">Gumb Izradite tablicu, pritisnite Enter da biste brzo izradili novu Google tablicu</translation> <translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (sinkronizirano)</translation> @@ -323,6 +324,7 @@ <translation id="192020519938775529">{COUNT,plural, =0{Nijedna}=1{1 web-lokacija}one{# web-lokacija}few{# web-lokacije}other{# web-lokacija}}</translation> <translation id="1923390796829649802">Gumb Upravljajte postavkama pristupačnosti, pritisnite Enter da biste prilagodili svoje alate za pristupačnost u postavkama OS-a Chrome</translation> <translation id="1924727005275031552">Novo</translation> +<translation id="1927439593081478069">Gumb Pokreni Chromeovu sigurnosnu provjeru, pritisnite Enter da biste pokrenuli sigurnosnu provjeru u postavkama Chromea</translation> <translation id="1939175642807587452">Može tražiti dopuštenje za slanje obavijesti</translation> <translation id="1945968466830820669">Mogli biste izgubiti pristup računu svoje organizacije ili bi netko mogao ukrasti vaš identitet. Chromium preporučuje da odmah promijenite zaporku.</translation> <translation id="1947454675006758438">Spajanje pri vrhu desno</translation> @@ -342,6 +344,7 @@ <translation id="2003709556000175978">Poništite zaporku odmah</translation> <translation id="2003775180883135320">Četverostruko bušenje pri vrhu</translation> <translation id="201174227998721785">Dopuštenjima i podacima koji se pohranjuju na web-lokacijama možete upravljati u postavkama Chromea</translation> +<translation id="2019607688127825327">Gumb Upravljaj postavkama pristupačnosti, pritisnite Enter da biste prilagodili svoje alate za pristupačnost u postavkama Chromea</translation> <translation id="2025115093177348061">Proširena stvarnost</translation> <translation id="2025186561304664664">Proxy je postavljen na automatsko konfiguriranje.</translation> <translation id="2025891858974379949">Nesiguran sadržaj</translation> @@ -507,6 +510,7 @@ <translation id="2556876185419854533">&Poništi uređivanje</translation> <translation id="2570734079541893434">Upravljajte postavkama</translation> <translation id="257674075312929031">Grupa</translation> +<translation id="2576880857912732701">Gumb Upravljaj sigurnosnim postavkama, pritisnite Enter da biste upravljali sigurnim pregledavanjem i drugim značajkama u postavkama Chromea</translation> <translation id="2586657967955657006">Međuspremnik</translation> <translation id="2587730715158995865">Izdavač: <ph name="ARTICLE_PUBLISHER" />. Pročitajte ovaj članak i još <ph name="OTHER_ARTICLE_COUNT" />.</translation> <translation id="2587841377698384444">ID API-ja direktorija:</translation> @@ -551,6 +555,7 @@ <translation id="2713444072780614174">Bijela</translation> <translation id="2715612312510870559"><ph name="UPDATE_CREDIT_CARD_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da biste upravljali podacima o plaćanju i kreditnoj kartici u postavkama Chromea</translation> <translation id="2721148159707890343">Zahtjev je uspio</translation> +<translation id="2723669454293168317">Izvršite sigurnosnu provjeru u postavkama Chromea</translation> <translation id="2726001110728089263">Bočna ladica</translation> <translation id="2728127805433021124">Certifikat poslužitelja potpisan je slabim algoritmom potpisa.</translation> <translation id="2730326759066348565"><ph name="BEGIN_LINK" />pokrenuti Dijagnostiku povezivosti<ph name="END_LINK" /></translation> @@ -581,6 +586,7 @@ <translation id="2859806420264540918">Ova web-lokacija prikazuje ometajuće ili obmanjujuće oglase.</translation> <translation id="287596039013813457">Prijateljski</translation> <translation id="2876489322757410363">Napuštate anonimni način rada da biste platili putem vanjske aplikacije. Želite li nastaviti?</translation> +<translation id="2876949457278336305"><ph name="MANAGE_SECURITY_SETTINGS_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da biste upravljali sigurnim pregledavanjem i drugim značajkama u postavkama Chromea</translation> <translation id="2878197950673342043">Presavijanje u obliku postera</translation> <translation id="2878424575911748999">A1</translation> <translation id="2880660355386638022">Postavljanje prozora</translation> @@ -686,6 +692,7 @@ <translation id="3229041911291329567">Informacije o verziji uređaja i preglednika</translation> <translation id="323107829343500871">Unesite CVC za karticu <ph name="CREDIT_CARD" /></translation> <translation id="3234666976984236645">Uvijek otkrivaj važan sadržaj na ovoj web-lokaciji</translation> +<translation id="3240683217920639535"><ph name="MANAGE_CHROME_THEMES_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da biste prilagodili izgled preglednika</translation> <translation id="3240791268468473923">Otvoren je list obavijesti da nema podudarnih vjerodajnica za sigurno plaćanje</translation> <translation id="3249845759089040423">Živopisno</translation> <translation id="3252266817569339921">Francuski</translation> @@ -730,6 +737,7 @@ • izradu 3D karte vašeg okruženja i praćenje položaja kamere • upotrebu kamere</translation> <translation id="337363190475750230">Dodjela je uklonjena</translation> +<translation id="3375754925484257129">Pokreni Chromeovu sigurnosnu provjeru</translation> <translation id="3377144306166885718">Poslužitelj je koristio zastarjelu verziju TLS-a.</translation> <translation id="3377188786107721145">Pogreška pri analizi pravila</translation> <translation id="3377736046129930310">Za brže potvrđivanje kartica upotrijebite zaključavanje zaslona</translation> @@ -771,6 +779,7 @@ <translation id="3462200631372590220">Sakrij napredno</translation> <translation id="3467763166455606212">Potrebno je unijeti ime nositelja kartice</translation> <translation id="3468054117417088249"><ph name="TAB_SWITCH_SUFFIX" />, trenutačno otvoreno, pritisnite karticu pa Enter za prebacivanje na otvorenu karticu</translation> +<translation id="3470563864795286535"><ph name="CLOSE_INCOGNITO_WINDOWS_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da biste zatvorili sve anonimne prozore koji su trenutačno otvoreni</translation> <translation id="3479552764303398839">Ne sada</translation> <translation id="3484560055331845446">Mogli biste izgubiti pristup svojem Google računu. Chrome preporučuje da odmah promijenite zaporku. Morat ćete se prijaviti.</translation> <translation id="3487845404393360112">Ladica 4</translation> @@ -809,6 +818,7 @@ <translation id="3611395257124510155">Virtualna kartica za <ph name="CARD_IDENTIFIER" /></translation> <translation id="3614103345592970299">Veličina 2</translation> <translation id="361438452008624280">Unos na popisu "<ph name="LANGUAGE_ID" />": nepoznati ili nepodržani jezik.</translation> +<translation id="3614934205542186002"><ph name="RUN_CHROME_SAFETY_CHECK_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da biste pokrenuli sigurnosnu provjeru u postavkama Chromea</translation> <translation id="3615877443314183785">Unesite važeći datum isteka</translation> <translation id="36224234498066874">Obriši podatke o pregledavanju...</translation> <translation id="362276910939193118">Pokaži cijelu povijest</translation> @@ -1606,6 +1616,7 @@ <translation id="6218753634732582820">Želite li ukloniti adresu iz Chromiuma?</translation> <translation id="622039917539443112">Paralelno presavijanje</translation> <translation id="6221345481584921695">Google sigurno pregledavanje nedavno je <ph name="BEGIN_LINK" />otkrilo zlonamjerni sadržaj<ph name="END_LINK" /> na <ph name="SITE" />. Web-lokacije koje su inače sigurne ponekad mogu biti zaražene zlonamjernim softverom. Zlonamjerni sadržaj potječe s hosta <ph name="SUBRESOURCE_HOST" /> koji je poznat po distribuciji zlonamjernog softvera.</translation> +<translation id="6226163402662242066"><ph name="MANAGE_CHROME_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da biste prilagodili svoje alate za pristupačnost u postavkama Chromea</translation> <translation id="6234122620015464377">Obreži nakon svakog dokumenta</translation> <translation id="6240447795304464094">Logotip Google Paya</translation> <translation id="6241121617266208201">Sakrij prijedloge</translation> @@ -1624,6 +1635,7 @@ <translation id="6279098320682980337">Broj virtualne kartice nije ispunjen? Kliknite podatke o kartici da biste kopirali</translation> <translation id="6280223929691119688">Dostava na tu adresu nije moguća. Odaberite drugu adresu.</translation> <translation id="6282194474023008486">Poštanski broj</translation> +<translation id="6285507000506177184">Gumb Upravljaj preuzimanjima u Chromeu, pritisnite Enter da biste upravljali datotekama koje ste preuzeli u Chromeu</translation> <translation id="6289939620939689042">Boja stranice</translation> <translation id="6290238015253830360">Ovdje će se prikazivati predloženi članci</translation> <translation id="6293309776179964942">JIS B5</translation> @@ -1739,6 +1751,7 @@ <translation id="6689249931105087298">Relativno s kompresijom crne točke</translation> <translation id="6689271823431384964">Chrome vam nudi spremanje vaših kartica na vaš Google račun jer ste prijavljeni. To ponašanje možete promijeniti u postavkama. Ime nositelja kartice preuzeto je s vašeg računa.</translation> <translation id="6694681292321232194"><ph name="FIND_MY_PHONE_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da biste pronašli svoj uređaj na Google računu</translation> +<translation id="6696588630955820014">Gumb Dijeli ovu karticu, pritisnite Enter da biste podijelili ovu karticu dijeljenjem veze, izradom QR koda, emitiranjem i na druge načine</translation> <translation id="6698381487523150993">Autor/ica:</translation> <translation id="6702919718839027939">Prezentacija</translation> <translation id="6710213216561001401">Prethodno</translation> @@ -1944,6 +1957,7 @@ <translation id="7392089738299859607">Ažurirajte adresu</translation> <translation id="7399802613464275309">Sigurnosna provjera</translation> <translation id="7400418766976504921">URL</translation> +<translation id="7403392780200267761">Podijelite ovu karticu dijeljenjem veze, izradom QR koda, emitiranjem i na druge načine</translation> <translation id="7403591733719184120">Uređaj <ph name="DEVICE_NAME" /> upravljani je uređaj</translation> <translation id="7407424307057130981"><p>Ta će se pogreška prikazati ako na Windows računalu imate softver Superfish.</p> <p>Privremeno onemogućite softver prema ovim uputama da biste se povezali s webom. Potrebne su vam administratorske povlastice.</p> @@ -2174,6 +2188,7 @@ <translation id="810875025413331850">Nije pronađen nijedan uređaj u blizini.</translation> <translation id="8116925261070264013">Bez zvuka</translation> <translation id="8118489163946903409">Način plaćanja</translation> +<translation id="8124639700796374294">Gumb Prilagodi Chrome, pritisnite Enter da biste prilagodili izgled svojeg preglednika</translation> <translation id="8127301229239896662">Softver "<ph name="SOFTWARE_NAME" />" nije ispravno instaliran na vašem računalu ili mreži. Obratite se IT administratoru za rješavanje tog problema.</translation> <translation id="8131740175452115882">Potvrdi</translation> <translation id="8148608574971654810">Verzija PDF-a:</translation> @@ -2357,6 +2372,7 @@ <translation id="87601671197631245">Ova web-lokacija upotrebljava zastarjelu sigurnosnu konfiguraciju, pa bi vaši podaci (na primjer zaporke, poruke ili brojevi kreditnih kartica) mogli biti otkriveni kad se šalju na nju.</translation> <translation id="8761567432415473239">Googleovo Sigurno pregledavanje nedavno je <ph name="BEGIN_LINK" />pronašlo štetne programe<ph name="END_LINK" /> na web-lokaciji <ph name="SITE" />.</translation> <translation id="8763927697961133303">USB uređaj</translation> +<translation id="8763986294015493060">Zatvorite sve anonimne prozore koji su trenutačno otvoreni</translation> <translation id="8766943070169463815">Otvoren je list s autentifikacijom za vjerodajnicu sigurnog plaćanja</translation> <translation id="877985182522063539">A4</translation> <translation id="8790007591277257123">&Ponovi brisanje</translation> @@ -2370,6 +2386,7 @@ <translation id="8816395686387277279"><ph name="UPDATE_CHROME_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da biste ažurirali Chrome iz postavki Chromea</translation> <translation id="8820817407110198400">Knjižne oznake</translation> <translation id="882338992931677877">Utor za ručno umetanje</translation> +<translation id="8834380158646307944">Gumb Zatvori anonimne prozore, pritisnite Enter da biste zatvorili sve anonimne prozore koji su trenutačno otvoreni</translation> <translation id="883848425547221593">Druge oznake</translation> <translation id="884264119367021077">Adresa za dostavu</translation> <translation id="884923133447025588">Nije pronađen mehanizam za opoziv.</translation> @@ -2423,6 +2440,7 @@ <translation id="9020200922353704812">Potrebna je adresa za naplatu kartice</translation> <translation id="9020542370529661692">Ova je stranica prevedena na <ph name="TARGET_LANGUAGE" /></translation> <translation id="9020742383383852663">A8</translation> +<translation id="9021429684248523859"><ph name="SHARE_THIS_PAGE_FOCUSED_FRIENDLY_MATCH_TEXT" />, pritisnite Tab, a zatim Enter da biste podijelili ovu karticu dijeljenjem veze, izradom QR koda, emitiranjem i na druge načine</translation> <translation id="9025348182339809926">(Nije važeće)</translation> <translation id="9030265603405983977">Jednobojno</translation> <translation id="9035022520814077154">Sigurnosna pogreška</translation>
diff --git a/components/strings/components_strings_iw.xtb b/components/strings/components_strings_iw.xtb index e5e6dcc0..2cef32a 100644 --- a/components/strings/components_strings_iw.xtb +++ b/components/strings/components_strings_iw.xtb
@@ -82,6 +82,7 @@ <translation id="124116460088058876">שפות נוספות</translation> <translation id="1243027604378859286">מחבר:</translation> <translation id="1246424317317450637">מודגש</translation> +<translation id="1248573052514400575"><ph name="MANAGE_CHROMEOS_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />, לוחצים על Tab ואז על Enter כדי להתאים אישית את כלי הנגישות בהגדרות Chrome OS</translation> <translation id="1250759482327835220">כדי לשלם מהר יותר בפעם הבאה, אפשר לשמור בחשבון Google את פרטי הכרטיס, השם והכתובת לחיוב.</translation> <translation id="1252799212227771492">לחצן ליצירה של גיליון, מקישים על Enter כדי ליצור במהירות גיליון אלקטרוני חדש ב-Google Sheets</translation> <translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (מסונכרנים)</translation> @@ -323,6 +324,7 @@ <translation id="192020519938775529">{COUNT,plural, =0{ללא}=1{אתר אחד}two{שני אתרים}many{# אתרים}other{# אתרים}}</translation> <translation id="1923390796829649802">הלחצן לניהול הגדרות הנגישות, מקישים על Enter כדי להתאים אישית את כלי הנגישות בהגדרות Chrome OS</translation> <translation id="1924727005275031552">חדשה</translation> +<translation id="1927439593081478069">לחצן להרצת בדיקת אבטחה ב-Chrome, לוחצים על Enter כדי להריץ בדיקת אבטחה בהגדרות של Chrome</translation> <translation id="1939175642807587452">האתר יכול לבקש הרשאה לשלוח התראות</translation> <translation id="1945968466830820669">ייתכן שלא יתאפשר לך לגשת לחשבון הארגוני, והזהות שלך עלולה להיגנב. לגלישה בטוחה ב-Chromium, מומלץ לשנות את הסיסמה עכשיו.</translation> <translation id="1947454675006758438">סיכת הידוק בפינה הימנית העליונה</translation> @@ -342,6 +344,7 @@ <translation id="2003709556000175978">צריך לאפס את הסיסמה עכשיו</translation> <translation id="2003775180883135320">4 ניקובים בצד שמאל</translation> <translation id="201174227998721785">ניתן לנהל את ההרשאות והנתונים השמורים בכל האתרים בהגדרות Chrome</translation> +<translation id="2019607688127825327">הלחצן לניהול הגדרות הנגישות, מקישים על Enter כדי להתאים אישית את כלי הנגישות בהגדרות Chrome</translation> <translation id="2025115093177348061">מציאות רבודה</translation> <translation id="2025186561304664664">שרת Proxy נקבע למוגדר אוטומטית.</translation> <translation id="2025891858974379949">תוכן לא מאובטח</translation> @@ -507,6 +510,7 @@ <translation id="2556876185419854533">&ביטול עריכה</translation> <translation id="2570734079541893434">ניהול ההגדרות</translation> <translation id="257674075312929031">קבוצה</translation> +<translation id="2576880857912732701">הלחצן 'ניהול הגדרות האבטחה', יש להקיש על Enter כדי לנהל את הגלישה הבטוחה ועוד בהגדרות Chrome</translation> <translation id="2586657967955657006">לוח</translation> <translation id="2587730715158995865">מאת <ph name="ARTICLE_PUBLISHER" />. לקריאת כתבה זו ועוד <ph name="OTHER_ARTICLE_COUNT" /> כתבות נוספות.</translation> <translation id="2587841377698384444">מזהה Directory API:</translation> @@ -551,6 +555,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="2723669454293168317">הרצה של בדיקת אבטחה בהגדרות Chrome</translation> <translation id="2726001110728089263">מגש צידי</translation> <translation id="2728127805433021124">האישור של השרת נחתם באמצעות אלגוריתם של חתימה חלשה.</translation> <translation id="2730326759066348565"><ph name="BEGIN_LINK" />מפעיל את אבחון הקישוריות<ph name="END_LINK" /></translation> @@ -581,6 +586,7 @@ <translation id="2859806420264540918">באתר הזה מוצגות מודעות מפריעות או מטעות.</translation> <translation id="287596039013813457">ידידותי</translation> <translation id="2876489322757410363">בחרת לצאת מהמצב האנונימי כדי לשלם באמצעות אפליקציה חיצונית. להמשיך?</translation> +<translation id="2876949457278336305"><ph name="MANAGE_SECURITY_SETTINGS_FOCUSED_FRIENDLY_MATCH_TEXT" />, לוחצים על Tab ואז על Enter כדי לנהל את הגלישה הבטוחה ועוד בהגדרות Chrome</translation> <translation id="2878197950673342043">קיפול כרזה</translation> <translation id="2878424575911748999">A1</translation> <translation id="2880660355386638022">מיקום חלונות</translation> @@ -686,6 +692,7 @@ <translation id="3229041911291329567">פרטי גרסה של המכשיר והדפדפן</translation> <translation id="323107829343500871">יש להזין את קוד האימות של הכרטיס <ph name="CREDIT_CARD" /></translation> <translation id="3234666976984236645">זהה תמיד תוכן חשוב באתר זה</translation> +<translation id="3240683217920639535"><ph name="MANAGE_CHROME_THEMES_FOCUSED_FRIENDLY_MATCH_TEXT" />, מקישים על Tab ואז על Enter כדי להתאים אישית את מראה הדפדפן</translation> <translation id="3240791268468473923">הגיליון 'אין התאמה בין פרטי הכניסה לפרטי הכניסה לתשלום מאובטח' פתוח</translation> <translation id="3249845759089040423">מגניב</translation> <translation id="3252266817569339921">צרפתית</translation> @@ -730,6 +737,7 @@ • ליצור מפות תלת ממד של האזור שמסביבך ולעקוב אחרי המיקום של המצלמה. • להשתמש במצלמה שלך.</translation> <translation id="337363190475750230">ניהול התצורה בוטל</translation> +<translation id="3375754925484257129">הרצה של בדיקת אבטחה ב-Chrome</translation> <translation id="3377144306166885718">בשרת נעשה שימוש בגרסה מיושנת של TLS.</translation> <translation id="3377188786107721145">שגיאה בניתוח המדיניות</translation> <translation id="3377736046129930310">נעילת המסך מאפשרת לך לאשר כרטיסים מהר יותר</translation> @@ -771,6 +779,7 @@ <translation id="3462200631372590220">הסתרת פרטים מתקדמים</translation> <translation id="3467763166455606212">עליך לציין את שם בעל הכרטיס</translation> <translation id="3468054117417088249"><ph name="TAB_SWITCH_SUFFIX" />, פתוחה כרגע, יש להקיש על Tab ולאחר מכן על Enter כדי לעבור לכרטיסייה הפתוחה</translation> +<translation id="3470563864795286535"><ph name="CLOSE_INCOGNITO_WINDOWS_FOCUSED_FRIENDLY_MATCH_TEXT" />, לוחצים על Tab ואז על Enter כדי לסגור את כל החלונות הפרטיים שפתוחים כרגע</translation> <translation id="3479552764303398839">לא עכשיו</translation> <translation id="3484560055331845446">ייתכן שמישהו אחר ישלול את הגישה שלך לחשבון Google. לגלישה בטוחה ב-Chrome, מומלץ לשנות את הסיסמה עכשיו.</translation> <translation id="3487845404393360112">מגש 4</translation> @@ -809,6 +818,7 @@ <translation id="3611395257124510155">כרטיס וירטואלי עבור <ph name="CARD_IDENTIFIER" /></translation> <translation id="3614103345592970299">גודל 2</translation> <translation id="361438452008624280">רשומה ברשימה "<ph name="LANGUAGE_ID" />": שפה לא מוכרת או לא נתמכת.</translation> +<translation id="3614934205542186002"><ph name="RUN_CHROME_SAFETY_CHECK_FOCUSED_FRIENDLY_MATCH_TEXT" />, לוחצים על Tab ואז על Enter כדי להריץ בדיקת אבטחה בהגדרות Chrome</translation> <translation id="3615877443314183785">עליך להזין תאריך תפוגה חוקי</translation> <translation id="36224234498066874">ניקוי נתוני גלישה…</translation> <translation id="362276910939193118">כל ההיסטוריה</translation> @@ -1609,6 +1619,7 @@ <translation id="6218753634732582820">האם להסיר מ-Chromium את הכתובת?</translation> <translation id="622039917539443112">קיפול מקביל</translation> <translation id="6221345481584921695">לאחרונה, 'גלישה בטוחה של Google' <ph name="BEGIN_LINK" />זיהתה תוכנה זדונית<ph name="END_LINK" /> ב-<ph name="SITE" />. אתרים שבדרך כלל נחשבים לבטוחים נדבקים לעתים בתוכנה זדונית. התוכן הזדוני מגיע מ-<ph name="SUBRESOURCE_HOST" />, מפיץ ידוע של תוכנות זדוניות.</translation> +<translation id="6226163402662242066"><ph name="MANAGE_CHROME_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />, מקישים על Tab ואז על Enter כדי להתאים אישית את כלי הנגישות בהגדרות Chrome</translation> <translation id="6234122620015464377">חיתוך אחרי כל מסמך</translation> <translation id="6240447795304464094">הלוגו של Google Pay</translation> <translation id="6241121617266208201">הסתרת ההצעות</translation> @@ -1627,6 +1638,7 @@ <translation id="6279098320682980337">מספר הכרטיס הווירטואלי לא הוזן? לוחצים על פרטי הכרטיס כדי להעתיק</translation> <translation id="6280223929691119688">לא ניתן לבצע מסירה בכתובת זו. עליך לבחור כתובת אחרת.</translation> <translation id="6282194474023008486">מיקוד</translation> +<translation id="6285507000506177184">הלחצן לניהול הורדות ב-Chrome, מקישים על Enter לניהול הקבצים שהורדת ב-Chrome</translation> <translation id="6289939620939689042">צבע הדף</translation> <translation id="6290238015253830360">הצעות של מאמרים עבורך מופיעות כאן</translation> <translation id="6293309776179964942">JIS B5</translation> @@ -1742,6 +1754,7 @@ <translation id="6689249931105087298">יחסי עם דחיסת נקודות שחורות</translation> <translation id="6689271823431384964">מאחר שנכנסת לחשבון, Chrome מציע לשמור את הכרטיסים שלך בחשבון Google. אפשר לשנות את ההתנהגות הזאת בהגדרות. שם בעל הכרטיס מגיע מהחשבון שלך.</translation> <translation id="6694681292321232194"><ph name="FIND_MY_PHONE_FOCUSED_FRIENDLY_MATCH_TEXT" />, מקישים על Tab ואז על Enter כדי לאתר את המכשיר דרך חשבון Google</translation> +<translation id="6696588630955820014">לחצן לשיתוף הכרטיסייה הזו, מקישים על Enter כדי לשתף את הכרטיסייה הזו על ידי שיתוף הקישור, יצירת קוד QR, העברה (cast) ועוד</translation> <translation id="6698381487523150993">נוצר:</translation> <translation id="6702919718839027939">הצגה</translation> <translation id="6710213216561001401">הקודם</translation> @@ -1947,6 +1960,7 @@ <translation id="7392089738299859607">עדכון הכתובת</translation> <translation id="7399802613464275309">בדיקת אבטחה</translation> <translation id="7400418766976504921">כתובת אתר</translation> +<translation id="7403392780200267761">שיתוף הכרטיסייה הזו על ידי שיתוף הקישור, יצירת קוד QR, העברה (cast) ועוד</translation> <translation id="7403591733719184120">מכשיר <ph name="DEVICE_NAME" /> זה מנוהל</translation> <translation id="7407424307057130981"><p>השגיאה הזו תופיע אם תוכנת Superfish מותקנת במחשב Windows שלך.</p> <p>כדי להשבית את התוכנה באופן זמני ולקבל גישה לאינטרנט, צריך לבצע את השלבים הבאים. צריכות להיות לך הרשאות מנהל.</p> @@ -2177,6 +2191,7 @@ <translation id="810875025413331850">לא נמצאו מכשירים קרובים.</translation> <translation id="8116925261070264013">מושתקים</translation> <translation id="8118489163946903409">אמצעי תשלום</translation> +<translation id="8124639700796374294">לחצן להתאמה אישית של Chrome, מקישים על Enter כדי להתאים אישית את המראה של הדפדפן</translation> <translation id="8127301229239896662">הייתה בעיה בהתקנה של "<ph name="SOFTWARE_NAME" />" במחשב שלך או ברשת. יש לבקש ממנהל ה-IT לפתור את הבעיה.</translation> <translation id="8131740175452115882">אישור</translation> <translation id="8148608574971654810">גרסת PDF:</translation> @@ -2359,6 +2374,7 @@ <translation id="87601671197631245">באתר הזה נעשה שימוש בתצורת הגנה מיושנת, כך שמידע נשלח אליו עשוי להיחשף (למשל סיסמאות, הודעות או כרטיסי אשראי).</translation> <translation id="8761567432415473239">גלישה בטוחה של Google <ph name="BEGIN_LINK" />איתרה לאחרונה תוכניות מזיקות<ph name="END_LINK" /> באתר <ph name="SITE" />.</translation> <translation id="8763927697961133303">התקן USB</translation> +<translation id="8763986294015493060">סגירת כל החלונות הפרטיים שפתוחים כרגע</translation> <translation id="8766943070169463815">גיליון האימות של פרטי הכניסה לתשלום המאובטח פתוח</translation> <translation id="877985182522063539">A4</translation> <translation id="8790007591277257123">&ביצוע מחדש של מחיקה</translation> @@ -2372,6 +2388,7 @@ <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="8834380158646307944">הלחצן לסגירת החלונות האנונימיים, לוחצים על Enter כדי לסגור את כל החלונות האנונימיים שפתוחים כרגע</translation> <translation id="883848425547221593">סימניות אחרות</translation> <translation id="884264119367021077">כתובת למשלוח</translation> <translation id="884923133447025588">לא נמצא מנגנון ביטול</translation> @@ -2425,6 +2442,7 @@ <translation id="9020200922353704812">יש להזין את הכתובת לחיוב של הכרטיס</translation> <translation id="9020542370529661692">הדף הזה תורגם ל<ph name="TARGET_LANGUAGE" /></translation> <translation id="9020742383383852663">A8</translation> +<translation id="9021429684248523859"><ph name="SHARE_THIS_PAGE_FOCUSED_FRIENDLY_MATCH_TEXT" />, לוחצים על Tab ואז על Enter כדי לשתף את הכרטיסייה הזו על ידי שיתוף הקישור, יצירת קוד QR, העברה (cast) ועוד</translation> <translation id="9025348182339809926">(לא חוקי)</translation> <translation id="9030265603405983977">מונוכרומטי</translation> <translation id="9035022520814077154">שגיאת אבטחה</translation>
diff --git a/components/strings/components_strings_ky.xtb b/components/strings/components_strings_ky.xtb index 42d39dab..aa6e041 100644 --- a/components/strings/components_strings_ky.xtb +++ b/components/strings/components_strings_ky.xtb
@@ -157,6 +157,7 @@ <translation id="1422930527989633628">Жакын жердеги Bluetooth түзмөктөрүн табууга уруксат сурай алат</translation> <translation id="1426410128494586442">Ооба</translation> <translation id="1428146450423315676">7-төшөгүч</translation> +<translation id="142858679511221695">Булуттагы колдонуучу</translation> <translation id="1428729058023778569">Бул эскертүүнү көрүп жатсаңыз, бул сайтта HTTPS колдоого алынбайт. <ph name="BEGIN_LEARN_MORE_LINK" />Кеңири маалымат<ph name="END_LEARN_MORE_LINK" /></translation> <translation id="1430915738399379752">Басып чыгаруу</translation> <translation id="1432581352905426595">Издөө каражаттарын башкаруу</translation> @@ -719,6 +720,7 @@ <translation id="3329013043687509092">Каныктыруу</translation> <translation id="3333762389743153920">Виртуалдык карта үчүн жарамдуу эмес</translation> <translation id="3338095232262050444">Корголгон</translation> +<translation id="3339446062576134663">Булут (Боз)</translation> <translation id="3355823806454867987">Прокси жөндөөлөрүн өзгөртүү…</translation> <translation id="3360103848165129075">Төлөм иштетүү барагы</translation> <translation id="3361596688432910856">Chrome'до төмөнкү маалымат<ph name="BEGIN_EMPHASIS" />сактабайт<ph name="END_EMPHASIS" />: @@ -742,6 +744,7 @@ <translation id="3380365263193509176">Белгисиз ката</translation> <translation id="3380864720620200369">Кардар ID:</translation> <translation id="3381668585148405088">Сатып алууну ырастаңыз</translation> +<translation id="3383566085871012386">Учурдагы артыкчылык тартиби</translation> <translation id="3387261909427947069">Төлөм ыкмалары</translation> <translation id="3391030046425686457">Жеткирүү дареги</translation> <translation id="3391482648489541560">файл түзөтүү</translation> @@ -1410,6 +1413,7 @@ <translation id="5478437291406423475">B6/C4 (Конверт)</translation> <translation id="5481076368049295676">Бул мазмун маалыматыңызды уурдай турган же жок кыла турган кооптуу программаны түзмөгүңүзгө орнотууга аракет кылышы мүмкүн. <ph name="BEGIN_LINK" />Баары бир уланта берем<ph name="END_LINK" /></translation> <translation id="54817484435770891">Дарегин туура көрсөтүңүз</translation> +<translation id="5485973315555778056">Булуттагы компьютер</translation> <translation id="5490432419156082418">Даректер жана башкалар</translation> <translation id="5492298309214877701">Ишкана, уюм же университеттин интранетиндеги бул сайттын URL дареги тышкы вебсайттыкына окшош. <ph name="LINE_BREAK" /> @@ -1439,6 +1443,7 @@ <translation id="5571083550517324815">Бул даректен алып кетүү мүмкүн эмес. Башка дарек тандаңыз.</translation> <translation id="5580958916614886209">Мөөнөтү аяктоочу айды текшерип, кайталап көрүңүз</translation> <translation id="5586446728396275693">Сакталган даректер жок</translation> +<translation id="5587987780934666589">Платформаны колдонуучу</translation> <translation id="5593349413089863479">Туташуу кооптуураак</translation> <translation id="5595485650161345191">Даректи өзгөртүү</translation> <translation id="5598944008576757369">Төлөм ыкмасын тандоо</translation> @@ -2127,6 +2132,7 @@ <translation id="7953569069500808819">Жогорку четин жамоо</translation> <translation id="7956713633345437162">Мобилдик кыстармалар</translation> <translation id="7961015016161918242">Эч качан</translation> +<translation id="7962467575542381659">Платформадагы компьютер</translation> <translation id="7966803981046576691">Тапшырманын түрү</translation> <translation id="79682505114836835">"<ph name="VALUE" />" маанисинин он алтылык түсү жараксыз.</translation> <translation id="7968982339740310781">Чоо-жайын карап көрүү</translation>
diff --git a/components/strings/components_strings_lo.xtb b/components/strings/components_strings_lo.xtb index e91390e..80fe78b 100644 --- a/components/strings/components_strings_lo.xtb +++ b/components/strings/components_strings_lo.xtb
@@ -157,6 +157,7 @@ <translation id="1422930527989633628">ສາມາດຂໍຄົ້ນພົບອຸປະກອນ Bluetooth ທີ່ຢູ່ໃກ້ຄຽງ</translation> <translation id="1426410128494586442">ແມ່ນແລ້ວ</translation> <translation id="1428146450423315676">ສະແຕັກເກີ້ 7</translation> +<translation id="142858679511221695">ຜູ້ໃຊ້ຄລາວ</translation> <translation id="1428729058023778569">ທ່ານເຫັນຄຳເຕືອນນີ້ເນື່ອງຈາກເວັບໄຊນີ້ບໍ່ຮອງຮັບ HTTPS. <ph name="BEGIN_LEARN_MORE_LINK" />ສຶກສາເພີ່ມເຕີມ<ph name="END_LEARN_MORE_LINK" /></translation> <translation id="1430915738399379752">ພິມ</translation> <translation id="1432581352905426595">ຈັດການໂປຣແກຣມຊອກຫາ</translation> @@ -719,6 +720,7 @@ <translation id="3329013043687509092">ການອີ່ມຕົວ</translation> <translation id="3333762389743153920">ບໍ່ມີສິດສຳລັບບັດສະເໝືອນ</translation> <translation id="3338095232262050444">ປອດໄພ</translation> +<translation id="3339446062576134663">ຄລາວ (Ash)</translation> <translation id="3355823806454867987">ປ່ຽນການຕັ້ງຄ່າພຣັອກຊີ...</translation> <translation id="3360103848165129075">ແຜ່ນວຽກຂອງເຄື່ອງຈັດການການຊຳລະເງິນ</translation> <translation id="3361596688432910856">Chrome <ph name="BEGIN_EMPHASIS" />ຈະບໍ່ບັນທຶກ<ph name="END_EMPHASIS" /> ຂໍ້ມູນຕໍ່ໄປນີ້: @@ -742,6 +744,7 @@ <translation id="3380365263193509176">ຄວາມຜິດພາດທີ່ບໍ່ຮູ້ຈັກ</translation> <translation id="3380864720620200369">ID ລູກຂ່າຍ:</translation> <translation id="3381668585148405088">ຢັ້ງຢືນການສັ່ງຊື້ຂອງທ່ານ</translation> +<translation id="3383566085871012386">ລຳດັບຄວາມສຳຄັນປັດຈຸບັນ</translation> <translation id="3387261909427947069">ວິທີການຈ່າຍເງິນ</translation> <translation id="3391030046425686457">ທີ່ຢູ່ການຈັດສົ່ງ</translation> <translation id="3391482648489541560">ການແກ້ໄຂໄຟລ໌</translation> @@ -1411,6 +1414,7 @@ <translation id="5478437291406423475">B6/C4 (ຊອງຈົດໝາຍ)</translation> <translation id="5481076368049295676">ເນື້ອຫານີ້ອາດຈະພະຍາຍາມຕິດຕັ້ງຊອບແວອັນຕະລາຍໃສ່ອຸປະກອນຂອງທ່ານທີ່ລັກເອົາ ຫຼື ລຶບຂໍ້ມູນຂອງທ່ານ. <ph name="BEGIN_LINK" />ຢືນຢັນໃຫ້ສະແດງ<ph name="END_LINK" /></translation> <translation id="54817484435770891">ເພີ່ມທີ່ຢູ່ທີ່ຖືກຕ້ອງ</translation> +<translation id="5485973315555778056">ເຄື່ອງຈັກຄລາວ</translation> <translation id="5490432419156082418">ທີ່ຢູ່ ແລະ ອື່ນໆອີກ</translation> <translation id="5492298309214877701">ເວັບໄຊນີ້ຢູ່ໃນອິນທຣາເນັດຂອງບໍລິສັດ, ອົງການ ຫຼື ໂຮງຮຽນ ມີ URL ດຽວກັນກັບເວັບໄຊພາຍນອກ. <ph name="LINE_BREAK" /> @@ -1440,6 +1444,7 @@ <translation id="5571083550517324815">ບໍ່ສາມາດຮັບເອົາເຄື່ອງຈາກທີ່ຢູ່ນີ້ໄດ້. ເລືອກທີ່ຢູ່ອື່ນ.</translation> <translation id="5580958916614886209">ກວດເບິ່ງເດືອນໝົດອາຍຸຂອງທ່ານ ແລະ ລອງອີກຄັ້ງ</translation> <translation id="5586446728396275693">ບໍ່ມີທີ່ຢູ່ທີ່ບັນທຶກໄວ້</translation> +<translation id="5587987780934666589">ຜູ້ໃຊ້ແພລດຟອມ</translation> <translation id="5593349413089863479">ການເຊື່ອມຕໍ່ບໍ່ປອດໄພສົມບູນ</translation> <translation id="5595485650161345191">ແກ້ໄຂທີ່ຢູ່</translation> <translation id="5598944008576757369">ເລືອກວິທີການຈ່າຍເງິນ</translation> @@ -2128,6 +2133,7 @@ <translation id="7953569069500808819">ຫຍິບຂອບເທິງສຸດ</translation> <translation id="7956713633345437162">ບຸກມາກສ໌ມືຖື</translation> <translation id="7961015016161918242">ບໍ່ເລີຍ</translation> +<translation id="7962467575542381659">ເຄື່ອງຈັກແພລດຟອມ</translation> <translation id="7966803981046576691">ປະເພດບັນຊີວຽກ</translation> <translation id="79682505114836835">ຄ່າ "<ph name="VALUE" />" ເປັນສີ hex ທີ່ບໍ່ຖືກຕ້ອງ.</translation> <translation id="7968982339740310781">ເບິ່ງລາຍລະອຽດ</translation>
diff --git a/components/strings/components_strings_lv.xtb b/components/strings/components_strings_lv.xtb index d707bcab..3dc807a 100644 --- a/components/strings/components_strings_lv.xtb +++ b/components/strings/components_strings_lv.xtb
@@ -156,6 +156,7 @@ <translation id="1422930527989633628">Var pieprasīt atļauju noteikt tuvumā esošas Bluetooth ierīces</translation> <translation id="1426410128494586442">Jā</translation> <translation id="1428146450423315676">7. izvades vieta</translation> +<translation id="142858679511221695">Mākoņa lietotājs</translation> <translation id="1428729058023778569">Šis brīdinājums tiek rādīts, jo šajā vietnē netiek atbalstīts HTTPS. <ph name="BEGIN_LEARN_MORE_LINK" />Uzziniet vairāk<ph name="END_LEARN_MORE_LINK" />.</translation> <translation id="1430915738399379752">Drukāt</translation> <translation id="1432581352905426595">Pārvaldīt meklējumprogrammas</translation> @@ -712,6 +713,7 @@ <translation id="3329013043687509092">Piesātinājums</translation> <translation id="3333762389743153920">Neatbilst virtuālajai kartei</translation> <translation id="3338095232262050444">Droši</translation> +<translation id="3339446062576134663">Mākonis (Ash)</translation> <translation id="3355823806454867987">Mainīt starpniekservera iestatījumus...</translation> <translation id="3360103848165129075">Maksājumu apstrādātāja lapa</translation> <translation id="3361596688432910856">Pārlūkā Chrome <ph name="BEGIN_EMPHASIS" />netiks saglabāta<ph name="END_EMPHASIS" /> šāda informācija: @@ -734,6 +736,7 @@ <translation id="3380365263193509176">Nezināma kļūda</translation> <translation id="3380864720620200369">Klienta ID:</translation> <translation id="3381668585148405088">Pirkuma apstiprināšana</translation> +<translation id="3383566085871012386">Pašreizējā prioritārā secība</translation> <translation id="3387261909427947069">Maksājumu veidi</translation> <translation id="3391030046425686457">Piegādes adrese</translation> <translation id="3391482648489541560">failu rediģēšana</translation> @@ -1400,6 +1403,7 @@ <translation id="5478437291406423475">B6/C4 (aploksne)</translation> <translation id="5481076368049295676">Šis saturs jūsu ierīcē var mēģināt instalēt bīstamu programmatūru, kas var nozagt vai izdzēst jūsu informāciju. <ph name="BEGIN_LINK" />Tāpat rādīt<ph name="END_LINK" />.</translation> <translation id="54817484435770891">Derīgas adreses pievienošana</translation> +<translation id="5485973315555778056">Mākoņa ierīce</translation> <translation id="5490432419156082418">Adreses un citus datus</translation> <translation id="5492298309214877701">Šai vietnei uzņēmuma, organizācijas vai skolas iekštīklā ir tāds pats URL kā ārējai vietnei. <ph name="LINE_BREAK" /> @@ -1429,6 +1433,7 @@ <translation id="5571083550517324815">Nevar saņemt sūtījumu šajā adresē. Atlasiet citu adresi.</translation> <translation id="5580958916614886209">Pārbaudiet derīguma termiņa mēnesi un mēģiniet vēlreiz.</translation> <translation id="5586446728396275693">Nav saglabātu adrešu.</translation> +<translation id="5587987780934666589">Platformas lietotājs</translation> <translation id="5593349413089863479">Savienojums nav pilnīgi drošs</translation> <translation id="5595485650161345191">Rediģēt adresi</translation> <translation id="5598944008576757369">Izvēlēties maksājuma veidu</translation> @@ -2113,6 +2118,7 @@ <translation id="7953569069500808819">Malu sašuvums augšdaļā</translation> <translation id="7956713633345437162">Mobilās grāmatzīmes</translation> <translation id="7961015016161918242">Nekad</translation> +<translation id="7962467575542381659">Platformas ierīce</translation> <translation id="7966803981046576691">Darba konta veids</translation> <translation id="79682505114836835">Vērtība “<ph name="VALUE" />” nav derīga krāsa heksadecimālajā sistēmā.</translation> <translation id="7968982339740310781">Skatīt detalizētu informāciju</translation>
diff --git a/components/strings/components_strings_pt-BR.xtb b/components/strings/components_strings_pt-BR.xtb index fc07df0..5e3b2d1a 100644 --- a/components/strings/components_strings_pt-BR.xtb +++ b/components/strings/components_strings_pt-BR.xtb
@@ -157,6 +157,7 @@ <translation id="1422930527989633628">Pode pedir para descobrir dispositivos Bluetooth por perto</translation> <translation id="1426410128494586442">Sim</translation> <translation id="1428146450423315676">Empilhador 7</translation> +<translation id="142858679511221695">Usuário na nuvem</translation> <translation id="1428729058023778569">Este aviso está sendo exibido porque o site não é compatível com HTTPS. <ph name="BEGIN_LEARN_MORE_LINK" />Saiba mais<ph name="END_LEARN_MORE_LINK" /></translation> <translation id="1430915738399379752">Imprimir</translation> <translation id="1432581352905426595">Gerenciar mecanismos de pesquisa</translation> @@ -715,6 +716,7 @@ <translation id="3329013043687509092">Saturação</translation> <translation id="3333762389743153920">Não qualificado como cartão virtual</translation> <translation id="3338095232262050444">Seguro</translation> +<translation id="3339446062576134663">Nuvem (Ash)</translation> <translation id="3355823806454867987">Alterar configurações de proxy...</translation> <translation id="3360103848165129075">Página do gerenciador de pagamento</translation> <translation id="3361596688432910856">O Chrome <ph name="BEGIN_EMPHASIS" />não salvará<ph name="END_EMPHASIS" /> as seguintes informações: @@ -738,6 +740,7 @@ <translation id="3380365263193509176">Erro desconhecido</translation> <translation id="3380864720620200369">ID do cliente:</translation> <translation id="3381668585148405088">Verificar sua compra</translation> +<translation id="3383566085871012386">Ordem de precedência atual</translation> <translation id="3387261909427947069">Formas de pagamento</translation> <translation id="3391030046425686457">Endereço de entrega</translation> <translation id="3391482648489541560">edição de arquivo</translation> @@ -1402,6 +1405,7 @@ <translation id="5478437291406423475">Envelope 125 mm x 324 mm</translation> <translation id="5481076368049295676">Este conteúdo pode tentar instalar softwares perigosos no seu dispositivo que roubam ou excluem suas informações. <ph name="BEGIN_LINK" />Mostrar mesmo assim<ph name="END_LINK" /></translation> <translation id="54817484435770891">Adicionar endereço válido</translation> +<translation id="5485973315555778056">Computador na nuvem</translation> <translation id="5490432419156082418">Endereços e mais</translation> <translation id="5492298309214877701">Esse site na intranet da empresa, organização ou escola tem o mesmo URL de um website externo. <ph name="LINE_BREAK" /> @@ -1431,6 +1435,7 @@ <translation id="5571083550517324815">Não é possível fazer a retirada nesse endereço. Tente um endereço diferente.</translation> <translation id="5580958916614886209">Verifique o mês de validade e tente novamente</translation> <translation id="5586446728396275693">Nenhum endereço salvo</translation> +<translation id="5587987780934666589">Usuário da plataforma</translation> <translation id="5593349413089863479">A conexão não é totalmente segura</translation> <translation id="5595485650161345191">Editar endereço</translation> <translation id="5598944008576757369">Escolher forma de pagamento</translation> @@ -2119,6 +2124,7 @@ <translation id="7953569069500808819">Costura na parte superior</translation> <translation id="7956713633345437162">Favoritos nos dispositivos móveis</translation> <translation id="7961015016161918242">Nunca</translation> +<translation id="7962467575542381659">Computador da plataforma</translation> <translation id="7966803981046576691">Tipo de conta da tarefa</translation> <translation id="79682505114836835">O valor "<ph name="VALUE" />" é uma cor hexadecimal inválida.</translation> <translation id="7968982339740310781">Visualizar detalhes</translation>
diff --git a/components/strings/components_strings_sv.xtb b/components/strings/components_strings_sv.xtb index 8ec735f..f804e83 100644 --- a/components/strings/components_strings_sv.xtb +++ b/components/strings/components_strings_sv.xtb
@@ -82,6 +82,7 @@ <translation id="124116460088058876">Fler språk</translation> <translation id="1243027604378859286">Författare:</translation> <translation id="1246424317317450637">Fet</translation> +<translation id="1248573052514400575"><ph name="MANAGE_CHROMEOS_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />: tryck på Tabb och sedan på Retur om du vill anpassa tillgänglighetsverktygen i inställningarna för Chrome OS</translation> <translation id="1250759482327835220">Spara kortet, faktureringsadressen och ditt namn i Google-kontot så går det snabbare att betala nästa gång.</translation> <translation id="1252799212227771492">Knappen Skapa kalkylark: tryck på Retur om du snabbt vill skapa ett nytt Google-kalkylark</translation> <translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (synkroniserade)</translation> @@ -323,6 +324,7 @@ <translation id="192020519938775529">{COUNT,plural, =0{Ingen}=1{1 webbplats}other{# webbplatser}}</translation> <translation id="1923390796829649802">Knappen Hantera tillgänglighetsinställningar: tryck på Retur om du vill anpassa tillgänglighetsverktygen i inställningarna för Chrome OS</translation> <translation id="1924727005275031552">Ny</translation> +<translation id="1927439593081478069">Knappen Kör säkerhetskontroll i Chrome: tryck på Retur om du vill köra en säkerhetskontroll i inställningarna för Chrome</translation> <translation id="1939175642807587452">Får begära tillstånd att skicka aviseringar</translation> <translation id="1945968466830820669">Du kan förlora åtkomsten till organisationens konto eller bli utsatt för identitetsstöld. Du rekommenderas att ändra lösenordet nu.</translation> <translation id="1947454675006758438">Häfta uppe till höger</translation> @@ -342,6 +344,7 @@ <translation id="2003709556000175978">Återställ lösenordet nu</translation> <translation id="2003775180883135320">Fyra hål högst upp</translation> <translation id="201174227998721785">Hantera behörigheter och data som lagras på olika webbplatser i inställningarna för Chrome</translation> +<translation id="2019607688127825327">Knappen Hantera tillgänglighetsinställningar: tryck på Retur om du vill anpassa tillgänglighetsverktygen i Chrome-inställningarna</translation> <translation id="2025115093177348061">Förstärkt verklighet</translation> <translation id="2025186561304664664">Proxyn är inställd på automatisk konfiguration.</translation> <translation id="2025891858974379949">Osäkert innehåll</translation> @@ -507,6 +510,7 @@ <translation id="2556876185419854533">&Ånga Redigera</translation> <translation id="2570734079541893434">Hantera inställningar</translation> <translation id="257674075312929031">Grupp</translation> +<translation id="2576880857912732701">Knappen Säkerhetsinställningar: tryck på Retur om du vill hantera Säker webbsökning med mera i inställningarna för Chrome</translation> <translation id="2586657967955657006">Urklipp</translation> <translation id="2587730715158995865">Från <ph name="ARTICLE_PUBLISHER" />. Läs denna och <ph name="OTHER_ARTICLE_COUNT" /> andra artiklar.</translation> <translation id="2587841377698384444">Id för katalog-API:</translation> @@ -551,6 +555,7 @@ <translation id="2713444072780614174">Vit</translation> <translation id="2715612312510870559"><ph name="UPDATE_CREDIT_CARD_FOCUSED_FRIENDLY_MATCH_TEXT" />, tryck på Tabb och sedan på Retur om du vill hantera betalningar och kreditkortsuppgifter i inställningarna för Chrome</translation> <translation id="2721148159707890343">Begäran genomfördes</translation> +<translation id="2723669454293168317">Kör en säkerhetskontroll i inställningarna för Chrome</translation> <translation id="2726001110728089263">Sidofack</translation> <translation id="2728127805433021124">Serverns certifikat är signerat med en svag signaturalgoritm.</translation> <translation id="2730326759066348565"><ph name="BEGIN_LINK" />att köra anslutningsdiagnostik<ph name="END_LINK" /></translation> @@ -581,6 +586,7 @@ <translation id="2859806420264540918">Påträngande eller vilseledande annonser visas på den här webbplatsen.</translation> <translation id="287596039013813457">Vänlig</translation> <translation id="2876489322757410363">Om du betalar i ett externt program sker inte det i inkognitoläge. Vill du fortsätta?</translation> +<translation id="2876949457278336305"><ph name="MANAGE_SECURITY_SETTINGS_FOCUSED_FRIENDLY_MATCH_TEXT" />: tryck på Tabb och sedan på Retur om du vill hantera Säker webbsökning med mera i inställningarna för Chrome</translation> <translation id="2878197950673342043">Korsfalsning</translation> <translation id="2878424575911748999">A1</translation> <translation id="2880660355386638022">Fönsterplacering</translation> @@ -686,6 +692,7 @@ <translation id="3229041911291329567">Versionsinformation om enhet och webbläsare</translation> <translation id="323107829343500871">Ange CVC-koden för <ph name="CREDIT_CARD" /></translation> <translation id="3234666976984236645">Upptäck alltid viktigt innehåll på den här webbplatsen</translation> +<translation id="3240683217920639535"><ph name="MANAGE_CHROME_THEMES_FOCUSED_FRIENDLY_MATCH_TEXT" />: tryck på Tabb och sedan på Retur om du vill anpassa webbläsarens utseende</translation> <translation id="3240791268468473923">Arbetsblad för användaruppgifter för säker betalning utan överensstämmande användaruppgifter är öppet</translation> <translation id="3249845759089040423">Tuff</translation> <translation id="3252266817569339921">franska</translation> @@ -730,6 +737,7 @@ • skapa en 3D-karta över dina omgivningar och registrera kamerans position • använda kameran.</translation> <translation id="337363190475750230">Tagen ur bruk</translation> +<translation id="3375754925484257129">Kör säkerhetskontroll i Chrome</translation> <translation id="3377144306166885718">En föråldrad version av TLS används på servern.</translation> <translation id="3377188786107721145">Fel vid analys av policyn</translation> <translation id="3377736046129930310">Verifiera kreditkort snabbare med skärmlås</translation> @@ -771,6 +779,7 @@ <translation id="3462200631372590220">Dölja avancerade uppgifter</translation> <translation id="3467763166455606212">Kortinnehavarens namn måste anges</translation> <translation id="3468054117417088249"><ph name="TAB_SWITCH_SUFFIX" />, öppen nu, tryck på Tabb och sedan Retur för att byta till den öppna fliken</translation> +<translation id="3470563864795286535"><ph name="CLOSE_INCOGNITO_WINDOWS_FOCUSED_FRIENDLY_MATCH_TEXT" />: tryck på Tabb och sedan på Retur om du vill stänga alla inkognitofönster som är öppna för närvarande</translation> <translation id="3479552764303398839">Inte nu</translation> <translation id="3484560055331845446">Du kan förlora tillgången till Google-kontot. Du rekommenderas att ändra lösenordet nu. Du blir uppmanad att logga in.</translation> <translation id="3487845404393360112">Fack 4</translation> @@ -809,6 +818,7 @@ <translation id="3611395257124510155">Virtuellt kort för <ph name="CARD_IDENTIFIER" /></translation> <translation id="3614103345592970299">Storlek 2</translation> <translation id="361438452008624280">Listposten <ph name="LANGUAGE_ID" />: Språket är okänt eller stöds inte.</translation> +<translation id="3614934205542186002"><ph name="RUN_CHROME_SAFETY_CHECK_FOCUSED_FRIENDLY_MATCH_TEXT" />: tryck på Tabb och sedan på Retur om du vill köra en säkerhetskontroll i inställningarna för Chrome</translation> <translation id="3615877443314183785">Ange ett giltigt utgångsdatum</translation> <translation id="36224234498066874">Rensa webbinformation ...</translation> <translation id="362276910939193118">Visa fullständig historik</translation> @@ -1606,6 +1616,7 @@ <translation id="6218753634732582820">Vill du ta bort adressen från Chromium?</translation> <translation id="622039917539443112">Parallellfalsning</translation> <translation id="6221345481584921695">Google Säker webbsökning upptäckte nyligen <ph name="BEGIN_LINK" />skadlig programvara<ph name="END_LINK" /> på <ph name="SITE" />. Webbplatser som vanligtvis är säkra utsätts ibland för skadlig programvara. Det skadliga innehållet kommer från <ph name="SUBRESOURCE_HOST" />, som är en känd distributör av skadlig programvara.</translation> +<translation id="6226163402662242066"><ph name="MANAGE_CHROME_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />: tryck på Tabb och sedan på Retur om du vill anpassa tillgänglighetsverktygen i Chrome-inställningarna</translation> <translation id="6234122620015464377">Beskär efter varje dokument</translation> <translation id="6240447795304464094">Google Pay-logotyp</translation> <translation id="6241121617266208201">Dölj förslag</translation> @@ -1624,6 +1635,7 @@ <translation id="6279098320682980337">Har det virtuella kortnumret inte fyllts i? Klicka på kortuppgifterna om du vill kopiera dem</translation> <translation id="6280223929691119688">Det går inte att leverera till den här adressen. Välj en annan adress.</translation> <translation id="6282194474023008486">Postnummer</translation> +<translation id="6285507000506177184">Knappen Hantera nedladdningar i Chrome: tryck på Retur om du vill hantera filer du har laddat ned i Chrome</translation> <translation id="6289939620939689042">Sidfärg</translation> <translation id="6290238015253830360">Rekommenderade artiklar visas här</translation> <translation id="6293309776179964942">JIS B5</translation> @@ -1739,6 +1751,7 @@ <translation id="6689249931105087298">Relativ med svartpunktskomprimering</translation> <translation id="6689271823431384964">Chrome ger möjlighet att spara dina kort i ditt Google-konto eftersom du är inloggad. Du kan ändra detta i inställningarna. Kortinnehavarens namn hämtas från ditt konto.</translation> <translation id="6694681292321232194"><ph name="FIND_MY_PHONE_FOCUSED_FRIENDLY_MATCH_TEXT" />: tryck på Tabb och sedan på Retur om du vill hitta enheten i Google-kontot</translation> +<translation id="6696588630955820014">Knappen Dela den här fliken: tryck på Retur om du vill dela den här fliken genom att dela länken, skapa en QR-kod, casta med flera alternativ</translation> <translation id="6698381487523150993">Skapad av:</translation> <translation id="6702919718839027939">Presentera</translation> <translation id="6710213216561001401">Föregående</translation> @@ -1944,6 +1957,7 @@ <translation id="7392089738299859607">Uppdatera adressen</translation> <translation id="7399802613464275309">Säkerhetskontroll</translation> <translation id="7400418766976504921">Webbadress</translation> +<translation id="7403392780200267761">Dela den här fliken genom att dela länken, skapa en QR-kod, casta med flera alternativ</translation> <translation id="7403591733719184120">Din <ph name="DEVICE_NAME" /> hanteras</translation> <translation id="7407424307057130981"><p>Det här felmeddelandet visas om du har programvaran Superfish på Windows-datorn.</p> <p>Inaktivera programvaran tillfälligt enligt anvisningarna nedan så att du kan komma ut på internet. Du måste ha administratörsbehörighet.</p> @@ -2174,6 +2188,7 @@ <translation id="810875025413331850">Inga enheter i närheten hittades.</translation> <translation id="8116925261070264013">Ljudet avstängt</translation> <translation id="8118489163946903409">Betalningsmetod</translation> +<translation id="8124639700796374294">Knappen Anpassa Chrome: tryck på Retur om du vill anpassa webbläsarens utseende</translation> <translation id="8127301229239896662"><ph name="SOFTWARE_NAME" /> har inte installerats korrekt på datorn eller nätverket. Be IT-administratören om hjälp med problemet.</translation> <translation id="8131740175452115882">Bekräfta</translation> <translation id="8148608574971654810">PDF-version:</translation> @@ -2357,6 +2372,7 @@ <translation id="87601671197631245">Den här webbplatsens säkerhetskonfiguration är inaktuell. Det kan leda till att dina uppgifter (t.ex. lösenord, meddelanden eller kreditkort) exponeras när de skickas till den här webbplatsen.</translation> <translation id="8761567432415473239">Googles tjänst Säker webbsökning <ph name="BEGIN_LINK" />hittade skadliga program<ph name="END_LINK" /> på <ph name="SITE" /> nyligen.</translation> <translation id="8763927697961133303">USB-enhet</translation> +<translation id="8763986294015493060">Stäng alla inkognitofönster som är öppna för närvarande</translation> <translation id="8766943070169463815">Ett arbetsblad för autentisering av användaruppgifter för säker betalning har öppnats</translation> <translation id="877985182522063539">A4</translation> <translation id="8790007591277257123">&Gör om Ta bort</translation> @@ -2370,6 +2386,7 @@ <translation id="8816395686387277279"><ph name="UPDATE_CHROME_FOCUSED_FRIENDLY_MATCH_TEXT" />, tryck på Tabb och sedan på Retur om du vill uppdatera Chrome i inställningarna för Chrome</translation> <translation id="8820817407110198400">Bokmärken</translation> <translation id="882338992931677877">Manuell plats</translation> +<translation id="8834380158646307944">Knappen Stäng inkognitofönster: tryck på Retur om du vill stänga alla inkognitofönster som är öppna för närvarande</translation> <translation id="883848425547221593">Övriga bokmärken</translation> <translation id="884264119367021077">Leveransadress</translation> <translation id="884923133447025588">Ingen återkallningsmekanism har hittats.</translation> @@ -2423,6 +2440,7 @@ <translation id="9020200922353704812">Kortets faktureringsadress måste anges</translation> <translation id="9020542370529661692">Den här sidan har översatts till <ph name="TARGET_LANGUAGE" /></translation> <translation id="9020742383383852663">A8</translation> +<translation id="9021429684248523859"><ph name="SHARE_THIS_PAGE_FOCUSED_FRIENDLY_MATCH_TEXT" />: tryck på Tabb och sedan på Retur om du vill dela den här fliken genom att dela länken, skapa en QR-kod, casta med flera alternativ</translation> <translation id="9025348182339809926">(Ogiltigt)</translation> <translation id="9030265603405983977">Monokrom</translation> <translation id="9035022520814077154">Säkerhetsfel</translation>
diff --git a/components/strings/components_strings_tr.xtb b/components/strings/components_strings_tr.xtb index 72ddf2e..99a94c1 100644 --- a/components/strings/components_strings_tr.xtb +++ b/components/strings/components_strings_tr.xtb
@@ -82,6 +82,7 @@ <translation id="124116460088058876">Diğer diller</translation> <translation id="1243027604378859286">Yazar:</translation> <translation id="1246424317317450637">Kalın</translation> +<translation id="1248573052514400575"><ph name="MANAGE_CHROMEOS_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chrome OS ayarlarında erişilebilirlik araçlarınızı kişiselleştirmek için Sekme'ye, ardından Enter'a basın</translation> <translation id="1250759482327835220">Bir dahaki sefere daha hızlı ödeme yapmak için kartınızı ve fatura adresinizi Google Hesabınıza kaydedin.</translation> <translation id="1252799212227771492">E-Tablo oluştur düğmesi, hızlıca yeni bir Google E-Tablosu oluşturmak için Enter'a basın</translation> <translation id="1253921432148366685"><ph name="TYPE_1" />, <ph name="TYPE_2" /> (senkronize edildi)</translation> @@ -320,6 +321,7 @@ <translation id="192020519938775529">{COUNT,plural, =0{Yok}=1{1 site}other{# site}}</translation> <translation id="1923390796829649802">Erişilebilirlik ayarlarını yönetin düğmesi, Chrome OS ayarlarında erişilebilirlik araçlarınızı kişiselleştirmek için Enter'a basın</translation> <translation id="1924727005275031552">Yeni</translation> +<translation id="1927439593081478069">Chrome güvenlik kontrolü yürüt düğmesi. Chrome ayarlarında güvenlik kontrolü yürütmek için Enter'a basın</translation> <translation id="1939175642807587452">Bildirim göndermek isteyebilir</translation> <translation id="1945968466830820669">Kuruluşunuzun hesabına erişimi kaybedebilir veya kimlik hırsızlığına maruz kalabilirsiniz. Chromium, şifrenizi hemen değiştirmenizi önerir.</translation> <translation id="1947454675006758438">Sağ üstte tel zımba</translation> @@ -339,6 +341,7 @@ <translation id="2003709556000175978">Şifrenizi şimdi sıfırlayın</translation> <translation id="2003775180883135320">Üstte dörtlü delik</translation> <translation id="201174227998721785">Chrome ayarlarında izinleri ve sitelerde depolanan verileri yönetin</translation> +<translation id="2019607688127825327">Erişilebilirlik ayarlarını yönetin düğmesi. Chrome ayarlarında erişilebilirlik araçlarınızı kişiselleştirmek için Enter'a basın</translation> <translation id="2025115093177348061">Artırılmış gerçeklik</translation> <translation id="2025186561304664664">Proxy, otomatik yapılandırıldı değerine ayarlandı.</translation> <translation id="2025891858974379949">Güvenli olmayan içerik</translation> @@ -504,6 +507,7 @@ <translation id="2556876185419854533">Düzenlemeyi &Geri Al</translation> <translation id="2570734079541893434">Ayarları yönet</translation> <translation id="257674075312929031">Grup</translation> +<translation id="2576880857912732701">Güvenlik ayarlarını yönet düğmesi. Chrome ayarlarında Güvenli Tarama ve diğer özellikleri yönetmek için Enter'a basın</translation> <translation id="2586657967955657006">Pano</translation> <translation id="2587730715158995865"><ph name="ARTICLE_PUBLISHER" /> adlı yayıncıdan. Bunu ve diğer <ph name="OTHER_ARTICLE_COUNT" /> haberi okuyun.</translation> <translation id="2587841377698384444">Dizin API'sı Kimliği:</translation> @@ -548,6 +552,7 @@ <translation id="2713444072780614174">Beyaz</translation> <translation id="2715612312510870559"><ph name="UPDATE_CREDIT_CARD_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chrome ayarlarında ödemelerinizi ve kredi kartı bilgilerinizi yönetmek için Sekme'ye, sonra Enter'a basın</translation> <translation id="2721148159707890343">İstek başarılı oldu</translation> +<translation id="2723669454293168317">Chrome ayarlarında güvenlik kontrolü yürütün</translation> <translation id="2726001110728089263">Yan Tepsi</translation> <translation id="2728127805433021124">Sunucunun sertifikası, zayıf bir imza algoritması kullanılarak imzalanmış.</translation> <translation id="2730326759066348565"><ph name="BEGIN_LINK" />Bağlantı Teşhislerini Çalıştırma<ph name="END_LINK" /></translation> @@ -578,6 +583,7 @@ <translation id="2859806420264540918">Bu site, araya giren veya yanıltıcı reklamlar gösteriyor.</translation> <translation id="287596039013813457">Dost Canlısı</translation> <translation id="2876489322757410363">Harici bir uygulama üzerinden ödeme gerçekleştirmek için Gizli moddan çıkılıyor. Devam etmek istiyor musunuz?</translation> +<translation id="2876949457278336305"><ph name="MANAGE_SECURITY_SETTINGS_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chrome ayarlarında Güvenli Tarama ve diğer özellikleri yönetmek için Sekme'ye, ardından Enter'a basın</translation> <translation id="2878197950673342043">Poster katlama</translation> <translation id="2878424575911748999">A1</translation> <translation id="2880660355386638022">Pencere yerleşimi</translation> @@ -683,6 +689,7 @@ <translation id="3229041911291329567">Cihazınız ve tarayıcınızla ilgili sürüm bilgileri</translation> <translation id="323107829343500871"><ph name="CREDIT_CARD" /> numaralı kartın CVC kodunu girin</translation> <translation id="3234666976984236645">Her zaman bu sitedeki önemli içeriği algıla</translation> +<translation id="3240683217920639535"><ph name="MANAGE_CHROME_THEMES_FOCUSED_FRIENDLY_MATCH_TEXT" />, Tarayıcınızın görünümünü özelleştirmek için sekmeye, ardından Enter'a basın</translation> <translation id="3240791268468473923">Eşleşmeyen güvenli ödeme kimlik bilgisi sayfası açıldı</translation> <translation id="3249845759089040423">Modern</translation> <translation id="3252266817569339921">Fransızca</translation> @@ -727,6 +734,7 @@ • Çevrenizin 3D haritasını oluşturma ve kamera konumunu takip etme • Kameranızı kullanma</translation> <translation id="337363190475750230">Temel hazırlık iptal edildi</translation> +<translation id="3375754925484257129">Chrome güvenlik kontrolü yürüt</translation> <translation id="3377144306166885718">Sunucu TLS'nin eski bir sürümünü kullandı.</translation> <translation id="3377188786107721145">Politika ayrıştırma hatası</translation> <translation id="3377736046129930310">Kartları daha hızlı onaylamak için ekran kilidini kullanın</translation> @@ -768,6 +776,7 @@ <translation id="3462200631372590220">Gelişmiş bilgileri gizle</translation> <translation id="3467763166455606212">Kart sahibinin adı zorunludur</translation> <translation id="3468054117417088249"><ph name="TAB_SWITCH_SUFFIX" />, şu anda açık, açık Sekmeye geçmek için Sekmeye ve sonra enter tuşuna basın</translation> +<translation id="3470563864795286535"><ph name="CLOSE_INCOGNITO_WINDOWS_FOCUSED_FRIENDLY_MATCH_TEXT" />, açık olan tüm gizli pencereleri kapatmak için sekmeye, ardından Enter'a basın</translation> <translation id="3479552764303398839">Şimdi değil</translation> <translation id="3484560055331845446">Google Hesabınıza erişimi kaybedebilirsiniz. Chrome, şifrenizi hemen değiştirmenizi önerir. Oturum açmanız istenecektir.</translation> <translation id="3487845404393360112">Tepsi 4</translation> @@ -806,6 +815,7 @@ <translation id="3611395257124510155"><ph name="CARD_IDENTIFIER" /> için sanal kart</translation> <translation id="3614103345592970299">Boyut 2</translation> <translation id="361438452008624280">Liste girişi "<ph name="LANGUAGE_ID" />": Bilinmeyen veya desteklenmeyen dil.</translation> +<translation id="3614934205542186002"><ph name="RUN_CHROME_SAFETY_CHECK_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chrome ayarlarında güvenlik kontrolü yürütmek için Sekme'ye, sonra Enter'a basın</translation> <translation id="3615877443314183785">Geçerli bir son kullanma tarihi girin</translation> <translation id="36224234498066874">Tarama Verilerini Temizle...</translation> <translation id="362276910939193118">Tam Geçmişi Göster</translation> @@ -1599,6 +1609,7 @@ <translation id="6218753634732582820">Adres Chromium'dan kaldırılsın mı?</translation> <translation id="622039917539443112">Paralel katlama</translation> <translation id="6221345481584921695">Google Güvenli Tarama yakın bir zamanda <ph name="SITE" /> sitesinde <ph name="BEGIN_LINK" />kötü amaçlı yazılım tespit etti<ph name="END_LINK" />. Normalde güvenli olan web sitelerine bazen kötü amaçlı yazılımlar bulaşır. Kötü amaçlı içerik, kötü amaçlı yazılım dağıtımcısı olduğu bilinen <ph name="SUBRESOURCE_HOST" /> kaynağından gelmektedir.</translation> +<translation id="6226163402662242066"><ph name="MANAGE_CHROME_ACCESSIBILITY_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chrome ayarlarında erişilebilirlik araçlarınızı kişiselleştirmek için Sekme'ye, ardından Enter'a basın</translation> <translation id="6234122620015464377">Her dokümandan sonra kırp</translation> <translation id="6240447795304464094">Google Pay logosu</translation> <translation id="6241121617266208201">Önerileri gizle</translation> @@ -1617,6 +1628,7 @@ <translation id="6279098320682980337">Sanal kart numarası doldurulmadı mı? Kopyalamak için kart detaylarını tıklayın</translation> <translation id="6280223929691119688">Bu adrese teslimat yapılamıyor. Farklı bir adres seçin.</translation> <translation id="6282194474023008486">Posta kodu</translation> +<translation id="6285507000506177184">Chrome'da indirilenleri yönetin düğmesi. Chrome'da indirdiğiniz dosyaları yönetmek için Enter'a basın</translation> <translation id="6289939620939689042">Sayfa Rengi</translation> <translation id="6290238015253830360">Önerilen makaleler burada görünür</translation> <translation id="6293309776179964942">JIS B5</translation> @@ -1732,6 +1744,7 @@ <translation id="6689249931105087298">Siyah nokta sıkıştırma ile göreli</translation> <translation id="6689271823431384964">Chrome, oturumunuz açık olduğu için kartlarınızı Google Hesabınıza kaydetmeyi öneriyor. Bu davranışı ayarlardan değiştirebilirsiniz. Kart sahibinin adı hesabınızdan gelir.</translation> <translation id="6694681292321232194"><ph name="FIND_MY_PHONE_FOCUSED_FRIENDLY_MATCH_TEXT" />, Google Hesabı'nda cihazınızı bulmak için Sekme'ye, ardından Enter'a basın</translation> +<translation id="6696588630955820014">Bu sekmeyi paylaş düğmesi. Bağlantıyı paylaşarak, QR kodu oluşturarak, yayınlayarak ve başka seçenekleri kullanarak bu sekmeyi paylaşmak için Enter'a basın</translation> <translation id="6698381487523150993">Oluşturma tarihi:</translation> <translation id="6702919718839027939">Sunum</translation> <translation id="6710213216561001401">Önceki</translation> @@ -1937,6 +1950,7 @@ <translation id="7392089738299859607">Adresi Güncelle</translation> <translation id="7399802613464275309">Güvenlik Kontrolü</translation> <translation id="7400418766976504921">URL</translation> +<translation id="7403392780200267761">Bağlantıyı paylaşarak, QR kodu oluşturarak, yayınlayarak ve başka seçenekleri kullanarak bu sekmeyi paylaşın</translation> <translation id="7403591733719184120"><ph name="DEVICE_NAME" /> adlı cihazınız yönetilmektedir</translation> <translation id="7407424307057130981"><p>Windows bilgisayarınızda Superfish yazılımı varsa bu hatayı görürsünüz.</p> <p>Web'e ulaşabilmeniz amacıyla yazılımı geçici olarak devre dışı bırakmak için bu adımları uygulayın. Bu adımları gerçekleştirmek için yönetici ayrıcalıklarınızın olması gerekir.</p> @@ -2167,6 +2181,7 @@ <translation id="810875025413331850">Yakında olan cihaz bulunamadı.</translation> <translation id="8116925261070264013">Ses kapatıldı</translation> <translation id="8118489163946903409">Ödeme yöntemi</translation> +<translation id="8124639700796374294">Chrome'u özelleştir düğmesi. Tarayıcınızın görünümünü özelleştirmek için Enter'a basın</translation> <translation id="8127301229239896662">"<ph name="SOFTWARE_NAME" />" yazılımı bilgisayarınıza veya ağa düzgün şekilde yüklenmemiş. BT yöneticinizden sorunu çözmesini isteyin.</translation> <translation id="8131740175452115882">Onayla</translation> <translation id="8148608574971654810">PDF sürümü:</translation> @@ -2350,6 +2365,7 @@ <translation id="87601671197631245">Bu site, eski bir güvenlik yapılandırması kullanıyor. Bu siteye gönderildiğinde bilgileriniz (ör. şifreler, mesajlar veya kredi kartları) gösterilebilir.</translation> <translation id="8761567432415473239">Google Güvenli Tarama, yakın zamanda <ph name="SITE" /> sitesinde <ph name="BEGIN_LINK" />zararlı programlar buldu<ph name="END_LINK" />.</translation> <translation id="8763927697961133303">USB cihaz</translation> +<translation id="8763986294015493060">Açık olan tüm gizli pencereleri kapat</translation> <translation id="8766943070169463815">Güvenli ödeme kimlik bilgisi doğrulama sayfası açıldı</translation> <translation id="877985182522063539">A4</translation> <translation id="8790007591277257123">Silmeyi &yeniden yap</translation> @@ -2363,6 +2379,7 @@ <translation id="8816395686387277279"><ph name="UPDATE_CHROME_FOCUSED_FRIENDLY_MATCH_TEXT" />, Chrome ayarlarınızdan Chrome'u güncellemek için Sekme'ye, sonra Enter'a basın</translation> <translation id="8820817407110198400">Yer işaretleri</translation> <translation id="882338992931677877">Manuel Yuva</translation> +<translation id="8834380158646307944">Gizli pencereleri kapat düğmesi. Açık olan tüm gizli pencereleri kapatmak için Enter'a basın</translation> <translation id="883848425547221593">Diğer Yer İşaretleri</translation> <translation id="884264119367021077">Gönderim adresi</translation> <translation id="884923133447025588">İptal mekanizması bulunamadı.</translation> @@ -2416,6 +2433,7 @@ <translation id="9020200922353704812">Kartın fatura adresi gerekli</translation> <translation id="9020542370529661692">Bu sayfa <ph name="TARGET_LANGUAGE" /> diline çevrildi</translation> <translation id="9020742383383852663">A8</translation> +<translation id="9021429684248523859"><ph name="SHARE_THIS_PAGE_FOCUSED_FRIENDLY_MATCH_TEXT" />, bağlantıyı paylaşarak, QR kodu oluşturarak, yayınlayarak ve başka seçenekleri kullanarak bu sekmeyi paylaşmak için sekmeye, ardından Enter'a basın</translation> <translation id="9025348182339809926">(Geçersiz)</translation> <translation id="9030265603405983977">Tek renk</translation> <translation id="9035022520814077154">Güvenlik hatası</translation>
diff --git a/components/translate/content/android/java/res/layout/translate_menu_extended_item.xml b/components/translate/content/android/java/res/layout/translate_menu_extended_item.xml index 836c978..8dfb668 100644 --- a/components/translate/content/android/java/res/layout/translate_menu_extended_item.xml +++ b/components/translate/content/android/java/res/layout/translate_menu_extended_item.xml
@@ -35,7 +35,7 @@ android:id="@+id/menu_item_list_divider" android:layout_width="match_parent" android:layout_height="1dp" - android:background="@color/divider_line_bg_color" + android:background="@macro/divider_line_bg_color" android:visibility="gone" />
diff --git a/components/translate/content/android/java/res/layout/translate_menu_item_checked.xml b/components/translate/content/android/java/res/layout/translate_menu_item_checked.xml index c8512b3..36ea600 100644 --- a/components/translate/content/android/java/res/layout/translate_menu_item_checked.xml +++ b/components/translate/content/android/java/res/layout/translate_menu_item_checked.xml
@@ -43,7 +43,7 @@ android:id="@+id/menu_item_divider" android:layout_width="match_parent" android:layout_height="1dp" - android:background="@color/divider_line_bg_color" + android:background="@macro/divider_line_bg_color" android:visibility="gone" /> </LinearLayout>
diff --git a/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc b/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc index 55271ab..d1c6857 100644 --- a/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc +++ b/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc
@@ -9,6 +9,7 @@ #include "base/cxx17_backports.h" #include "base/strings/string_piece.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "components/url_formatter/spoof_checks/idn_spoof_checker.h" @@ -19,9 +20,6 @@ namespace { -using base::ASCIIToUTF16; -using base::WideToUTF16; - // Expected result of the IDN conversion. enum class Result { // Hostname can safely be decoded to unicode. @@ -43,145 +41,131 @@ // The equivalent Unicode version of the domain. Even if we expect the domain // to be displayed in Punycode, this should still contain the Unicode // equivalent (see |unicode_allowed|). - const wchar_t* unicode_output; + const char16_t* unicode_output; // Whether we expect the domain to be displayed decoded as a Unicode string or // in its Punycode form. const Result expected_result; }; -// These cases can be generated with the script +// These cases MUST be generated with the script // tools/security/idn_test_case_generator.py. // See documentation there: you can either run it from the command line or call // the make_case function directly from the Python shell (which may be easier // for entering Unicode text). // +// Do NOT generate these cases by hand. +// // Q: Why not just do this conversion right here in the test, rather than having // a Python script to generate it? // A: Because then we would have to rely on complex logic (IDNA encoding) in the // test itself; the same code we are trying to test. By using Python's IDN // encoder to generate the test data, we independently verify that our // algorithm is correct. - -// TODO(jshin): Replace L"..." with "..." in UTF-8 when it's easier to read. const IDNTestCase kIdnCases[] = { // No IDN - {"www.google.com", L"www.google.com", kSafe}, - {"www.google.com.", L"www.google.com.", kSafe}, - {".", L".", kSafe}, - {"", L"", kSafe}, + {"www.google.com", u"www.google.com", kSafe}, + {"www.google.com.", u"www.google.com.", kSafe}, + {".", u".", kSafe}, + {"", u"", kSafe}, // Invalid IDN - {"xn--example-.com", L"xn--example-.com", kInvalid}, + {"xn--example-.com", u"xn--example-.com", kInvalid}, // IDN // Hanzi (Traditional Chinese) - {"xn--1lq90ic7f1rc.cn", L"\x5317\x4eac\x5927\x5b78.cn", kSafe}, - // Hanzi ('video' in Simplified Chinese - {"xn--cy2a840a.com", L"\x89c6\x9891.com", kSafe}, + {"xn--1lq90ic7f1rc.cn", u"\u5317\u4eac\u5927\u5b78.cn", kSafe}, + // Hanzi ('video' in Simplified Chinese) + {"xn--cy2a840a.com", u"\u89c6\u9891.com", kSafe}, // Hanzi + '123' - {"www.xn--123-p18d.com", - L"www.\x4e00" - L"123.com", - kSafe}, + {"www.xn--123-p18d.com", u"www.\u4e00123.com", kSafe}, // Hanzi + Latin : U+56FD is simplified - {"www.xn--hello-9n1hm04c.com", L"www.hello\x4e2d\x56fd.com", kSafe}, + {"www.xn--hello-9n1hm04c.com", u"www.hello\u4e2d\u56fd.com", kSafe}, // Kanji + Kana (Japanese) - {"xn--l8jvb1ey91xtjb.jp", L"\x671d\x65e5\x3042\x3055\x3072.jp", kSafe}, + {"xn--l8jvb1ey91xtjb.jp", u"\u671d\u65e5\u3042\u3055\u3072.jp", kSafe}, // Katakana including U+30FC - {"xn--tckm4i2e.jp", L"\x30b3\x30de\x30fc\x30b9.jp", kSafe}, - {"xn--3ck7a7g.jp", L"\u30ce\u30f3\u30bd.jp", kSafe}, + {"xn--tckm4i2e.jp", u"\u30b3\u30de\u30fc\u30b9.jp", kSafe}, + {"xn--3ck7a7g.jp", u"\u30ce\u30f3\u30bd.jp", kSafe}, // Katakana + Latin (Japanese) - {"xn--e-efusa1mzf.jp", L"e\x30b3\x30de\x30fc\x30b9.jp", kSafe}, - {"xn--3bkxe.jp", L"\x30c8\x309a.jp", kSafe}, + {"xn--e-efusa1mzf.jp", u"e\u30b3\u30de\u30fc\u30b9.jp", kSafe}, + {"xn--3bkxe.jp", u"\u30c8\u309a.jp", kSafe}, // Hangul (Korean) - {"www.xn--or3b17p6jjc.kr", L"www.\xc804\xc790\xc815\xbd80.kr", kSafe}, + {"www.xn--or3b17p6jjc.kr", u"www.\uc804\uc790\uc815\ubd80.kr", kSafe}, // b<u-umlaut>cher (German) - {"xn--bcher-kva.de", - L"b\x00fc" - L"cher.de", - kSafe}, + {"xn--bcher-kva.de", u"b\u00fccher.de", kSafe}, // a with diaeresis - {"www.xn--frgbolaget-q5a.se", L"www.f\x00e4rgbolaget.se", kSafe}, + {"www.xn--frgbolaget-q5a.se", u"www.f\u00e4rgbolaget.se", kSafe}, // c-cedilla (French) - {"www.xn--alliancefranaise-npb.fr", - L"www.alliancefran\x00e7" - L"aise.fr", + {"www.xn--alliancefranaise-npb.fr", u"www.alliancefran\u00e7aise.fr", kSafe}, - // caf'e with acute accent' (French) - {"xn--caf-dma.fr", L"caf\x00e9.fr", kSafe}, + // caf'e with acute accent (French) + {"xn--caf-dma.fr", u"caf\u00e9.fr", kSafe}, // c-cedillla and a with tilde (Portuguese) - {"xn--poema-9qae5a.com.br", L"p\x00e3oema\x00e7\x00e3.com.br", kSafe}, + {"xn--poema-9qae5a.com.br", u"p\u00e3oema\u00e7\u00e3.com.br", kSafe}, // s with caron - {"xn--achy-f6a.com", - L"\x0161" - L"achy.com", - kSafe}, - {"xn--kxae4bafwg.gr", L"\x03bf\x03c5\x03c4\x03bf\x03c0\x03af\x03b1.gr", + {"xn--achy-f6a.com", u"\u0161achy.com", kSafe}, + {"xn--kxae4bafwg.gr", u"\u03bf\u03c5\u03c4\u03bf\u03c0\u03af\u03b1.gr", kSafe}, // Eutopia + 123 (Greek) {"xn---123-pldm0haj2bk.gr", - L"\x03bf\x03c5\x03c4\x03bf\x03c0\x03af\x03b1-123.gr", kSafe}, + u"\u03bf\u03c5\u03c4\u03bf\u03c0\u03af\u03b1-123.gr", kSafe}, // Cyrillic (Russian) - {"xn--n1aeec9b.ru", L"\x0442\x043e\x0440\x0442\x044b.ru", kSafe}, + {"xn--n1aeec9b.ru", u"\u0442\u043e\u0440\u0442\u044b.ru", kSafe}, // Cyrillic + 123 (Russian) - {"xn---123-45dmmc5f.ru", L"\x0442\x043e\x0440\x0442\x044b-123.ru", kSafe}, + {"xn---123-45dmmc5f.ru", u"\u0442\u043e\u0440\u0442\u044b-123.ru", kSafe}, // 'president' in Russian. Is a wholescript confusable, but allowed. {"xn--d1abbgf6aiiy.xn--p1ai", - L"\x043f\x0440\x0435\x0437\x0438\x0434\x0435\x043d\x0442.\x0440\x0444", + u"\u043f\u0440\u0435\u0437\u0438\u0434\u0435\u043d\u0442.\u0440\u0444", kSafe}, // Arabic - {"xn--mgba1fmg.eg", L"\x0627\x0641\x0644\x0627\x0645.eg", kSafe}, + {"xn--mgba1fmg.eg", u"\u0627\u0641\u0644\u0627\u0645.eg", kSafe}, // Hebrew - {"xn--4dbib.he", L"\x05d5\x05d0\x05d4.he", kSafe}, + {"xn--4dbib.he", u"\u05d5\u05d0\u05d4.he", kSafe}, // Hebrew + Common - {"xn---123-ptf2c5c6bt.il", L"\x05e2\x05d1\x05e8\x05d9\x05ea-123.il", kSafe}, + {"xn---123-ptf2c5c6bt.il", u"\u05e2\u05d1\u05e8\u05d9\u05ea-123.il", kSafe}, // Thai {"xn--12c2cc4ag3b4ccu.th", - L"\x0e2a\x0e32\x0e22\x0e01\x0e32\x0e23\x0e1a\x0e34\x0e19.th", kSafe}, + u"\u0e2a\u0e32\u0e22\u0e01\u0e32\u0e23\u0e1a\u0e34\u0e19.th", kSafe}, // Thai + Common {"xn---123-9goxcp8c9db2r.th", - L"\x0e20\x0e32\x0e29\x0e32\x0e44\x0e17\x0e22-123.th", kSafe}, + u"\u0e20\u0e32\u0e29\u0e32\u0e44\u0e17\u0e22-123.th", kSafe}, // Devangari (Hindi) - {"www.xn--l1b6a9e1b7c.in", L"www.\x0905\x0915\x094b\x0932\x093e.in", kSafe}, + {"www.xn--l1b6a9e1b7c.in", u"www.\u0905\u0915\u094b\u0932\u093e.in", kSafe}, // Devanagari + Common - {"xn---123-kbjl2j0bl2k.in", L"\x0939\x093f\x0928\x094d\x0926\x0940-123.in", + {"xn---123-kbjl2j0bl2k.in", u"\u0939\u093f\u0928\u094d\u0926\u0940-123.in", kSafe}, // Block mixed numeric + numeric lookalike (12.com, using U+0577). - {"xn--1-9dd.com", L"1߳.com", kUnsafe}, + {"xn--1-9dd.com", u"1\u07f3.com", kUnsafe}, // Block mixed numeric lookalike + numeric (੨0.com, uses U+0A68). - {"xn--0-6ee.com", L"੨0.com", kUnsafe}, + {"xn--0-6ee.com", u"\u0a680.com", kUnsafe}, // Block fully numeric lookalikes (৪੨.com using U+09EA and U+0A68). - {"xn--47b6w.com", L"৪੨.com", kUnsafe}, + {"xn--47b6w.com", u"\u09ea\u0a68.com", kUnsafe}, // Block single script digit lookalikes (using three U+0A68 characters). - {"xn--qccaa.com", L"੨੨੨.com", kUnsafe}, + {"xn--qccaa.com", u"\u0a68\u0a68\u0a68.com", kUnsafe}, // URL test with mostly numbers and one confusable character // Georgian 'd' 4000.com - {"xn--4000-pfr.com", - L"\x10eb" - L"4000.com", - kUnsafe}, + {"xn--4000-pfr.com", u"\u10eb4000.com", kUnsafe}, // What used to be 5 Aspirational scripts in the earlier versions of UAX 31. // UAX 31 does not define aspirational scripts any more. // See http://www.unicode.org/reports/tr31/#Aspirational_Use_Scripts . // Unified Canadian Syllabary - {"xn--dfe0tte.ca", L"\x1456\x14c2\x14ef.ca", kUnsafe}, + {"xn--dfe0tte.ca", u"\u1456\u14c2\u14ef.ca", kUnsafe}, // Tifinagh - {"xn--4ljxa2bb4a6bxb.ma", L"\x2d5c\x2d49\x2d3c\x2d49\x2d4f\x2d30\x2d56.ma", + {"xn--4ljxa2bb4a6bxb.ma", u"\u2d5c\u2d49\u2d3c\u2d49\u2d4f\u2d30\u2d56.ma", kUnsafe}, // Tifinagh with a disallowed character(U+2D6F) - {"xn--hmjzaby5d5f.ma", L"\x2d5c\x2d49\x2d3c\x2d6f\x2d49\x2d4f.ma", + {"xn--hmjzaby5d5f.ma", u"\u2d5c\u2d49\u2d3c\u2d6f\u2d49\u2d4f.ma", kInvalid}, // Yi - {"xn--4o7a6e1x64c.cn", L"\xa188\xa320\xa071\xa0b7.cn", kUnsafe}, + {"xn--4o7a6e1x64c.cn", u"\ua188\ua320\ua071\ua0b7.cn", kUnsafe}, // Mongolian - 'ordu' (place, camp) - {"xn--56ec8bp.cn", L"\x1823\x1837\x1833\x1824.cn", kUnsafe}, + {"xn--56ec8bp.cn", u"\u1823\u1837\u1833\u1824.cn", kUnsafe}, // Mongolian with a disallowed character - {"xn--95e5de3ds.cn", L"\x1823\x1837\x1804\x1833\x1824.cn", kUnsafe}, + {"xn--95e5de3ds.cn", u"\u1823\u1837\u1804\u1833\u1824.cn", kUnsafe}, // Miao/Pollad - {"xn--2u0fpf0a.cn", L"\U00016f04\U00016f62\U00016f59.cn", kUnsafe}, + {"xn--2u0fpf0a.cn", u"\U00016f04\U00016f62\U00016f59.cn", kUnsafe}, // Script mixing tests // The following script combinations are allowed. @@ -190,315 +174,274 @@ // ASCII-Latin + Kore (Hangul + Han) // ASCII-Latin + Han + Bopomofo // "payp<alpha>l.com" - {"xn--paypl-g9d.com", L"payp\x03b1l.com", kUnsafe}, + {"xn--paypl-g9d.com", u"payp\u03b1l.com", kUnsafe}, // google.gr with Greek omicron and epsilon - {"xn--ggl-6xc1ca.gr", L"g\x03bf\x03bfgl\x03b5.gr", kUnsafe}, + {"xn--ggl-6xc1ca.gr", u"g\u03bf\u03bfgl\u03b5.gr", kUnsafe}, // google.ru with Cyrillic o - {"xn--ggl-tdd6ba.ru", L"g\x043e\x043egl\x0435.ru", kUnsafe}, + {"xn--ggl-tdd6ba.ru", u"g\u043e\u043egl\u0435.ru", kUnsafe}, // h<e with acute>llo<China in Han>.cn - {"xn--hllo-bpa7979ih5m.cn", L"h\x00e9llo\x4e2d\x56fd.cn", kUnsafe}, + {"xn--hllo-bpa7979ih5m.cn", u"h\u00e9llo\u4e2d\u56fd.cn", kUnsafe}, // <Greek rho><Cyrillic a><Cyrillic u>.ru - {"xn--2xa6t2b.ru", L"\x03c1\x0430\x0443.ru", kUnsafe}, + {"xn--2xa6t2b.ru", u"\u03c1\u0430\u0443.ru", kUnsafe}, // Georgian + Latin - {"xn--abcef-vuu.test", - L"abc\x10eb" - L"ef.test", - kUnsafe}, + {"xn--abcef-vuu.test", u"abc\u10ebef.test", kUnsafe}, // Hangul + Latin - {"xn--han-eb9ll88m.kr", L"\xd55c\xae00han.kr", kSafe}, + {"xn--han-eb9ll88m.kr", u"\ud55c\uae00han.kr", kSafe}, // Hangul + Latin + Han with IDN ccTLD - {"xn--han-or0kq92gkm3c.xn--3e0b707e", L"\xd55c\xae00han\x97d3.\xd55c\xad6d", + {"xn--han-or0kq92gkm3c.xn--3e0b707e", u"\ud55c\uae00han\u97d3.\ud55c\uad6d", kSafe}, // non-ASCII Latin + Hangul - {"xn--caf-dma9024xvpg.kr", L"caf\x00e9\xce74\xd398.kr", kUnsafe}, + {"xn--caf-dma9024xvpg.kr", u"caf\u00e9\uce74\ud398.kr", kUnsafe}, // Hangul + Hiragana - {"xn--y9j3b9855e.kr", L"\xd55c\x3072\x3089.kr", kUnsafe}, + {"xn--y9j3b9855e.kr", u"\ud55c\u3072\u3089.kr", kUnsafe}, // <Hiragana>.<Hangul> is allowed because script mixing check is per label. - {"xn--y9j3b.xn--3e0b707e", L"\x3072\x3089.\xd55c\xad6d", kSafe}, + {"xn--y9j3b.xn--3e0b707e", u"\u3072\u3089.\ud55c\uad6d", kSafe}, // Traditional Han + Latin - {"xn--hanzi-u57ii69i.tw", L"\x6f22\x5b57hanzi.tw", kSafe}, + {"xn--hanzi-u57ii69i.tw", u"\u6f22\u5b57hanzi.tw", kSafe}, // Simplified Han + Latin - {"xn--hanzi-u57i952h.cn", L"\x6c49\x5b57hanzi.cn", kSafe}, + {"xn--hanzi-u57i952h.cn", u"\u6c49\u5b57hanzi.cn", kSafe}, // Simplified Han + Traditonal Han - {"xn--hanzi-if9kt8n.cn", L"\x6c49\x6f22hanzi.cn", kSafe}, + {"xn--hanzi-if9kt8n.cn", u"\u6c49\u6f22hanzi.cn", kSafe}, // Han + Hiragana + Katakana + Latin {"xn--kanji-ii4dpizfq59yuykqr4b.jp", - L"\x632f\x308a\x4eee\x540d\x30ab\x30bfkanji.jp", kSafe}, + u"\u632f\u308a\u4eee\u540d\u30ab\u30bfkanji.jp", kSafe}, // Han + Bopomofo - {"xn--5ekcde0577e87tc.tw", L"\x6ce8\x97f3\x3105\x3106\x3107\x3108.tw", + {"xn--5ekcde0577e87tc.tw", u"\u6ce8\u97f3\u3105\u3106\u3107\u3108.tw", kSafe}, // Han + Latin + Bopomofo {"xn--bopo-ty4cghi8509kk7xd.tw", - L"\x6ce8\x97f3" - L"bopo\x3105\x3106\x3107\x3108.tw", - kSafe}, + u"\u6ce8\u97f3bopo\u3105\u3106\u3107\u3108.tw", kSafe}, // Latin + Bopomofo - {"xn--bopomofo-hj5gkalm.tw", L"bopomofo\x3105\x3106\x3107\x3108.tw", kSafe}, + {"xn--bopomofo-hj5gkalm.tw", u"bopomofo\u3105\u3106\u3107\u3108.tw", kSafe}, // Bopomofo + Katakana {"xn--lcka3d1bztghi.tw", - L"\x3105\x3106\x3107\x3108\x30ab\x30bf\x30ab\x30ca.tw", kUnsafe}, + u"\u3105\u3106\u3107\u3108\u30ab\u30bf\u30ab\u30ca.tw", kUnsafe}, // Bopomofo + Hangul - {"xn--5ekcde4543qbec.tw", L"\x3105\x3106\x3107\x3108\xc8fc\xc74c.tw", + {"xn--5ekcde4543qbec.tw", u"\u3105\u3106\u3107\u3108\uc8fc\uc74c.tw", kUnsafe}, // Devanagari + Latin - {"xn--ab-3ofh8fqbj6h.in", L"ab\x0939\x093f\x0928\x094d\x0926\x0940.in", + {"xn--ab-3ofh8fqbj6h.in", u"ab\u0939\u093f\u0928\u094d\u0926\u0940.in", kUnsafe}, // Thai + Latin {"xn--ab-jsi9al4bxdb6n.th", - L"ab\x0e20\x0e32\x0e29\x0e32\x0e44\x0e17\x0e22.th", kUnsafe}, + u"ab\u0e20\u0e32\u0e29\u0e32\u0e44\u0e17\u0e22.th", kUnsafe}, // Armenian + Latin - {"xn--bs-red.com", L"b\x057ds.com", kUnsafe}, + {"xn--bs-red.com", u"b\u057ds.com", kUnsafe}, // Tibetan + Latin - {"xn--foo-vkm.com", L"foo\x0f37.com", kUnsafe}, + {"xn--foo-vkm.com", u"foo\u0f37.com", kUnsafe}, // Oriya + Latin - {"xn--fo-h3g.com", L"fo\x0b66.com", kUnsafe}, + {"xn--fo-h3g.com", u"fo\u0b66.com", kUnsafe}, // Gujarati + Latin - {"xn--fo-isg.com", L"fo\x0ae6.com", kUnsafe}, + {"xn--fo-isg.com", u"fo\u0ae6.com", kUnsafe}, // <vitamin in Katakana>b1.com - {"xn--b1-xi4a7cvc9f.com", - L"\x30d3\x30bf\x30df\x30f3" - L"b1.com", - kSafe}, + {"xn--b1-xi4a7cvc9f.com", u"\u30d3\u30bf\u30df\u30f3b1.com", kSafe}, // Devanagari + Han - {"xn--t2bes3ds6749n.com", L"\x0930\x094b\x0932\x0947\x76e7\x0938.com", + {"xn--t2bes3ds6749n.com", u"\u0930\u094b\u0932\u0947\u76e7\u0938.com", kUnsafe}, // Devanagari + Bengali - {"xn--11b0x.in", L"\x0915\x0995.in", kUnsafe}, + {"xn--11b0x.in", u"\u0915\u0995.in", kUnsafe}, // Canadian Syllabary + Latin - {"xn--ab-lym.com", L"abᒿ.com", kUnsafe}, - {"xn--ab1-p6q.com", L"ab1ᒿ.com", kUnsafe}, - {"xn--1ab-m6qd.com", L"ᒿ1abᒿ.com", kUnsafe}, - {"xn--ab-jymc.com", L"ᒿabᒿ.com", kUnsafe}, + {"xn--ab-lym.com", u"ab\u14bf.com", kUnsafe}, + {"xn--ab1-p6q.com", u"ab1\u14bf.com", kUnsafe}, + {"xn--1ab-m6qd.com", u"\u14bf1ab\u14bf.com", kUnsafe}, + {"xn--ab-jymc.com", u"\u14bfab\u14bf.com", kUnsafe}, // Tifinagh + Latin - {"xn--liy-bq1b.com", L"li\u2d4fy.com", kUnsafe}, - {"xn--rol-cq1b.com", L"rol\u2d4f.com", kUnsafe}, - {"xn--ily-8p1b.com", L"\u2d4fily.com", kUnsafe}, - {"xn--1ly-8p1b.com", L"\u2d4f1ly.com", kUnsafe}, + {"xn--liy-bq1b.com", u"li\u2d4fy.com", kUnsafe}, + {"xn--rol-cq1b.com", u"rol\u2d4f.com", kUnsafe}, + {"xn--ily-8p1b.com", u"\u2d4fily.com", kUnsafe}, + {"xn--1ly-8p1b.com", u"\u2d4f1ly.com", kUnsafe}, // Invisibility check // Thai tone mark malek(U+0E48) repeated - {"xn--03c0b3ca.th", L"\x0e23\x0e35\x0e48\x0e48.th", kUnsafe}, + {"xn--03c0b3ca.th", u"\u0e23\u0e35\u0e48\u0e48.th", kUnsafe}, // Accute accent repeated - {"xn--a-xbba.com", L"a\x0301\x0301.com", kInvalid}, + {"xn--a-xbba.com", u"a\u0301\u0301.com", kInvalid}, // 'a' with acuted accent + another acute accent - {"xn--1ca20i.com", L"\x00e1\x0301.com", kUnsafe}, + {"xn--1ca20i.com", u"\u00e1\u0301.com", kUnsafe}, // Combining mark at the beginning - {"xn--abc-fdc.jp", L"\u0300abc.jp", kInvalid}, + {"xn--abc-fdc.jp", u"\u0300abc.jp", kInvalid}, // The following three are detected by |dangerous_pattern| regex, but // can be regarded as an extension of blocking repeated diacritic marks. // i followed by U+0307 (combining dot above) - {"xn--pixel-8fd.com", L"pi\x0307xel.com", kUnsafe}, + {"xn--pixel-8fd.com", u"pi\u0307xel.com", kUnsafe}, // U+0131 (dotless i) followed by U+0307 - {"xn--pxel-lza43z.com", L"p\x0131\x0307xel.com", kUnsafe}, + {"xn--pxel-lza43z.com", u"p\u0131\u0307xel.com", kUnsafe}, // j followed by U+0307 (combining dot above) - {"xn--jack-qwc.com", - L"j\x0307" - L"ack.com", - kUnsafe}, + {"xn--jack-qwc.com", u"j\u0307ack.com", kUnsafe}, // l followed by U+0307 - {"xn--lace-qwc.com", - L"l\x0307" - L"ace.com", - kUnsafe}, + {"xn--lace-qwc.com", u"l\u0307ace.com", kUnsafe}, // Do not allow a combining mark after dotless i/j. - {"xn--pxel-lza29y.com", L"p\x0131\x0300xel.com", kUnsafe}, - {"xn--ack-gpb42h.com", - L"\x0237\x0301" - L"ack.com", - kUnsafe}, + {"xn--pxel-lza29y.com", u"p\u0131\u0300xel.com", kUnsafe}, + {"xn--ack-gpb42h.com", u"\u0237\u0301ack.com", kUnsafe}, // Mixed script confusable // google with Armenian Small Letter Oh(U+0585) - {"xn--gogle-lkg.com", L"g\x0585ogle.com", kUnsafe}, - {"xn--range-kkg.com", L"\x0585range.com", kUnsafe}, - {"xn--cucko-pkg.com", L"cucko\x0585.com", kUnsafe}, + {"xn--gogle-lkg.com", u"g\u0585ogle.com", kUnsafe}, + {"xn--range-kkg.com", u"\u0585range.com", kUnsafe}, + {"xn--cucko-pkg.com", u"cucko\u0585.com", kUnsafe}, // Latin 'o' in Armenian. - {"xn--o-ybcg0cu0cq.com", L"o\x0580\x0574\x0578\x0582\x0566\x0568.com", + {"xn--o-ybcg0cu0cq.com", u"o\u0580\u0574\u0578\u0582\u0566\u0568.com", kUnsafe}, // Hiragana HE(U+3078) mixed with Katakana {"xn--49jxi3as0d0fpc.com", - L"\x30e2\x30d2\x30fc\x30c8\x3078\x30d6\x30f3.com", kUnsafe}, + u"\u30e2\u30d2\u30fc\u30c8\u3078\u30d6\u30f3.com", kUnsafe}, // U+30FC should be preceded by a Hiragana/Katakana. // Katakana + U+30FC + Han - {"xn--lck0ip02qw5ya.jp", L"\x30ab\x30fc\x91ce\x7403.jp", kSafe}, + {"xn--lck0ip02qw5ya.jp", u"\u30ab\u30fc\u91ce\u7403.jp", kSafe}, // Hiragana + U+30FC + Han - {"xn--u8j5tr47nw5ya.jp", L"\x304b\x30fc\x91ce\x7403.jp", kSafe}, + {"xn--u8j5tr47nw5ya.jp", u"\u304b\u30fc\u91ce\u7403.jp", kSafe}, // U+30FC + Han - {"xn--weka801xo02a.com", L"\x30fc\x52d5\x753b\x30fc.com", kUnsafe}, + {"xn--weka801xo02a.com", u"\u30fc\u52d5\u753b\u30fc.com", kUnsafe}, // Han + U+30FC + Han - {"xn--wekz60nb2ay85atj0b.jp", L"\x65e5\x672c\x30fc\x91ce\x7403.jp", + {"xn--wekz60nb2ay85atj0b.jp", u"\u65e5\u672c\u30fc\u91ce\u7403.jp", kUnsafe}, // U+30FC at the beginning - {"xn--wek060nb2a.jp", L"\x30fc\x65e5\x672c.jp", kUnsafe}, + {"xn--wek060nb2a.jp", u"\u30fc\u65e5\u672c.jp", kUnsafe}, // Latin + U+30FC + Latin - {"xn--abcdef-r64e.jp", - L"abc\x30fc" - L"def.jp", - kUnsafe}, + {"xn--abcdef-r64e.jp", u"abc\u30fcdef.jp", kUnsafe}, // U+30FB (・) is not allowed next to Latin, but allowed otherwise. // U+30FB + Han - {"xn--vekt920a.jp", L"\x30fb\x91ce.jp", kSafe}, + {"xn--vekt920a.jp", u"\u30fb\u91ce.jp", kSafe}, // Han + U+30FB + Han - {"xn--vek160nb2ay85atj0b.jp", L"\x65e5\x672c\x30fb\x91ce\x7403.jp", kSafe}, + {"xn--vek160nb2ay85atj0b.jp", u"\u65e5\u672c\u30fb\u91ce\u7403.jp", kSafe}, // Latin + U+30FB + Latin - {"xn--abcdef-k64e.jp", - L"abc\x30fb" - L"def.jp", - kUnsafe}, + {"xn--abcdef-k64e.jp", u"abc\u30fbdef.jp", kUnsafe}, // U+30FB + Latin - {"xn--abc-os4b.jp", - L"\x30fb" - L"abc.jp", - kUnsafe}, + {"xn--abc-os4b.jp", u"\u30fbabc.jp", kUnsafe}, // U+30FD (ヽ) is allowed only after Katakana. // Katakana + U+30FD - {"xn--lck2i.jp", L"\x30ab\x30fd.jp", kSafe}, + {"xn--lck2i.jp", u"\u30ab\u30fd.jp", kSafe}, // Hiragana + U+30FD - {"xn--u8j7t.jp", L"\x304b\x30fd.jp", kUnsafe}, + {"xn--u8j7t.jp", u"\u304b\u30fd.jp", kUnsafe}, // Han + U+30FD - {"xn--xek368f.jp", L"\x4e00\x30fd.jp", kUnsafe}, - {"xn--a-mju.jp", L"a\x30fd.jp", kUnsafe}, - {"xn--a1-bo4a.jp", L"a1\x30fd.jp", kUnsafe}, + {"xn--xek368f.jp", u"\u4e00\u30fd.jp", kUnsafe}, + {"xn--a-mju.jp", u"a\u30fd.jp", kUnsafe}, + {"xn--a1-bo4a.jp", u"a1\u30fd.jp", kUnsafe}, // U+30FE (ヾ) is allowed only after Katakana. // Katakana + U+30FE - {"xn--lck4i.jp", L"\x30ab\x30fe.jp", kSafe}, + {"xn--lck4i.jp", u"\u30ab\u30fe.jp", kSafe}, // Hiragana + U+30FE - {"xn--u8j9t.jp", L"\x304b\x30fe.jp", kUnsafe}, + {"xn--u8j9t.jp", u"\u304b\u30fe.jp", kUnsafe}, // Han + U+30FE - {"xn--yek168f.jp", L"\x4e00\x30fe.jp", kUnsafe}, - {"xn--a-oju.jp", L"a\x30fe.jp", kUnsafe}, - {"xn--a1-eo4a.jp", L"a1\x30fe.jp", kUnsafe}, + {"xn--yek168f.jp", u"\u4e00\u30fe.jp", kUnsafe}, + {"xn--a-oju.jp", u"a\u30fe.jp", kUnsafe}, + {"xn--a1-eo4a.jp", u"a1\u30fe.jp", kUnsafe}, // Cyrillic labels made of Latin-look-alike Cyrillic letters. // 1) ѕсоре.com with ѕсоре in Cyrillic. - {"xn--e1argc3h.com", L"\x0455\x0441\x043e\x0440\x0435.com", kUnsafe}, + {"xn--e1argc3h.com", u"\u0455\u0441\u043e\u0440\u0435.com", kUnsafe}, // 2) ѕсоре123.com with ѕсоре in Cyrillic. - {"xn--123-qdd8bmf3n.com", - L"\x0455\x0441\x043e\x0440\x0435" - L"123.com", + {"xn--123-qdd8bmf3n.com", u"\u0455\u0441\u043e\u0440\u0435123.com", kUnsafe}, // 3) ѕсоре-рау.com with ѕсоре and рау in Cyrillic. {"xn----8sbn9akccw8m.com", - L"\x0455\x0441\x043e\x0440\x0435-\x0440\x0430\x0443.com", kUnsafe}, + u"\u0455\u0441\u043e\u0440\u0435-\u0440\u0430\u0443.com", kUnsafe}, // 4) ѕсоре1рау.com with scope and pay in Cyrillic and a non-letter between // them. {"xn--1-8sbn9akccw8m.com", - L"\x0455\x0441\x043e\x0440\x0435\x0031\x0440\x0430\x0443.com", kUnsafe}, + u"\u0455\u0441\u043e\u0440\u0435\u0031\u0440\u0430\u0443.com", kUnsafe}, // The same as above three, but in IDN TLD (рф). - // 1) ѕсоре.рф with ѕсоре in Cyrillic. - {"xn--e1argc3h.xn--p1ai", L"\x0455\x0441\x043e\x0440\x0435.\x0440\x0444", + // 1) ѕсоре.рф with ѕсоре in Cyrillic. + {"xn--e1argc3h.xn--p1ai", u"\u0455\u0441\u043e\u0440\u0435.\u0440\u0444", kSafe}, // 2) ѕсоре123.рф with ѕсоре in Cyrillic. {"xn--123-qdd8bmf3n.xn--p1ai", - L"\x0455\x0441\x043e\x0440\x0435" - L"123.\x0440\x0444", - kSafe}, + u"\u0455\u0441\u043e\u0440\u0435123.\u0440\u0444", kSafe}, // 3) ѕсоре-рау.рф with ѕсоре and рау in Cyrillic. {"xn----8sbn9akccw8m.xn--p1ai", - L"\x0455\x0441\x043e\x0440\x0435-\x0440\x0430\x0443.\x0440\x0444", kSafe}, + u"\u0455\u0441\u043e\u0440\u0435-\u0440\u0430\u0443.\u0440\u0444", kSafe}, // 4) ѕсоре1рау.com with scope and pay in Cyrillic and a non-letter between // them. {"xn--1-8sbn9akccw8m.xn--p1ai", - L"\x0455\x0441\x043e\x0440\x0435\x0031\x0440\x0430\x0443.\x0440\x0444", + u"\u0455\u0441\u043e\u0440\u0435\u0031\u0440\u0430\u0443.\u0440\u0444", kSafe}, // Same as above three, but in .ru TLD. // 1) ѕсоре.ru with ѕсоре in Cyrillic. - {"xn--e1argc3h.ru", L"\x0455\x0441\x043e\x0440\x0435.ru", kSafe}, + {"xn--e1argc3h.ru", u"\u0455\u0441\u043e\u0440\u0435.ru", kSafe}, // 2) ѕсоре123.ru with ѕсоре in Cyrillic. - {"xn--123-qdd8bmf3n.ru", - L"\x0455\x0441\x043e\x0440\x0435" - L"123.ru", - kSafe}, + {"xn--123-qdd8bmf3n.ru", u"\u0455\u0441\u043e\u0440\u0435123.ru", kSafe}, // 3) ѕсоре-рау.ru with ѕсоре and рау in Cyrillic. {"xn----8sbn9akccw8m.ru", - L"\x0455\x0441\x043e\x0440\x0435-\x0440\x0430\x0443.ru", kSafe}, + u"\u0455\u0441\u043e\u0440\u0435-\u0440\u0430\u0443.ru", kSafe}, // 4) ѕсоре1рау.com with scope and pay in Cyrillic and a non-letter between // them. {"xn--1-8sbn9akccw8m.ru", - L"\x0455\x0441\x043e\x0440\x0435\x0031\x0440\x0430\x0443.ru", kSafe}, + u"\u0455\u0441\u043e\u0440\u0435\u0031\u0440\u0430\u0443.ru", kSafe}, // ѕсоре-рау.한국 with ѕсоре and рау in Cyrillic. The label will remain // punycode while the TLD will be decoded. - {"xn----8sbn9akccw8m.xn--3e0b707e", L"xn----8sbn9akccw8m.\xd55c\xad6d", + {"xn----8sbn9akccw8m.xn--3e0b707e", u"xn----8sbn9akccw8m.\ud55c\uad6d", kSafe}, // музей (museum in Russian) has characters without a Latin-look-alike. - {"xn--e1adhj9a.com", L"\x043c\x0443\x0437\x0435\x0439.com", kSafe}, + {"xn--e1adhj9a.com", u"\u043c\u0443\u0437\u0435\u0439.com", kSafe}, // ѕсоԗе.com is Cyrillic with Latin lookalikes. - {"xn--e1ari3f61c.com", L"\x0455\x0441\x043e\x0517\x0435.com", kUnsafe}, + {"xn--e1ari3f61c.com", u"\u0455\u0441\u043e\u0517\u0435.com", kUnsafe}, // ыоԍ.com is Cyrillic with Latin lookalikes. - {"xn--n1az74c.com", L"\x044b\x043e\x050d.com", kUnsafe}, + {"xn--n1az74c.com", u"\u044b\u043e\u050d.com", kUnsafe}, // сю.com is Cyrillic with Latin lookalikes. - {"xn--q1a0a.com", L"\x0441\x044e.com", kUnsafe}, + {"xn--q1a0a.com", u"\u0441\u044e.com", kUnsafe}, // Regression test for lowercase letters in whole script confusable // lookalike character lists. - {"xn--80a8a6a.com", L"аьс.com", kUnsafe}, + {"xn--80a8a6a.com", u"\u0430\u044c\u0441.com", kUnsafe}, // googlе.한국 where е is Cyrillic. This tests the generic case when one // label is not allowed but other labels in the domain name are still // decoded. Here, googlе is left in punycode but the TLD is decoded. - {"xn--googl-3we.xn--3e0b707e", L"xn--googl-3we.\xd55c\xad6d", kSafe}, + {"xn--googl-3we.xn--3e0b707e", u"xn--googl-3we.\ud55c\uad6d", kSafe}, // Combining Diacritic marks after a script other than Latin-Greek-Cyrillic - {"xn--rsa2568fvxya.com", L"\xd55c\x0307\xae00.com", kUnsafe}, // 한́글.com - {"xn--rsa0336bjom.com", L"\x6f22\x0307\x5b57.com", kUnsafe}, // 漢̇字.com + {"xn--rsa2568fvxya.com", u"\ud55c\u0307\uae00.com", kUnsafe}, // 한́글.com + {"xn--rsa0336bjom.com", u"\u6f22\u0307\u5b57.com", kUnsafe}, // 漢̇字.com // नागरी́.com - {"xn--lsa922apb7a6do.com", L"\x0928\x093e\x0917\x0930\x0940\x0301.com", + {"xn--lsa922apb7a6do.com", u"\u0928\u093e\u0917\u0930\u0940\u0301.com", kUnsafe}, // Similarity checks against the list of top domains. "digklmo68.com" and // 'digklmo68.co.uk" are listed for unittest in the top domain list. // đigklmo68.com: - {"xn--igklmo68-kcb.com", L"\x0111igklmo68.com", kUnsafe}, + {"xn--igklmo68-kcb.com", u"\u0111igklmo68.com", kUnsafe}, // www.đigklmo68.com: - {"www.xn--igklmo68-kcb.com", L"www.\x0111igklmo68.com", kUnsafe}, + {"www.xn--igklmo68-kcb.com", u"www.\u0111igklmo68.com", kUnsafe}, // foo.bar.đigklmo68.com: - {"foo.bar.xn--igklmo68-kcb.com", L"foo.bar.\x0111igklmo68.com", kUnsafe}, + {"foo.bar.xn--igklmo68-kcb.com", u"foo.bar.\u0111igklmo68.com", kUnsafe}, // đigklmo68.co.uk: - {"xn--igklmo68-kcb.co.uk", L"\x0111igklmo68.co.uk", kUnsafe}, + {"xn--igklmo68-kcb.co.uk", u"\u0111igklmo68.co.uk", kUnsafe}, // mail.đigklmo68.co.uk: - {"mail.xn--igklmo68-kcb.co.uk", L"mail.\x0111igklmo68.co.uk", kUnsafe}, + {"mail.xn--igklmo68-kcb.co.uk", u"mail.\u0111igklmo68.co.uk", kUnsafe}, // di̇gklmo68.com: - {"xn--digklmo68-6jf.com", L"di\x0307gklmo68.com", kUnsafe}, + {"xn--digklmo68-6jf.com", u"di\u0307gklmo68.com", kUnsafe}, // dig̱klmo68.com: - {"xn--digklmo68-7vf.com", L"dig\x0331klmo68.com", kUnsafe}, + {"xn--digklmo68-7vf.com", u"dig\u0331klmo68.com", kUnsafe}, // digĸlmo68.com: - {"xn--diglmo68-omb.com", L"dig\x0138lmo68.com", kUnsafe}, + {"xn--diglmo68-omb.com", u"dig\u0138lmo68.com", kUnsafe}, // digkłmo68.com: - {"xn--digkmo68-9ob.com", L"digk\x0142mo68.com", kUnsafe}, + {"xn--digkmo68-9ob.com", u"digk\u0142mo68.com", kUnsafe}, // digklṃo68.com: - {"xn--digklo68-l89c.com", L"digkl\x1e43o68.com", kUnsafe}, + {"xn--digklo68-l89c.com", u"digkl\u1e43o68.com", kUnsafe}, // digklmø68.com: - {"xn--digklm68-b5a.com", - L"digklm\x00f8" - L"68.com", - kUnsafe}, + {"xn--digklm68-b5a.com", u"digklm\u00f868.com", kUnsafe}, // digklmoб8.com: - {"xn--digklmo8-h7g.com", - L"digklmo\x0431" - L"8.com", - kUnsafe}, + {"xn--digklmo8-h7g.com", u"digklmo\u04318.com", kUnsafe}, // digklmo6৪.com: - {"xn--digklmo6-7yr.com", L"digklmo6\x09ea.com", kUnsafe}, + {"xn--digklmo6-7yr.com", u"digklmo6\u09ea.com", kUnsafe}, // 'islkpx123.com' is in the test domain list. // 'іѕӏкрх123' can look like 'islkpx123' in some fonts. {"xn--123-bed4a4a6hh40i.com", - L"\x0456\x0455\x04cf\x043a\x0440\x0445" - L"123.com", - kUnsafe}, + u"\u0456\u0455\u04cf\u043a\u0440\u0445123.com", kUnsafe}, // 'o2.com', '28.com', '39.com', '43.com', '89.com', 'oo.com' and 'qq.com' // are all explicitly added to the test domain list to aid testing of @@ -506,549 +449,400 @@ // edge cases. // // Bengali: - {"xn--07be.com", L"\x09e6\x09e8.com", kUnsafe}, - {"xn--27be.com", L"\x09e8\x09ea.com", kUnsafe}, - {"xn--77ba.com", L"\x09ed\x09ed.com", kUnsafe}, + {"xn--07be.com", u"\u09e6\u09e8.com", kUnsafe}, + {"xn--27be.com", u"\u09e8\u09ea.com", kUnsafe}, + {"xn--77ba.com", u"\u09ed\u09ed.com", kUnsafe}, // Gurmukhi: - {"xn--qcce.com", L"\x0a68\x0a6a.com", kUnsafe}, - {"xn--occe.com", L"\x0a66\x0a68.com", kUnsafe}, - {"xn--rccd.com", L"\x0a6b\x0a69.com", kUnsafe}, - {"xn--pcca.com", L"\x0a67\x0a67.com", kUnsafe}, + {"xn--qcce.com", u"\u0a68\u0a6a.com", kUnsafe}, + {"xn--occe.com", u"\u0a66\u0a68.com", kUnsafe}, + {"xn--rccd.com", u"\u0a6b\u0a69.com", kUnsafe}, + {"xn--pcca.com", u"\u0a67\u0a67.com", kUnsafe}, // Telugu: - {"xn--drcb.com", L"\x0c69\x0c68.com", kUnsafe}, + {"xn--drcb.com", u"\u0c69\u0c68.com", kUnsafe}, // Devanagari: - {"xn--d4be.com", L"\x0966\x0968.com", kUnsafe}, + {"xn--d4be.com", u"\u0966\u0968.com", kUnsafe}, // Kannada: - {"xn--yucg.com", L"\x0ce6\x0ce9.com", kUnsafe}, - {"xn--yuco.com", L"\x0ce6\x0ced.com", kUnsafe}, + {"xn--yucg.com", u"\u0ce6\u0ce9.com", kUnsafe}, + {"xn--yuco.com", u"\u0ce6\u0ced.com", kUnsafe}, // Oriya: - {"xn--1jcf.com", L"\x0b6b\x0b68.com", kUnsafe}, - {"xn--zjca.com", L"\x0b66\x0b66.com", kUnsafe}, + {"xn--1jcf.com", u"\u0b6b\u0b68.com", kUnsafe}, + {"xn--zjca.com", u"\u0b66\u0b66.com", kUnsafe}, // Gujarati: - {"xn--cgce.com", L"\x0ae6\x0ae8.com", kUnsafe}, - {"xn--fgci.com", L"\x0ae9\x0aed.com", kUnsafe}, - {"xn--dgca.com", L"\x0ae7\x0ae7.com", kUnsafe}, + {"xn--cgce.com", u"\u0ae6\u0ae8.com", kUnsafe}, + {"xn--fgci.com", u"\u0ae9\u0aed.com", kUnsafe}, + {"xn--dgca.com", u"\u0ae7\u0ae7.com", kUnsafe}, // wmhtb.com - {"xn--l1acpvx.com", L"\x0448\x043c\x043d\x0442\x044c.com", kUnsafe}, + {"xn--l1acpvx.com", u"\u0448\u043c\u043d\u0442\u044c.com", kUnsafe}, // щмнть.com - {"xn--l1acpzs.com", L"\x0449\x043c\x043d\x0442\x044c.com", kUnsafe}, + {"xn--l1acpzs.com", u"\u0449\u043c\u043d\u0442\u044c.com", kUnsafe}, // шмнтв.com - {"xn--b1atdu1a.com", L"\x0448\x043c\x043d\x0442\x0432.com", kUnsafe}, + {"xn--b1atdu1a.com", u"\u0448\u043c\u043d\u0442\u0432.com", kUnsafe}, // шмԋтв.com - {"xn--b1atsw09g.com", L"\x0448\x043c\x050b\x0442\x0432.com", kUnsafe}, + {"xn--b1atsw09g.com", u"\u0448\u043c\u050b\u0442\u0432.com", kUnsafe}, // шмԧтв.com - {"xn--b1atsw03i.com", L"\x0448\x043c\x0527\x0442\x0432.com", kUnsafe}, + {"xn--b1atsw03i.com", u"\u0448\u043c\u0527\u0442\u0432.com", kUnsafe}, // шмԋԏв.com - {"xn--b1at9a12dua.com", L"\x0448\x043c\x050b\x050f\x0432.com", kUnsafe}, + {"xn--b1at9a12dua.com", u"\u0448\u043c\u050b\u050f\u0432.com", kUnsafe}, // ഠട345.com - {"xn--345-jtke.com", - L"\x0d20\x0d1f" - L"345.com", - kUnsafe}, + {"xn--345-jtke.com", u"\u0d20\u0d1f345.com", kUnsafe}, // Test additional confusable LGC characters (most of them without // decomposition into base + diacritc mark). The corresponding ASCII // domain names are in the test top domain list. // ϼκαωχ.com - {"xn--mxar4bh6w.com", L"\x03fc\x03ba\x03b1\x03c9\x03c7.com", kUnsafe}, + {"xn--mxar4bh6w.com", u"\u03fc\u03ba\u03b1\u03c9\u03c7.com", kUnsafe}, // þħĸŧƅ.com - {"xn--vda6f3b2kpf.com", L"\x00fe\x0127\x0138\x0167\x0185.com", kUnsafe}, + {"xn--vda6f3b2kpf.com", u"\u00fe\u0127\u0138\u0167\u0185.com", kUnsafe}, // þhktb.com - {"xn--hktb-9ra.com", L"\x00fehktb.com", kUnsafe}, + {"xn--hktb-9ra.com", u"\u00fehktb.com", kUnsafe}, // pħktb.com - {"xn--pktb-5xa.com", L"p\x0127ktb.com", kUnsafe}, + {"xn--pktb-5xa.com", u"p\u0127ktb.com", kUnsafe}, // phĸtb.com - {"xn--phtb-m0a.com", L"ph\x0138tb.com", kUnsafe}, + {"xn--phtb-m0a.com", u"ph\u0138tb.com", kUnsafe}, // phkŧb.com - {"xn--phkb-d7a.com", - L"phk\x0167" - L"b.com", - kUnsafe}, + {"xn--phkb-d7a.com", u"phk\u0167b.com", kUnsafe}, // phktƅ.com - {"xn--phkt-ocb.com", L"phkt\x0185.com", kUnsafe}, + {"xn--phkt-ocb.com", u"phkt\u0185.com", kUnsafe}, // ҏнкть.com - {"xn--j1afq4bxw.com", L"\x048f\x043d\x043a\x0442\x044c.com", kUnsafe}, + {"xn--j1afq4bxw.com", u"\u048f\u043d\u043a\u0442\u044c.com", kUnsafe}, // ҏћкть.com - {"xn--j1aq4a7cvo.com", L"\x048f\x045b\x043a\x0442\x044c.com", kUnsafe}, + {"xn--j1aq4a7cvo.com", u"\u048f\u045b\u043a\u0442\u044c.com", kUnsafe}, // ҏңкть.com - {"xn--j1aq4azund.com", L"\x048f\x04a3\x043a\x0442\x044c.com", kUnsafe}, + {"xn--j1aq4azund.com", u"\u048f\u04a3\u043a\u0442\u044c.com", kUnsafe}, // ҏҥкть.com - {"xn--j1aq4azuxd.com", L"\x048f\x04a5\x043a\x0442\x044c.com", kUnsafe}, + {"xn--j1aq4azuxd.com", u"\u048f\u04a5\u043a\u0442\u044c.com", kUnsafe}, // ҏӈкть.com - {"xn--j1aq4azuyj.com", L"\x048f\x04c8\x043a\x0442\x044c.com", kUnsafe}, + {"xn--j1aq4azuyj.com", u"\u048f\u04c8\u043a\u0442\u044c.com", kUnsafe}, // ҏԧкть.com - {"xn--j1aq4azu9z.com", L"\x048f\x0527\x043a\x0442\x044c.com", kUnsafe}, + {"xn--j1aq4azu9z.com", u"\u048f\u0527\u043a\u0442\u044c.com", kUnsafe}, // ҏԩкть.com - {"xn--j1aq4azuq0a.com", L"\x048f\x0529\x043a\x0442\x044c.com", kUnsafe}, + {"xn--j1aq4azuq0a.com", u"\u048f\u0529\u043a\u0442\u044c.com", kUnsafe}, // ҏнқть.com - {"xn--m1ak4azu6b.com", L"\x048f\x043d\x049b\x0442\x044c.com", kUnsafe}, + {"xn--m1ak4azu6b.com", u"\u048f\u043d\u049b\u0442\u044c.com", kUnsafe}, // ҏнҝть.com - {"xn--m1ak4azunc.com", L"\x048f\x043d\x049d\x0442\x044c.com", kUnsafe}, + {"xn--m1ak4azunc.com", u"\u048f\u043d\u049d\u0442\u044c.com", kUnsafe}, // ҏнҟть.com - {"xn--m1ak4azuxc.com", L"\x048f\x043d\x049f\x0442\x044c.com", kUnsafe}, + {"xn--m1ak4azuxc.com", u"\u048f\u043d\u049f\u0442\u044c.com", kUnsafe}, // ҏнҡть.com - {"xn--m1ak4azu7c.com", L"\x048f\x043d\x04a1\x0442\x044c.com", kUnsafe}, + {"xn--m1ak4azu7c.com", u"\u048f\u043d\u04a1\u0442\u044c.com", kUnsafe}, // ҏнӄть.com - {"xn--m1ak4azu8i.com", L"\x048f\x043d\x04c4\x0442\x044c.com", kUnsafe}, + {"xn--m1ak4azu8i.com", u"\u048f\u043d\u04c4\u0442\u044c.com", kUnsafe}, // ҏнԟть.com - {"xn--m1ak4azuzy.com", L"\x048f\x043d\x051f\x0442\x044c.com", kUnsafe}, + {"xn--m1ak4azuzy.com", u"\u048f\u043d\u051f\u0442\u044c.com", kUnsafe}, // ҏнԟҭь.com - {"xn--m1a4a4nnery.com", L"\x048f\x043d\x051f\x04ad\x044c.com", kUnsafe}, + {"xn--m1a4a4nnery.com", u"\u048f\u043d\u051f\u04ad\u044c.com", kUnsafe}, // ҏнԟҭҍ.com - {"xn--m1a4ne5jry.com", L"\x048f\x043d\x051f\x04ad\x048d.com", kUnsafe}, + {"xn--m1a4ne5jry.com", u"\u048f\u043d\u051f\u04ad\u048d.com", kUnsafe}, // ҏнԟҭв.com - {"xn--b1av9v8dry.com", L"\x048f\x043d\x051f\x04ad\x0432.com", kUnsafe}, + {"xn--b1av9v8dry.com", u"\u048f\u043d\u051f\u04ad\u0432.com", kUnsafe}, // ҏӊԟҭв.com - {"xn--b1a9p8c1e8r.com", L"\x048f\x04ca\x051f\x04ad\x0432.com", kUnsafe}, + {"xn--b1a9p8c1e8r.com", u"\u048f\u04ca\u051f\u04ad\u0432.com", kUnsafe}, // wmŋr.com - {"xn--wmr-jxa.com", L"wm\x014br.com", kUnsafe}, + {"xn--wmr-jxa.com", u"wm\u014br.com", kUnsafe}, // шмпґ.com - {"xn--l1agz80a.com", L"\x0448\x043c\x043f\x0491.com", kUnsafe}, + {"xn--l1agz80a.com", u"\u0448\u043c\u043f\u0491.com", kUnsafe}, // щмпґ.com - {"xn--l1ag2a0y.com", L"\x0449\x043c\x043f\x0491.com", kUnsafe}, + {"xn--l1ag2a0y.com", u"\u0449\u043c\u043f\u0491.com", kUnsafe}, // щӎпґ.com - {"xn--o1at1tsi.com", L"\x0449\x04ce\x043f\x0491.com", kUnsafe}, + {"xn--o1at1tsi.com", u"\u0449\u04ce\u043f\u0491.com", kUnsafe}, // ґғ.com - {"xn--03ae.com", L"\x0491\x0493.com", kUnsafe}, + {"xn--03ae.com", u"\u0491\u0493.com", kUnsafe}, // ґӻ.com - {"xn--03a6s.com", L"\x0491\x04fb.com", kUnsafe}, + {"xn--03a6s.com", u"\u0491\u04fb.com", kUnsafe}, // ҫұҳҽ.com - {"xn--r4amg4b.com", L"\x04ab\x04b1\x04b3\x04bd.com", kUnsafe}, + {"xn--r4amg4b.com", u"\u04ab\u04b1\u04b3\u04bd.com", kUnsafe}, // ҫұӽҽ.com - {"xn--r4am0b8r.com", L"\x04ab\x04b1\x04fd\x04bd.com", kUnsafe}, + {"xn--r4am0b8r.com", u"\u04ab\u04b1\u04fd\u04bd.com", kUnsafe}, // ҫұӿҽ.com - {"xn--r4am0b3s.com", L"\x04ab\x04b1\x04ff\x04bd.com", kUnsafe}, + {"xn--r4am0b3s.com", u"\u04ab\u04b1\u04ff\u04bd.com", kUnsafe}, // ҫұӿҿ.com - {"xn--r4am6b4p.com", L"\x04ab\x04b1\x04ff\x04bf.com", kUnsafe}, + {"xn--r4am6b4p.com", u"\u04ab\u04b1\u04ff\u04bf.com", kUnsafe}, // ҫұӿє.com - {"xn--91a7osa62a.com", L"\x04ab\x04b1\x04ff\x0454.com", kUnsafe}, + {"xn--91a7osa62a.com", u"\u04ab\u04b1\u04ff\u0454.com", kUnsafe}, // ӏԃԍ.com - {"xn--s5a8h4a.com", L"\x04cf\x0503\x050d.com", kUnsafe}, + {"xn--s5a8h4a.com", u"\u04cf\u0503\u050d.com", kUnsafe}, // U+04CF(ӏ) is mapped to multiple characters, lowercase L(l) and // lowercase I(i). Lowercase L is also regarded as similar to digit 1. // The test domain list has {ig, ld, 1gd}.com for Cyrillic. // ӏԍ.com - {"xn--s5a8j.com", L"\x04cf\x050d.com", kUnsafe}, + {"xn--s5a8j.com", u"\u04cf\u050d.com", kUnsafe}, // ӏԃ.com - {"xn--s5a8h.com", L"\x04cf\x0503.com", kUnsafe}, + {"xn--s5a8h.com", u"\u04cf\u0503.com", kUnsafe}, // ӏԍԃ.com - {"xn--s5a8h3a.com", L"\x04cf\x050d\x0503.com", kUnsafe}, + {"xn--s5a8h3a.com", u"\u04cf\u050d\u0503.com", kUnsafe}, // 1շ34567890.com - {"xn--134567890-gnk.com", L"1շ34567890.com", kUnsafe}, + {"xn--134567890-gnk.com", u"1\u057734567890.com", kUnsafe}, // ꓲ2345б7890.com - {"xn--23457890-e7g93622b.com", - L"\xa4f2" - L"2345\x0431" - L"7890.com", - kUnsafe}, + {"xn--23457890-e7g93622b.com", u"\ua4f22345\u04317890.com", kUnsafe}, // 1ᒿ345б7890.com - {"xn--13457890-e7g0943b.com", - L"1\x14bf" - L"345\x0431" - L"7890.com", - kUnsafe}, + {"xn--13457890-e7g0943b.com", u"1\u14bf345\u04317890.com", kUnsafe}, // 12з4567890.com - {"xn--124567890-10h.com", - L"12\x0437" - L"4567890.com", - kUnsafe}, + {"xn--124567890-10h.com", u"12\u04374567890.com", kUnsafe}, // 12ҙ4567890.com - {"xn--124567890-1ti.com", - L"12\x0499" - L"4567890.com", - kUnsafe}, + {"xn--124567890-1ti.com", u"12\u04994567890.com", kUnsafe}, // 12ӡ4567890.com - {"xn--124567890-mfj.com", - L"12\x04e1" - L"4567890.com", - kUnsafe}, + {"xn--124567890-mfj.com", u"12\u04e14567890.com", kUnsafe}, // 12उ4567890.com - {"xn--124567890-m3r.com", - L"12\u0909" - L"4567890.com", - kUnsafe}, + {"xn--124567890-m3r.com", u"12\u09094567890.com", kUnsafe}, // 12ও4567890.com - {"xn--124567890-17s.com", - L"12\u0993" - L"4567890.com", - kUnsafe}, + {"xn--124567890-17s.com", u"12\u09934567890.com", kUnsafe}, // 12ਤ4567890.com - {"xn--124567890-hfu.com", - L"12\u0a24" - L"4567890.com", - kUnsafe}, + {"xn--124567890-hfu.com", u"12\u0a244567890.com", kUnsafe}, // 12ဒ4567890.com - {"xn--124567890-6s6a.com", - L"12\x1012" - L"4567890.com", - kUnsafe}, + {"xn--124567890-6s6a.com", u"12\u10124567890.com", kUnsafe}, // 12ვ4567890.com - {"xn--124567890-we8a.com", - L"12\x10D5" - L"4567890.com", - kUnsafe}, + {"xn--124567890-we8a.com", u"12\u10D54567890.com", kUnsafe}, // 12პ4567890.com - {"xn--124567890-hh8a.com", - L"12\x10DE" - L"4567890.com", - kUnsafe}, + {"xn--124567890-hh8a.com", u"12\u10DE4567890.com", kUnsafe}, // 123ㄐ567890.com - {"xn--123567890-dr5h.com", L"123ㄐ567890.com", kUnsafe}, + {"xn--123567890-dr5h.com", u"123ㄐ567890.com", kUnsafe}, // 123Ꮞ567890.com - {"xn--123567890-dm4b.com", - L"123\x13ce" - L"567890.com", - kUnsafe}, + {"xn--123567890-dm4b.com", u"123\u13ce567890.com", kUnsafe}, // 12345б7890.com - {"xn--123457890-fzh.com", - L"12345\x0431" - L"7890.com", - kUnsafe}, + {"xn--123457890-fzh.com", u"12345\u04317890.com", kUnsafe}, // 12345ճ7890.com - {"xn--123457890-fmk.com", L"12345ճ7890.com", kUnsafe}, + {"xn--123457890-fmk.com", u"12345ճ7890.com", kUnsafe}, // 1234567ȣ90.com - {"xn--123456790-6od.com", - L"1234567\x0223" - L"90.com", - kUnsafe}, + {"xn--123456790-6od.com", u"1234567\u022390.com", kUnsafe}, // 12345678୨0.com - {"xn--123456780-71w.com", - L"12345678\x0b68" - L"0.com", - kUnsafe}, + {"xn--123456780-71w.com", u"12345678\u0b680.com", kUnsafe}, // 123456789ଠ.com - {"xn--http://123456789-v01b.com", L"http://123456789\x0b20.com", kUnsafe}, + {"xn--123456789-ohw.com", u"123456789\u0b20.com", kUnsafe}, // 123456789ꓳ.com - {"xn--123456789-tx75a.com", L"123456789\xa4f3.com", kUnsafe}, + {"xn--123456789-tx75a.com", u"123456789\ua4f3.com", kUnsafe}, // aeœ.com - {"xn--ae-fsa.com", L"ae\x0153.com", kUnsafe}, + {"xn--ae-fsa.com", u"ae\u0153.com", kUnsafe}, // æce.com - {"xn--ce-0ia.com", - L"\x00e6" - L"ce.com", - kUnsafe}, + {"xn--ce-0ia.com", u"\u00e6ce.com", kUnsafe}, // æœ.com - {"xn--6ca2t.com", L"\x00e6\x0153.com", kUnsafe}, + {"xn--6ca2t.com", u"\u00e6\u0153.com", kUnsafe}, // ӕԥ.com - {"xn--y5a4n.com", L"\x04d5\x0525.com", kUnsafe}, + {"xn--y5a4n.com", u"\u04d5\u0525.com", kUnsafe}, // ငၔဌ၂ဝ.com (entirely made of Myanmar characters) - {"xn--ridq5c9hnd.com", - L"\x1004\x1054\x100c" - L"\x1042\x101d.com", - kUnsafe}, + {"xn--ridq5c9hnd.com", u"\u1004\u1054\u100c\u1042\u101d.com", kUnsafe}, // ฟรฟร.com (made of two Thai characters. similar to wsws.com in // some fonts) - {"xn--w3calb.com", L"\x0e1f\x0e23\x0e1f\x0e23.com", kUnsafe}, + {"xn--w3calb.com", u"\u0e1f\u0e23\u0e1f\u0e23.com", kUnsafe}, // พรบ.com - {"xn--r3chp.com", L"\x0e1e\x0e23\x0e1a.com", kUnsafe}, + {"xn--r3chp.com", u"\u0e1e\u0e23\u0e1a.com", kUnsafe}, // ฟรบ.com - {"xn--r3cjm.com", L"\x0e1f\x0e23\x0e1a.com", kUnsafe}, + {"xn--r3cjm.com", u"\u0e1f\u0e23\u0e1a.com", kUnsafe}, // Lao characters that look like w, s, o, and u. // ພຣບ.com - {"xn--f7chp.com", L"\x0e9e\x0ea3\x0e9a.com", kUnsafe}, + {"xn--f7chp.com", u"\u0e9e\u0ea3\u0e9a.com", kUnsafe}, // ຟຣບ.com - {"xn--f7cjm.com", L"\x0e9f\x0ea3\x0e9a.com", kUnsafe}, + {"xn--f7cjm.com", u"\u0e9f\u0ea3\u0e9a.com", kUnsafe}, // ຟຮບ.com - {"xn--f7cj9b.com", L"\x0e9f\x0eae\x0e9a.com", kUnsafe}, + {"xn--f7cj9b.com", u"\u0e9f\u0eae\u0e9a.com", kUnsafe}, // ຟຮ໐ບ.com - {"xn--f7cj9b5h.com", - L"\x0e9f\x0eae" - L"\x0ed0\x0e9a.com", - kUnsafe}, + {"xn--f7cj9b5h.com", u"\u0e9f\u0eae\u0ed0\u0e9a.com", kUnsafe}, // Lao character that looks like n. // ก11.com - {"xn--11-lqi.com", - L"\x0e01" - L"11.com", - kUnsafe}, + {"xn--11-lqi.com", u"\u0e0111.com", kUnsafe}, // At one point the skeleton of 'w' was 'vv', ensure that // that it's treated as 'w'. - {"xn--wder-qqa.com", - L"w\x00f3" - L"der.com", - kUnsafe}, + {"xn--wder-qqa.com", u"w\u00f3der.com", kUnsafe}, // Mixed digits: the first two will also fail mixed script test // Latin + ASCII digit + Deva digit - {"xn--asc1deva-j0q.co.in", L"asc1deva\x0967.co.in", kUnsafe}, + {"xn--asc1deva-j0q.co.in", u"asc1deva\u0967.co.in", kUnsafe}, // Latin + Deva digit + Beng digit - {"xn--devabeng-f0qu3f.co.in", - L"deva\x0967" - L"beng\x09e7.co.in", - kUnsafe}, + {"xn--devabeng-f0qu3f.co.in", u"deva\u0967beng\u09e7.co.in", kUnsafe}, // ASCII digit + Deva digit - {"xn--79-v5f.co.in", - L"7\x09ea" - L"9.co.in", - kUnsafe}, + {"xn--79-v5f.co.in", u"7\u09ea9.co.in", kUnsafe}, // Deva digit + Beng digit - {"xn--e4b0x.co.in", L"\x0967\x09e7.co.in", kUnsafe}, + {"xn--e4b0x.co.in", u"\u0967\u09e7.co.in", kUnsafe}, // U+4E00 (CJK Ideograph One) is not a digit, but it's not allowed next to // non-Kana scripts including numbers. - {"xn--d12-s18d.cn", L"d12\x4e00.cn", kUnsafe}, + {"xn--d12-s18d.cn", u"d12\u4e00.cn", kUnsafe}, // One that's really long that will force a buffer realloc {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaa", - L"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - L"aaaaaaaa", + u"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + u"aaaaaaaa", kSafe}, // Not allowed; characters outside [:Identifier_Status=Allowed:] // Limited Use Scripts: UTS 31 Table 7. // Vai - {"xn--sn8a.com", L"\xa50b.com", kUnsafe}, + {"xn--sn8a.com", u"\ua50b.com", kUnsafe}, // 'CARD' look-alike in Cherokee - {"xn--58db0a9q.com", L"\x13df\x13aa\x13a1\x13a0.com", kUnsafe}, + {"xn--58db0a9q.com", u"\u13df\u13aa\u13a1\u13a0.com", kUnsafe}, // Scripts excluded from Identifiers: UTS 31 Table 4 // Coptic - {"xn--5ya.com", L"\x03e7.com", kUnsafe}, + {"xn--5ya.com", u"\u03e7.com", kUnsafe}, // Old Italic - {"xn--097cc.com", L"\U00010300\U00010301.com", kUnsafe}, + {"xn--097cc.com", u"\U00010300\U00010301.com", kUnsafe}, // U+115F (Hangul Filler) - {"xn--osd3820f24c.kr", L"\xac00\xb098\x115f.kr", kInvalid}, - {"www.xn--google-ho0coa.com", L"www.\x2039google\x203a.com", kUnsafe}, + {"xn--osd3820f24c.kr", u"\uac00\ub098\u115f.kr", kInvalid}, + {"www.xn--google-ho0coa.com", u"www.\u2039google\u203a.com", kUnsafe}, // Latin small capital w: hardᴡare.com - {"xn--hardare-l41c.com", - L"hard\x1d21" - L"are.com", - kUnsafe}, + {"xn--hardare-l41c.com", u"hard\u1d21are.com", kUnsafe}, // Minus Sign(U+2212) - {"xn--t9g238xc2a.jp", L"\x65e5\x2212\x672c.jp", kUnsafe}, + {"xn--t9g238xc2a.jp", u"\u65e5\u2212\u672c.jp", kUnsafe}, // Latin Small Letter Script G: ɡɡ.com - {"xn--0naa.com", L"\x0261\x0261.com", kUnsafe}, + {"xn--0naa.com", u"\u0261\u0261.com", kUnsafe}, // Hangul Jamo(U+11xx) - {"xn--0pdc3b.com", L"\x1102\x1103\x1110.com", kUnsafe}, + {"xn--0pdc3b.com", u"\u1102\u1103\u1110.com", kUnsafe}, // degree sign: 36°c.com - {"xn--36c-tfa.com", - L"36\x00b0" - L"c.com", - kUnsafe}, + {"xn--36c-tfa.com", u"36\u00b0c.com", kUnsafe}, // Pound sign - {"xn--5free-fga.com", L"5free\x00a3.com", kUnsafe}, + {"xn--5free-fga.com", u"5free\u00a3.com", kUnsafe}, // Hebrew points (U+05B0, U+05B6) - {"xn--7cbl2kc2a.com", L"\x05e1\x05b6\x05e7\x05b0\x05e1.com", kUnsafe}, + {"xn--7cbl2kc2a.com", u"\u05e1\u05b6\u05e7\u05b0\u05e1.com", kUnsafe}, // Danda(U+0964) - {"xn--81bp1b6ch8s.com", L"\x0924\x093f\x091c\x0964\x0930\x0940.com", + {"xn--81bp1b6ch8s.com", u"\u0924\u093f\u091c\u0964\u0930\u0940.com", kUnsafe}, // Small letter script G(U+0261) - {"xn--oogle-qmc.com", L"\x0261oogle.com", kUnsafe}, + {"xn--oogle-qmc.com", u"\u0261oogle.com", kUnsafe}, // Small Katakana Extension(U+31F1) - {"xn--wlk.com", L"\x31f1.com", kUnsafe}, + {"xn--wlk.com", u"\u31f1.com", kUnsafe}, // Heart symbol: ♥ - {"xn--ab-u0x.com", L"ab\x2665.com", kUnsafe}, + {"xn--ab-u0x.com", u"ab\u2665.com", kUnsafe}, // Emoji - {"xn--vi8hiv.xyz", L"\U0001f355\U0001f4a9.xyz", kUnsafe}, + {"xn--vi8hiv.xyz", u"\U0001f355\U0001f4a9.xyz", kUnsafe}, // Registered trade mark - {"xn--egistered-fna.com", - L"\x00ae" - L"egistered.com", - kUnsafe}, + {"xn--egistered-fna.com", u"\u00aeegistered.com", kUnsafe}, // Latin Letter Retroflex Click - {"xn--registered-25c.com", L"registered\x01c3.com", kUnsafe}, + {"xn--registered-25c.com", u"registered\u01c3.com", kUnsafe}, // ASCII '!' not allowed in IDN - {"xn--!-257eu42c.kr", L"\xc548\xb155!.kr", kUnsafe}, + {"xn--!-257eu42c.kr", u"\uc548\ub155!.kr", kUnsafe}, // 'GOOGLE' in IPA extension: ɢᴏᴏɢʟᴇ - {"xn--1naa7pn51hcbaa.com", L"\x0262\x1d0f\x1d0f\x0262\x029f\x1d07.com", + {"xn--1naa7pn51hcbaa.com", u"\u0262\u1d0f\u1d0f\u0262\u029f\u1d07.com", kUnsafe}, // Padlock icon spoof. - {"xn--google-hj64e.com", L"\U0001f512google.com", kUnsafe}, + {"xn--google-hj64e.com", u"\U0001f512google.com", kUnsafe}, - // Custom black list + // Custom block list // Combining Long Solidus Overlay - {"google.xn--comabc-k8d", - L"google.com\x0338" - L"abc", - kUnsafe}, + {"google.xn--comabc-k8d", u"google.com\u0338abc", kUnsafe}, // Hyphenation Point instead of Katakana Middle dot - {"xn--svgy16dha.jp", L"\x30a1\x2027\x30a3.jp", kUnsafe}, + {"xn--svgy16dha.jp", u"\u30a1\u2027\u30a3.jp", kUnsafe}, // Gershayim with other Hebrew characters is allowed. - {"xn--5db6bh9b.il", L"\x05e9\x05d1\x05f4\x05e6.il", kSafe}, + {"xn--5db6bh9b.il", u"\u05e9\u05d1\u05f4\u05e6.il", kSafe}, // Hebrew Gershayim with Latin is invalid according to Python's idna // package. - {"xn--ab-yod.com", - L"a\x05f4" - L"b.com", - kInvalid}, + {"xn--ab-yod.com", u"a\u05f4b.com", kInvalid}, // Hebrew Gershayim with Arabic is disallowed. - {"xn--5eb7h.eg", L"\x0628\x05f4.eg", kUnsafe}, + {"xn--5eb7h.eg", u"\u0628\u05f4.eg", kUnsafe}, #if defined(OS_APPLE) // These characters are blocked due to a font issue on Mac. // Tibetan transliteration characters. - {"xn--com-lum.test.pl", L"com\u0f8c.test.pl", kUnsafe}, + {"xn--com-lum.test.pl", u"com\u0f8c.test.pl", kUnsafe}, // Arabic letter KASHMIRI YEH - {"xn--fgb.com", L"\u0620.com", kUnsafe}, + {"xn--fgb.com", u"\u0620.com", kUnsafe}, #endif // Hyphens (http://unicode.org/cldr/utility/confusables.jsp?a=-) // Hyphen-Minus (the only hyphen allowed) // abc-def - {"abc-def.com", L"abc-def.com", kSafe}, + {"abc-def.com", u"abc-def.com", kSafe}, // Modifier Letter Minus Sign - {"xn--abcdef-5od.com", - L"abc\x02d7" - L"def.com", - kUnsafe}, + {"xn--abcdef-5od.com", u"abc\u02d7def.com", kUnsafe}, // Hyphen - {"xn--abcdef-dg0c.com", - L"abc\x2010" - L"def.com", - kUnsafe}, + {"xn--abcdef-dg0c.com", u"abc\u2010def.com", kUnsafe}, // Non-Breaking Hyphen // This is actually an invalid IDNA domain (U+2011 normalizes to U+2010), // but it is included to ensure that we do not inadvertently allow this // character to be displayed as Unicode. - {"xn--abcdef-kg0c.com", - L"abc\x2011" - L"def.com", - kInvalid}, + {"xn--abcdef-kg0c.com", u"abc\u2011def.com", kInvalid}, // Figure Dash. // Python's idna package refuses to decode the minus signs and dashes. ICU // decodes them but treats them as unsafe in spoof checks, so these test // cases are marked as unsafe instead of invalid. - {"xn--abcdef-rg0c.com", - L"abc\x2012" - L"def.com", - kUnsafe}, + {"xn--abcdef-rg0c.com", u"abc\u2012def.com", kUnsafe}, // En Dash - {"xn--abcdef-yg0c.com", - L"abc\x2013" - L"def.com", - kUnsafe}, + {"xn--abcdef-yg0c.com", u"abc\u2013def.com", kUnsafe}, // Hyphen Bullet - {"xn--abcdef-kq0c.com", - L"abc\x2043" - L"def.com", - kUnsafe}, + {"xn--abcdef-kq0c.com", u"abc\u2043def.com", kUnsafe}, // Minus Sign - {"xn--abcdef-5d3c.com", - L"abc\x2212" - L"def.com", - kUnsafe}, + {"xn--abcdef-5d3c.com", u"abc\u2212def.com", kUnsafe}, // Heavy Minus Sign - {"xn--abcdef-kg1d.com", - L"abc\x2796" - L"def.com", - kUnsafe}, + {"xn--abcdef-kg1d.com", u"abc\u2796def.com", kUnsafe}, // Em Dash // Small Em Dash (U+FE58) is normalized to Em Dash. - {"xn--abcdef-5g0c.com", - L"abc\x2014" - L"def.com", - kUnsafe}, + {"xn--abcdef-5g0c.com", u"abc\u2014def.com", kUnsafe}, // Coptic Small Letter Dialect-P Ni. Looks like dash. // Coptic Capital Letter Dialect-P Ni is normalized to small letter. - {"xn--abcdef-yy8d.com", - L"abc\x2cbb" - L"def.com", - kUnsafe}, + {"xn--abcdef-yy8d.com", u"abc\u2cbbdef.com", kUnsafe}, // Block NV8 (Not valid in IDN 2008) characters. // U+058A (֊) - {"xn--ab-vfd.com", - L"a\x058a" - L"b.com", - kUnsafe}, - {"xn--y9ac3j.com", L"\x0561\x058a\x0562.com", kUnsafe}, + {"xn--ab-vfd.com", u"a\u058ab.com", kUnsafe}, + {"xn--y9ac3j.com", u"\u0561\u058a\u0562.com", kUnsafe}, // U+2019 (’) - {"xn--ab-n2t.com", - L"a\x2019" - L"b.com", - kUnsafe}, + {"xn--ab-n2t.com", u"a\u2019b.com", kUnsafe}, // U+2027 (‧) - {"xn--ab-u3t.com", - L"a\x2027" - L"b.com", - kUnsafe}, + {"xn--ab-u3t.com", u"a\u2027b.com", kUnsafe}, // U+30A0 (゠) - {"xn--ab-bg4a.com", - L"a\x30a0" - L"b.com", - kUnsafe}, - {"xn--9bk3828aea.com", L"\xac00\x30a0\xac01.com", kUnsafe}, - {"xn--9bk279fba.com", L"\x4e00\x30a0\x4e00.com", kUnsafe}, - {"xn--n8jl2x.com", L"\x304a\x30a0\x3044.com", kUnsafe}, - {"xn--fbke7f.com", L"\x3082\x30a0\x3084.com", kUnsafe}, + {"xn--ab-bg4a.com", u"a\u30a0b.com", kUnsafe}, + {"xn--9bk3828aea.com", u"\uac00\u30a0\uac01.com", kUnsafe}, + {"xn--9bk279fba.com", u"\u4e00\u30a0\u4e00.com", kUnsafe}, + {"xn--n8jl2x.com", u"\u304a\u30a0\u3044.com", kUnsafe}, + {"xn--fbke7f.com", u"\u3082\u30a0\u3084.com", kUnsafe}, // Block single/double-quote-like characters. // U+02BB (ʻ) - {"xn--ab-8nb.com", - L"a\x02bb" - L"b.com", - kUnsafe}, + {"xn--ab-8nb.com", u"a\u02bbb.com", kUnsafe}, // U+02BC (ʼ) - {"xn--ab-cob.com", - L"a\x02bc" - L"b.com", - kUnsafe}, + {"xn--ab-cob.com", u"a\u02bcb.com", kUnsafe}, // U+144A: Not allowed to mix with scripts other than Canadian Syllabics. - {"xn--ab-jom.com", - L"a\x144a" - L"b.com", - kUnsafe}, - {"xn--xcec9s.com", L"\x1401\x144a\x1402.com", kUnsafe}, + {"xn--ab-jom.com", u"a\u144ab.com", kUnsafe}, + {"xn--xcec9s.com", u"\u1401\u144a\u1402.com", kUnsafe}, // Custom dangerous patterns // Two Katakana-Hiragana combining mark in a row - {"google.xn--com-oh4ba.evil.jp", L"google.com\x309a\x309a.evil.jp", + {"google.xn--com-oh4ba.evil.jp", u"google.com\u309a\u309a.evil.jp", kUnsafe}, // Katakana Letter No not enclosed by {Han,Hiragana,Katakana}. - {"google.xn--comevil-v04f.jp", - L"google.com\x30ce" - L"evil.jp", - kUnsafe}, + {"google.xn--comevil-v04f.jp", u"google.com\u30ceevil.jp", kUnsafe}, // TODO(jshin): Review the danger of allowing the following two. // Hiragana 'No' by itself is allowed. - {"xn--ldk.jp", L"\x30ce.jp", kSafe}, + {"xn--ldk.jp", u"\u30ce.jp", kSafe}, // Hebrew Gershayim used by itself is allowed. - {"xn--5eb.il", L"\x05f4.il", kSafe}, + {"xn--5eb.il", u"\u05f4.il", kSafe}, // Block RTL nonspacing marks (NSM) after unrelated scripts. - {"xn--foog-ycg.com", L"foog\x0650.com", kUnsafe}, // Latin + Arabic NSM - {"xn--foog-jdg.com", L"foog\x0654.com", kUnsafe}, // Latin + Arabic NSM - {"xn--foog-jhg.com", L"foog\x0670.com", kUnsafe}, // Latin + Arbic NSM - {"xn--foog-opf.com", L"foog\x05b4.com", kUnsafe}, // Latin + Hebrew NSM - {"xn--shb5495f.com", L"\xac00\x0650.com", kUnsafe}, // Hang + Arabic NSM + {"xn--foog-ycg.com", u"foog\u0650.com", kUnsafe}, // Latin + Arabic NSM + {"xn--foog-jdg.com", u"foog\u0654.com", kUnsafe}, // Latin + Arabic NSM + {"xn--foog-jhg.com", u"foog\u0670.com", kUnsafe}, // Latin + Arbic NSM + {"xn--foog-opf.com", u"foog\u05b4.com", kUnsafe}, // Latin + Hebrew NSM + {"xn--shb5495f.com", u"\uac00\u0650.com", kUnsafe}, // Hang + Arabic NSM // 4 Deviation characters between IDNA 2003 and IDNA 2008 // When entered in Unicode, the first two are mapped to 'ss' and Greek sigma // and the latter two are mapped away. However, the punycode form should // remain in punycode. // U+00DF(sharp-s) - {"xn--fu-hia.de", L"fu\x00df.de", kUnsafe}, + {"xn--fu-hia.de", u"fu\u00df.de", kUnsafe}, // U+03C2(final-sigma) - {"xn--mxac2c.gr", L"\x03b1\x03b2\x03c2.gr", kUnsafe}, + {"xn--mxac2c.gr", u"\u03b1\u03b2\u03c2.gr", kUnsafe}, // U+200C(ZWNJ) - {"xn--h2by8byc123p.in", L"\x0924\x094d\x200c\x0930\x093f.in", kUnsafe}, + {"xn--h2by8byc123p.in", u"\u0924\u094d\u200c\u0930\u093f.in", kUnsafe}, // U+200C(ZWJ) - {"xn--11b6iy14e.in", L"\x0915\x094d\x200d.in", kUnsafe}, + {"xn--11b6iy14e.in", u"\u0915\u094d\u200d.in", kUnsafe}, // Math Monospace Small A. When entered in Unicode, it's canonicalized to // 'a'. The punycode form should remain in punycode. - {"xn--bc-9x80a.xyz", - L"\U0001d68a" - L"bc.xyz", - kInvalid}, + {"xn--bc-9x80a.xyz", u"\U0001d68abc.xyz", kInvalid}, // Math Sans Bold Capital Alpha - {"xn--bc-rg90a.xyz", - L"\U0001d756" - L"bc.xyz", - kInvalid}, + {"xn--bc-rg90a.xyz", u"\U0001d756bc.xyz", kInvalid}, // U+3000 is canonicalized to a space(U+0020), but the punycode form // should remain in punycode. - {"xn--p6j412gn7f.cn", L"\x4e2d\x56fd\x3000", kInvalid}, + {"xn--p6j412gn7f.cn", u"\u4e2d\u56fd\u3000", kInvalid}, // U+3002 is canonicalized to ASCII fullstop(U+002E), but the punycode form // should remain in punycode. - {"xn--r6j012gn7f.cn", L"\x4e2d\x56fd\x3002", kInvalid}, + {"xn--r6j012gn7f.cn", u"\u4e2d\u56fd\u3002", kInvalid}, // Invalid punycode // Has a codepoint beyond U+10FFFF. {"xn--krank-kg706554a", nullptr, kInvalid}, @@ -1057,226 +851,244 @@ // Not allowed in UTS46/IDNA 2008 // Georgian Capital Letter(U+10BD) - {"xn--1nd.com", L"\x10bd.com", kInvalid}, + {"xn--1nd.com", u"\u10bd.com", kInvalid}, // 3rd and 4th characters are '-'. - {"xn-----8kci4dhsd", L"\x0440\x0443--\x0430\x0432\x0442\x043e", kInvalid}, + {"xn-----8kci4dhsd", u"\u0440\u0443--\u0430\u0432\u0442\u043e", kInvalid}, // Leading combining mark - {"xn--72b.com", L"\x093e.com", kInvalid}, + {"xn--72b.com", u"\u093e.com", kInvalid}, // BiDi check per IDNA 2008/UTS 46 // Cannot starts with AN(Arabic-Indic Number) - {"xn--8hbae.eg", L"\x0662\x0660\x0660.eg", kInvalid}, + {"xn--8hbae.eg", u"\u0662\u0660\u0660.eg", kInvalid}, // Cannot start with a RTL character and ends with a LTR - {"xn--x-ymcov.eg", L"\x062c\x0627\x0631x.eg", kInvalid}, + {"xn--x-ymcov.eg", u"\u062c\u0627\u0631x.eg", kInvalid}, // Can start with a RTL character and ends with EN(European Number) - {"xn--2-ymcov.eg", - L"\x062c\x0627\x0631" - L"2.eg", - kSafe}, + {"xn--2-ymcov.eg", u"\u062c\u0627\u06312.eg", kSafe}, // Can start with a RTL and end with AN - {"xn--mgbjq0r.eg", L"\x062c\x0627\x0631\x0662.eg", kSafe}, + {"xn--mgbjq0r.eg", u"\u062c\u0627\u0631\u0662.eg", kSafe}, // Extremely rare Latin letters // Latin Ext B - Pinyin: ǔnion.com - {"xn--nion-unb.com", L"\x01d4nion.com", kUnsafe}, + {"xn--nion-unb.com", u"\u01d4nion.com", kUnsafe}, // Latin Ext C: ⱴase.com - {"xn--ase-7z0b.com", - L"\x2c74" - L"ase.com", - kUnsafe}, + {"xn--ase-7z0b.com", u"\u2c74ase.com", kUnsafe}, // Latin Ext D: ꝴode.com - {"xn--ode-ut3l.com", L"\xa774ode.com", kUnsafe}, + {"xn--ode-ut3l.com", u"\ua774ode.com", kUnsafe}, // Latin Ext Additional: ḷily.com - {"xn--ily-n3y.com", L"\x1e37ily.com", kUnsafe}, + {"xn--ily-n3y.com", u"\u1e37ily.com", kUnsafe}, // Latin Ext E: ꬺove.com - {"xn--ove-8y6l.com", L"\xab3aove.com", kUnsafe}, + {"xn--ove-8y6l.com", u"\uab3aove.com", kUnsafe}, // Greek Ext: ᾳβγ.com - {"xn--nxac616s.com", L"\x1fb3\x03b2\x03b3.com", kInvalid}, + {"xn--nxac616s.com", u"\u1fb3\u03b2\u03b3.com", kInvalid}, // Cyrillic Ext A (label cannot begin with an illegal combining character). - {"xn--lrj.com", L"\x2def.com", kInvalid}, + {"xn--lrj.com", u"\u2def.com", kInvalid}, // Cyrillic Ext B: ꙡ.com - {"xn--kx8a.com", L"\xa661.com", kUnsafe}, + {"xn--kx8a.com", u"\ua661.com", kUnsafe}, // Cyrillic Ext C: ᲂ.com (Narrow o) - {"xn--43f.com", L"\x1c82.com", kInvalid}, + {"xn--43f.com", u"\u1c82.com", kInvalid}, // The skeleton of Extended Arabic-Indic Digit Zero (۰) is a dot. Check that // this is handled correctly (crbug/877045). - {"xn--dmb", L"\x06f0", kSafe}, + {"xn--dmb", u"\u06f0", kSafe}, // Test that top domains whose skeletons are the same as the domain name are // handled properly. In this case, tést.net should match test.net top // domain and not be converted to unicode. - {"xn--tst-bma.net", L"t\x00e9st.net", kUnsafe}, + {"xn--tst-bma.net", u"t\u00e9st.net", kUnsafe}, // Variations of the above, for testing crbug.com/925199. // some.tést.net should match test.net. - {"some.xn--tst-bma.net", L"some.t\x00e9st.net", kUnsafe}, + {"some.xn--tst-bma.net", u"some.t\u00e9st.net", kUnsafe}, // The following should not match test.net, so should be converted to // unicode. // ést.net (a suffix of tést.net). - {"xn--st-9ia.net", L"\x00e9st.net", kSafe}, + {"xn--st-9ia.net", u"\u00e9st.net", kSafe}, // some.ést.net - {"some.xn--st-9ia.net", L"some.\x00e9st.net", kSafe}, + {"some.xn--st-9ia.net", u"some.\u00e9st.net", kSafe}, // atést.net (tést.net is a suffix of atést.net) - {"xn--atst-cpa.net", L"at\x00e9st.net", kSafe}, + {"xn--atst-cpa.net", u"at\u00e9st.net", kSafe}, // some.atést.net - {"some.xn--atst-cpa.net", L"some.at\x00e9st.net", kSafe}, + {"some.xn--atst-cpa.net", u"some.at\u00e9st.net", kSafe}, // Modifier-letter-voicing should be blocked (wwwˬtest.com). - {"xn--wwwtest-2be.com", L"www\x02ectest.com", kUnsafe}, + {"xn--wwwtest-2be.com", u"www\u02ectest.com", kUnsafe}, // oĸ.com: Not a top domain, should be blocked because of Kra. - {"xn--o-tka.com", L"o\x0138.com", kUnsafe}, + {"xn--o-tka.com", u"o\u0138.com", kUnsafe}, // U+4E00 and U+3127 should be blocked when next to non-CJK. - {"xn--ipaddress-w75n.com", L"ip一address.com", kUnsafe}, - {"xn--ipaddress-wx5h.com", L"ipㄧaddress.com", kUnsafe}, - // U+4E00 at the beginning and end of a string. - {"xn--google-gg5e.com", L"googleㄧ.com", kUnsafe}, - {"xn--google-9f5e.com", L"ㄧgoogle.com", kUnsafe}, - // These are allowed because 一 is not immediately next to non-CJK. - {"xn--gamer-fg1hz05u.com", L"一生gamer.com", kSafe}, - {"xn--gamer-kg1hy05u.com", L"gamer生一.com", kSafe}, - {"xn--4gqz91g.com", L"一猫.com", kSafe}, - {"xn--4fkv10r.com", L"ㄧ猫.com", kSafe}, + {"xn--ipaddress-w75n.com", u"ip\u4e00address.com", kUnsafe}, + {"xn--ipaddress-wx5h.com", u"ip\u3127address.com", kUnsafe}, + // U+4E00 and U+3127 at the beginning and end of a string. + {"xn--google-gg5e.com", u"google\u3127.com", kUnsafe}, + {"xn--google-9f5e.com", u"\u3127google.com", kUnsafe}, + {"xn--google-gn7i.com", u"google\u4e00.com", kUnsafe}, + {"xn--google-9m7i.com", u"\u4e00google.com", kUnsafe}, + // These are allowed because U+4E00 and U+3127 are not immediately next to + // non-CJK. + {"xn--gamer-fg1hz05u.com", u"\u4e00\u751fgamer.com", kSafe}, + {"xn--gamer-kg1hy05u.com", u"gamer\u751f\u4e00.com", kSafe}, + {"xn--gamer-f94d4426b.com", u"\u3127\u751fgamer.com", kSafe}, + {"xn--gamer-k94d3426b.com", u"gamer\u751f\u3127.com", kSafe}, + {"xn--4gqz91g.com", u"\u4e00\u732b.com", kSafe}, + {"xn--4fkv10r.com", u"\u3127\u732b.com", kSafe}, // U+4E00 with another ideograph. - {"xn--4gqc.com", L"一丁.com", kSafe}, + {"xn--4gqc.com", u"\u4e00\u4e01.com", kSafe}, // CJK ideographs looking like slashes should be blocked when next to // non-CJK. - {"example.xn--comtest-k63k", L"example.com丶test", kUnsafe}, - {"example.xn--comtest-u83k", L"example.com乀test", kUnsafe}, - {"example.xn--comtest-283k", L"example.com乁test", kUnsafe}, - {"example.xn--comtest-m83k", L"example.com丿test", kUnsafe}, + {"example.xn--comtest-k63k", u"example.com\u4e36test", kUnsafe}, + {"example.xn--comtest-u83k", u"example.com\u4e40test", kUnsafe}, + {"example.xn--comtest-283k", u"example.com\u4e41test", kUnsafe}, + {"example.xn--comtest-m83k", u"example.com\u4e3ftest", kUnsafe}, // This is allowed because the ideographs are not immediately next to // non-CJK. - {"xn--oiqsace.com", L"丶乀乁丿.com", kSafe}, + {"xn--oiqsace.com", u"\u4e36\u4e40\u4e41\u4e3f.com", kSafe}, // Kana voiced sound marks are not allowed. - {"xn--google-1m4e.com", L"google\x3099.com", kUnsafe}, - {"xn--google-8m4e.com", L"google\x309A.com", kUnsafe}, + {"xn--google-1m4e.com", u"google\u3099.com", kUnsafe}, + {"xn--google-8m4e.com", u"google\u309A.com", kUnsafe}, // Small letter theta looks like a zero. - {"xn--123456789-yzg.com", L"123456789θ.com", kUnsafe}, + {"xn--123456789-yzg.com", u"123456789\u03b8.com", kUnsafe}, - {"xn--est-118d.net", L"七est.net", kUnsafe}, - {"xn--est-918d.net", L"丅est.net", kUnsafe}, - {"xn--est-e28d.net", L"丆est.net", kUnsafe}, - {"xn--est-t18d.net", L"丁est.net", kUnsafe}, - {"xn--3-cq6a.com", L"丩3.com", kUnsafe}, - {"xn--cxe-n68d.com", L"c丫xe.com", kUnsafe}, - {"xn--cye-b98d.com", L"cy乂e.com", kUnsafe}, + {"xn--est-118d.net", u"\u4e03est.net", kUnsafe}, + {"xn--est-918d.net", u"\u4e05est.net", kUnsafe}, + {"xn--est-e28d.net", u"\u4e06est.net", kUnsafe}, + {"xn--est-t18d.net", u"\u4e01est.net", kUnsafe}, + {"xn--3-cq6a.com", u"\u4e293.com", kUnsafe}, + {"xn--cxe-n68d.com", u"c\u4e2bxe.com", kUnsafe}, + {"xn--cye-b98d.com", u"cy\u4e42e.com", kUnsafe}, // U+05D7 can look like Latin n in many fonts. - {"xn--ceba.com", L"חח.com", kUnsafe}, + {"xn--ceba.com", u"\u05d7\u05d7.com", kUnsafe}, // U+00FE (þ) and U+00F0 (ð) are only allowed under the .is TLD. - {"xn--acdef-wva.com", L"aþcdef.com", kUnsafe}, - {"xn--mnpqr-jta.com", L"mnðpqr.com", kUnsafe}, - {"xn--acdef-wva.is", L"aþcdef.is", kSafe}, - {"xn--mnpqr-jta.is", L"mnðpqr.is", kSafe}, + {"xn--acdef-wva.com", u"a\u00fecdef.com", kUnsafe}, + {"xn--mnpqr-jta.com", u"mn\u00f0pqr.com", kUnsafe}, + {"xn--acdef-wva.is", u"a\u00fecdef.is", kSafe}, + {"xn--mnpqr-jta.is", u"mn\u00f0pqr.is", kSafe}, // U+0259 (ə) is only allowed under the .az TLD. - {"xn--xample-vyc.com", L"əxample.com", kUnsafe}, - {"xn--xample-vyc.az", L"əxample.az", kSafe}, + {"xn--xample-vyc.com", u"\u0259xample.com", kUnsafe}, + {"xn--xample-vyc.az", u"\u0259xample.az", kSafe}, // U+00B7 is only allowed on Catalan domains between two l's. - {"xn--googlecom-5pa.com", L"google·com.com", kUnsafe}, - {"xn--ll-0ea.com", L"l·l.com", kUnsafe}, - {"xn--ll-0ea.cat", L"l·l.cat", kSafe}, - {"xn--al-0ea.cat", L"a·l.cat", kUnsafe}, - {"xn--la-0ea.cat", L"l·a.cat", kUnsafe}, - {"xn--l-fda.cat", L"·l.cat", kUnsafe}, - {"xn--l-gda.cat", L"l·.cat", kUnsafe}, + {"xn--googlecom-5pa.com", u"google\u00b7com.com", kUnsafe}, + {"xn--ll-0ea.com", u"l\u00b7l.com", kUnsafe}, + {"xn--ll-0ea.cat", u"l\u00b7l.cat", kSafe}, + {"xn--al-0ea.cat", u"a\u00b7l.cat", kUnsafe}, + {"xn--la-0ea.cat", u"l\u00b7a.cat", kUnsafe}, + {"xn--l-fda.cat", u"\u00b7l.cat", kUnsafe}, + {"xn--l-gda.cat", u"l\u00b7.cat", kUnsafe}, - {"xn--googlecom-gk6n.com", L"google丨com.com", kUnsafe}, // (U+4E28) - {"xn--googlecom-0y6n.com", L"google乛com.com", kUnsafe}, // (U+4E5B) - {"xn--googlecom-v85n.com", L"google七com.com", kUnsafe}, // (U+4E03) - {"xn--googlecom-g95n.com", L"google丅com.com", kUnsafe}, // (U+4E05) - {"xn--googlecom-go6n.com", L"google丶com.com", kUnsafe}, // (U+4E36) - {"xn--googlecom-b76o.com", L"google十com.com", kUnsafe}, // (U+5341) - {"xn--googlecom-ql3h.com", L"google〇com.com", kUnsafe}, // (U+3007) - {"xn--googlecom-0r5h.com", L"googleㄒcom.com", kUnsafe}, // (U+3112) - {"xn--googlecom-bu5h.com", L"googleㄚcom.com", kUnsafe}, // (U+311A) - {"xn--googlecom-qv5h.com", L"googleㄟcom.com", kUnsafe}, // (U+311F) - {"xn--googlecom-0x5h.com", L"googleㄧcom.com", kUnsafe}, // (U+3127) - {"xn--googlecom-by5h.com", L"googleㄨcom.com", kUnsafe}, // (U+3128) - {"xn--googlecom-ly5h.com", L"googleㄩcom.com", kUnsafe}, // (U+3129) - {"xn--googlecom-5o5h.com", L"googleㄈcom.com", kUnsafe}, // (U+3108) - {"xn--googlecom-075n.com", L"google一com.com", kUnsafe}, // (U+4E00) - {"xn--googlecom-046h.com", L"googleㆺcom.com", kUnsafe}, // (U+31BA) - {"xn--googlecom-026h.com", L"googleㆳcom.com", kUnsafe}, // (U+31B3) - {"xn--googlecom-lg9q.com", L"google工com.com", kUnsafe}, // (U+5DE5) - {"xn--googlecom-g040a.com", L"google讠com.com", kUnsafe}, // (U+8BA0) - {"xn--googlecom-b85n.com", L"google丁com.com", kUnsafe}, // (U+4E01) + {"xn--googlecom-gk6n.com", u"google\u4e28com.com", kUnsafe}, + {"xn--googlecom-0y6n.com", u"google\u4e5bcom.com", kUnsafe}, + {"xn--googlecom-v85n.com", u"google\u4e03com.com", kUnsafe}, + {"xn--googlecom-g95n.com", u"google\u4e05com.com", kUnsafe}, + {"xn--googlecom-go6n.com", u"google\u4e36com.com", kUnsafe}, + {"xn--googlecom-b76o.com", u"google\u5341com.com", kUnsafe}, + {"xn--googlecom-ql3h.com", u"google\u3007com.com", kUnsafe}, + {"xn--googlecom-0r5h.com", u"google\u3112com.com", kUnsafe}, + {"xn--googlecom-bu5h.com", u"google\u311acom.com", kUnsafe}, + {"xn--googlecom-qv5h.com", u"google\u311fcom.com", kUnsafe}, + {"xn--googlecom-0x5h.com", u"google\u3127com.com", kUnsafe}, + {"xn--googlecom-by5h.com", u"google\u3128com.com", kUnsafe}, + {"xn--googlecom-ly5h.com", u"google\u3129com.com", kUnsafe}, + {"xn--googlecom-5o5h.com", u"google\u3108com.com", kUnsafe}, + {"xn--googlecom-075n.com", u"google\u4e00com.com", kUnsafe}, + {"xn--googlecom-046h.com", u"google\u31bacom.com", kUnsafe}, + {"xn--googlecom-026h.com", u"google\u31b3com.com", kUnsafe}, + {"xn--googlecom-lg9q.com", u"google\u5de5com.com", kUnsafe}, + {"xn--googlecom-g040a.com", u"google\u8ba0com.com", kUnsafe}, + {"xn--googlecom-b85n.com", u"google\u4e01com.com", kUnsafe}, // Whole-script-confusables. Cyrillic is sufficiently handled in cases above // so it's not included here. // Armenian: - {"xn--mbbkpm.com", L"ոսւօ.com", kUnsafe}, - {"xn--mbbkpm.am", L"ոսւօ.am", kSafe}, - {"xn--mbbkpm.xn--y9a3aq", L"ոսւօ.հայ", kSafe}, + {"xn--mbbkpm.com", u"\u0578\u057d\u0582\u0585.com", kUnsafe}, + {"xn--mbbkpm.am", u"\u0578\u057d\u0582\u0585.am", kSafe}, + {"xn--mbbkpm.xn--y9a3aq", u"\u0578\u057d\u0582\u0585.\u0570\u0561\u0575", + kSafe}, // Ethiopic: - {"xn--6xd66aa62c.com", L"ሠዐዐፐ.com", kUnsafe}, - {"xn--6xd66aa62c.et", L"ሠዐዐፐ.et", kSafe}, - {"xn--6xd66aa62c.xn--m0d3gwjla96a", L"ሠዐዐፐ.ኢትዮጵያ", kSafe}, + {"xn--6xd66aa62c.com", u"\u1220\u12d0\u12d0\u1350.com", kUnsafe}, + {"xn--6xd66aa62c.et", u"\u1220\u12d0\u12d0\u1350.et", kSafe}, + {"xn--6xd66aa62c.xn--m0d3gwjla96a", + u"\u1220\u12d0\u12d0\u1350.\u12a2\u1275\u12ee\u1335\u12eb", kSafe}, // Greek: - {"xn--mxapd.com", L"ικα.com", kUnsafe}, - {"xn--mxapd.gr", L"ικα.gr", kSafe}, - {"xn--mxapd.xn--qxam", L"ικα.ελ", kSafe}, + {"xn--mxapd.com", u"\u03b9\u03ba\u03b1.com", kUnsafe}, + {"xn--mxapd.gr", u"\u03b9\u03ba\u03b1.gr", kSafe}, + {"xn--mxapd.xn--qxam", u"\u03b9\u03ba\u03b1.\u03b5\u03bb", kSafe}, // Georgian: - {"xn--gpd3ag.com", L"ჽჿხ.com", kUnsafe}, - {"xn--gpd3ag.ge", L"ჽჿხ.ge", kSafe}, - {"xn--gpd3ag.xn--node", L"ჽჿხ.გე", kSafe}, + {"xn--gpd3ag.com", u"\u10fd\u10ff\u10ee.com", kUnsafe}, + {"xn--gpd3ag.ge", u"\u10fd\u10ff\u10ee.ge", kSafe}, + {"xn--gpd3ag.xn--node", u"\u10fd\u10ff\u10ee.\u10d2\u10d4", kSafe}, // Hebrew: - {"xn--7dbh4a.com", L"חסד.com", kUnsafe}, - {"xn--7dbh4a.il", L"חסד.il", kSafe}, - {"xn--9dbq2a.xn--7dbh4a", L"קום.חסד", kSafe}, + {"xn--7dbh4a.com", u"\u05d7\u05e1\u05d3.com", kUnsafe}, + {"xn--7dbh4a.il", u"\u05d7\u05e1\u05d3.il", kSafe}, + {"xn--9dbq2a.xn--7dbh4a", u"\u05e7\u05d5\u05dd.\u05d7\u05e1\u05d3", kSafe}, // Myanmar: - {"xn--oidbbf41a.com", L"င၀ဂခဂ.com", kUnsafe}, - {"xn--oidbbf41a.mm", L"င၀ဂခဂ.mm", kSafe}, - {"xn--oidbbf41a.xn--7idjb0f4ck", L"င၀ဂခဂ.မြန်မာ", kSafe}, + {"xn--oidbbf41a.com", u"\u1004\u1040\u1002\u1001\u1002.com", kUnsafe}, + {"xn--oidbbf41a.mm", u"\u1004\u1040\u1002\u1001\u1002.mm", kSafe}, + {"xn--oidbbf41a.xn--7idjb0f4ck", + u"\u1004\u1040\u1002\u1001\u1002.\u1019\u103c\u1014\u103a\u1019\u102c", + kSafe}, // Myanmar Shan digits: - {"xn--rmdcmef.com", L"႐႑႕႖႗.com", kUnsafe}, - {"xn--rmdcmef.mm", L"႐႑႕႖႗.mm", kSafe}, - {"xn--rmdcmef.xn--7idjb0f4ck", L"႐႑႕႖႗.မြန်မာ", kSafe}, + {"xn--rmdcmef.com", u"\u1090\u1091\u1095\u1096\u1097.com", kUnsafe}, + {"xn--rmdcmef.mm", u"\u1090\u1091\u1095\u1096\u1097.mm", kSafe}, + {"xn--rmdcmef.xn--7idjb0f4ck", + u"\u1090\u1091\u1095\u1096\u1097.\u1019\u103c\u1014\u103a\u1019\u102c", + kSafe}, // Thai: #if defined(OS_LINUX) || defined(OS_CHROMEOS) - {"xn--o3cedqz2c.com", L"ทนบพรห.com", kUnsafe}, - {"xn--o3cedqz2c.th", L"ทนบพรห.th", kSafe}, - {"xn--o3cedqz2c.xn--o3cw4h", L"ทนบพรห.ไทย", kSafe}, + {"xn--o3cedqz2c.com", u"\u0e17\u0e19\u0e1a\u0e1e\u0e23\u0e2b.com", kUnsafe}, + {"xn--o3cedqz2c.th", u"\u0e17\u0e19\u0e1a\u0e1e\u0e23\u0e2b.th", kSafe}, + {"xn--o3cedqz2c.xn--o3cw4h", + u"\u0e17\u0e19\u0e1a\u0e1e\u0e23\u0e2b.\u0e44\u0e17\u0e22", kSafe}, #else - {"xn--r3ch7hsc.com", L"พบเ๐.com", kUnsafe}, - {"xn--r3ch7hsc.th", L"พบเ๐.th", kSafe}, - {"xn--r3ch7hsc.xn--o3cw4h", L"พบเ๐.ไทย", kSafe}, + {"xn--r3ch7hsc.com", u"\u0e1e\u0e1a\u0e40\u0e50.com", kUnsafe}, + {"xn--r3ch7hsc.th", u"\u0e1e\u0e1a\u0e40\u0e50.th", kSafe}, + {"xn--r3ch7hsc.xn--o3cw4h", u"\u0e1e\u0e1a\u0e40\u0e50.\u0e44\u0e17\u0e22", + kSafe}, #endif // Indic scripts: // Bengali: - {"xn--07baub.com", L"০৭০৭.com", kUnsafe}, + {"xn--07baub.com", u"\u09e6\u09ed\u09e6\u09ed.com", kUnsafe}, // Devanagari: - {"xn--62ba6j.com", L"ऽ०ऽ.com", kUnsafe}, + {"xn--62ba6j.com", u"\u093d\u0966\u093d.com", kUnsafe}, // Gujarati: - {"xn--becd.com", L"ડટ.com", kUnsafe}, + {"xn--becd.com", u"\u0aa1\u0a9f.com", kUnsafe}, // Gurmukhi: - {"xn--occacb.com", L"੦੧੦੧.com", kUnsafe}, + {"xn--occacb.com", u"\u0a66\u0a67\u0a66\u0a67.com", kUnsafe}, // Kannada: - {"xn--stca6jf.com", L"ಽ೦ಽ೧.com", kUnsafe}, + {"xn--stca6jf.com", u"\u0cbd\u0ce6\u0cbd\u0ce7.com", kUnsafe}, // Malayalam: - {"xn--lwccv.com", L"ടഠധ.com", kUnsafe}, + {"xn--lwccv.com", u"\u0d1f\u0d20\u0d27.com", kUnsafe}, // Oriya: - {"xn--zhca6ub.com", L"୮ଠ୮ଠ.com", kUnsafe}, + {"xn--zhca6ub.com", u"\u0b6e\u0b20\u0b6e\u0b20.com", kUnsafe}, // Tamil: - {"xn--mlca6ab.com", L"டபடப.com", kUnsafe}, + {"xn--mlca6ab.com", u"\u0b9f\u0baa\u0b9f\u0baa.com", kUnsafe}, // Telugu: - {"xn--brcaabbb.com", L"౧౦౧౦౧౦.com", kUnsafe}, + {"xn--brcaabbb.com", u"\u0c67\u0c66\u0c67\u0c66\u0c67\u0c66.com", kUnsafe}, - // IDN domain matching an IDN top-domain (fóó.com) - {"xn--fo-5ja.com", L"fóo.com", kUnsafe}, + // IDN domain matching an IDN top-domain (f\u00f3\u00f3.com) + {"xn--fo-5ja.com", u"f\u00f3o.com", kUnsafe}, // crbug.com/769547: Subdomains of top domains should be allowed. - {"xn--xample-9ua.test.net", L"éxample.test.net", kSafe}, + {"xn--xample-9ua.test.net", u"\u00e9xample.test.net", kSafe}, // Skeleton of the eTLD+1 matches a top domain, but the eTLD+1 itself is // not a top domain. Should not be decoded to unicode. - {"xn--xample-9ua.test.xn--nt-bja", L"éxample.test.nét", kUnsafe}, + {"xn--xample-9ua.test.xn--nt-bja", u"\u00e9xample.test.n\u00e9t", kUnsafe}, + + // New test cases go ↑↑ above. + + // /!\ WARNING: You MUST use tools/security/idn_test_case_generator.py to + // generate new test cases, as specified by the comment at the top of this + // test list. Why must you use that python script? + // 1. It is easy to get things wrong. There were several hand-crafted + // incorrect test cases committed that was later fixed. + // 2. This test _also_ is a test of Chromium's IDN encoder/decoder, so using + // Chromium's IDN encoder/decoder to generate test files loses an + // advantage of having Python's IDN encode/decode the tests. }; namespace test { @@ -1313,13 +1125,16 @@ // used in a domain name. TEST_F(IDNSpoofCheckerTest, IDNToUnicode) { for (size_t i = 0; i < base::size(kIdnCases); i++) { + SCOPED_TRACE( + base::StringPrintf("input #%zu: \"%s\"", i, kIdnCases[i].input)); + // Sanity check to ensure that the unicode output matches the input. Bypass // all spoof checks by doing an unsafe conversion. const IDNConversionResult unsafe_result = UnsafeIDNToUnicodeWithDetails(kIdnCases[i].input); // Ignore inputs that can't be converted even with unsafe conversion because - // they contain certain characters not allowed in IDNs. E.g. U+24df (Latin + // they contain certain characters not allowed in IDNs. E.g. U+24DF (Latin // CIRCLED LATIN SMALL LETTER P) in hostname causes the conversion to fail // before reaching spoof checks. if (kIdnCases[i].expected_result != kInvalid) { @@ -1327,42 +1142,40 @@ // as ѕсоре-рау.한국 where scope-pay is a Cyrillic whole-script // confusable but 한국 is safe. This would require adding yet another // field to the the test struct. - if (!IsPunycode(WideToUTF16(kIdnCases[i].unicode_output))) { - ASSERT_EQ(unsafe_result.result, - WideToUTF16(kIdnCases[i].unicode_output)); + if (!IsPunycode(kIdnCases[i].unicode_output)) { + EXPECT_EQ(unsafe_result.result, kIdnCases[i].unicode_output); } } else { // Invalid punycode should not be converted. - ASSERT_EQ(unsafe_result.result, ASCIIToUTF16(kIdnCases[i].input)); + EXPECT_EQ(unsafe_result.result, base::ASCIIToUTF16(kIdnCases[i].input)); } const std::u16string output(IDNToUnicode(kIdnCases[i].input)); const std::u16string expected(kIdnCases[i].expected_result == kSafe - ? WideToUTF16(kIdnCases[i].unicode_output) - : ASCIIToUTF16(kIdnCases[i].input)); - EXPECT_EQ(expected, output) - << "input # " << i << ": \"" << kIdnCases[i].input << "\""; + ? kIdnCases[i].unicode_output + : base::ASCIIToUTF16(kIdnCases[i].input)); + EXPECT_EQ(expected, output); } } TEST_F(IDNSpoofCheckerTest, GetSimilarTopDomain) { struct TestCase { - const wchar_t* const hostname; + const char16_t* const hostname; const char* const expected_top_domain; } kTestCases[] = { - {L"tést.net", "test.net"}, - {L"subdomain.tést.net", "test.net"}, + {u"tést.net", "test.net"}, + {u"subdomain.tést.net", "test.net"}, // A top domain should not return a similar top domain result. - {L"test.net", ""}, + {u"test.net", ""}, // A subdomain of a top domain should not return a similar top domain // result. - {L"subdomain.test.net", ""}, + {u"subdomain.test.net", ""}, // An IDN subdomain of a top domain should not return a similar top domain // result. - {L"subdómain.test.net", ""}}; + {u"subdómain.test.net", ""}}; for (const TestCase& test_case : kTestCases) { - const TopDomainEntry entry = IDNSpoofChecker().GetSimilarTopDomain( - base::WideToUTF16(test_case.hostname)); + const TopDomainEntry entry = + IDNSpoofChecker().GetSimilarTopDomain(test_case.hostname); EXPECT_EQ(test_case.expected_top_domain, entry.domain); EXPECT_FALSE(entry.is_top_500); } @@ -1426,7 +1239,7 @@ // The IDNA/Punycode version of the domain (plain ASCII). const char* const punycode; // The equivalent Unicode version of the domain, if converted. - const wchar_t* const expected_unicode; + const char16_t* const expected_unicode; // Whether the input (punycode) has idn. const bool expected_has_idn; // The top domain that |punycode| matched to, if any. @@ -1436,35 +1249,35 @@ const IDNSpoofChecker::Result expected_spoof_check_result; } kTestCases[] = { {// An ASCII, top domain. - "google.com", L"google.com", false, + "google.com", u"google.com", false, // Since it's not unicode, we won't attempt to match it to a top domain. "", // ...And since we don't match it to a top domain, we don't know if it's // a top 500 domain. false, IDNSpoofChecker::Result::kNone}, {// An ASCII domain that's not a top domain. - "not-top-domain.com", L"not-top-domain.com", false, "", false, + "not-top-domain.com", u"not-top-domain.com", false, "", false, IDNSpoofChecker::Result::kNone}, {// A unicode domain that's valid according to all of the rules in IDN // spoof checker except that it matches a top domain. Should be // converted to punycode. Spoof check result is kSafe because top domain // similarity isn't included in IDNSpoofChecker::Result. - "xn--googl-fsa.com", L"googlé.com", true, "google.com", true, + "xn--googl-fsa.com", u"googlé.com", true, "google.com", true, IDNSpoofChecker::Result::kSafe}, {// A unicode domain that's not valid according to the rules in IDN spoof // checker (whole script confusable in Cyrillic) and it matches a top // domain. Should be converted to punycode. - "xn--80ak6aa92e.com", L"аррӏе.com", true, "apple.com", true, + "xn--80ak6aa92e.com", u"аррӏе.com", true, "apple.com", true, IDNSpoofChecker::Result::kWholeScriptConfusable}, {// A unicode domain that's not valid according to the rules in IDN spoof // checker (mixed script) but it doesn't match a top domain. - "xn--o-o-oai-26a223aia177a7ab7649d.com", L"ɴoτ-τoρ-ďoᛖaiɴ.com", true, "", + "xn--o-o-oai-26a223aia177a7ab7649d.com", u"ɴoτ-τoρ-ďoᛖaiɴ.com", true, "", false, IDNSpoofChecker::Result::kICUSpoofChecks}}; for (const TestCase& test_case : kTestCases) { const url_formatter::IDNConversionResult result = UnsafeIDNToUnicodeWithDetails(test_case.punycode); - EXPECT_EQ(base::WideToUTF16(test_case.expected_unicode), result.result); + EXPECT_EQ(test_case.expected_unicode, result.result); EXPECT_EQ(test_case.expected_has_idn, result.has_idn_component); EXPECT_EQ(test_case.expected_matching_domain, result.matching_top_domain.domain);
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc index 539a6603..41c6132b 100644 --- a/components/viz/service/display/surface_aggregator.cc +++ b/components/viz/service/display/surface_aggregator.cc
@@ -557,6 +557,7 @@ } void SurfaceAggregator::HandleSurfaceQuad( + const CompositorRenderPass& source_pass, const SurfaceDrawQuad* surface_quad, float parent_device_scale_factor, const gfx::Transform& target_transform, @@ -624,15 +625,16 @@ dest_pass, mask_filter_info); } - EmitSurfaceContent(*resolved_frame, parent_device_scale_factor, surface_quad, - target_transform, clip_rect, dest_pass, ignore_undamaged, - damage_rect_in_quad_space, damage_rect_in_quad_space_valid, - mask_filter_info); + EmitSurfaceContent(*resolved_frame, parent_device_scale_factor, source_pass, + surface_quad, target_transform, clip_rect, dest_pass, + ignore_undamaged, damage_rect_in_quad_space, + damage_rect_in_quad_space_valid, mask_filter_info); } void SurfaceAggregator::EmitSurfaceContent( const ResolvedFrameData& resolved_frame, float parent_device_scale_factor, + const CompositorRenderPass& source_pass, const SurfaceDrawQuad* surface_quad, const gfx::Transform& target_transform, const absl::optional<gfx::Rect>& clip_rect, @@ -738,6 +740,8 @@ surface_quad_clip_rect.Intersect(*surface_quad_sqs->clip_rect); } + surface_quad_clip_rect.Intersect(source_pass.output_rect); + quads_clip = CalculateClipRect(clip_rect, surface_quad_clip_rect, target_transform); } @@ -1172,10 +1176,11 @@ quad->shared_quad_state->is_fast_rounded_corner, target_transform); } - HandleSurfaceQuad( - surface_quad, parent_device_scale_factor, target_transform, clip_rect, - dest_pass, ignore_undamaged, &damage_rect_in_quad_space, - &damage_rect_in_quad_space_valid, new_mask_filter_info_ext); + HandleSurfaceQuad(source_pass, surface_quad, parent_device_scale_factor, + target_transform, clip_rect, dest_pass, + ignore_undamaged, &damage_rect_in_quad_space, + &damage_rect_in_quad_space_valid, + new_mask_filter_info_ext); } else { if (quad->shared_quad_state != last_copied_source_shared_quad_state) { if (parent_mask_filter_info_ext.mask_filter_info.IsEmpty()) {
diff --git a/components/viz/service/display/surface_aggregator.h b/components/viz/service/display/surface_aggregator.h index 280a164..d187f36 100644 --- a/components/viz/service/display/surface_aggregator.h +++ b/components/viz/service/display/surface_aggregator.h
@@ -126,7 +126,9 @@ ResolvedFrameData* GetResolvedFrame(Surface* surface, bool inside_aggregation); - void HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad, + // |source_pass| is the render pass that contains |surface_quad|. + void HandleSurfaceQuad(const CompositorRenderPass& source_pass, + const SurfaceDrawQuad* surface_quad, float parent_device_scale_factor, const gfx::Transform& target_transform, const absl::optional<gfx::Rect>& clip_rect, @@ -136,8 +138,10 @@ bool* damage_rect_in_quad_space_valid, const MaskFilterInfoExt& mask_filter_info_pair); + // |source_pass| is the render pass that contains |surface_quad|. void EmitSurfaceContent(const ResolvedFrameData& resolved_frame, float parent_device_scale_factor, + const CompositorRenderPass& source_pass, const SurfaceDrawQuad* surface_quad, const gfx::Transform& target_transform, const absl::optional<gfx::Rect>& clip_rect,
diff --git a/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.cc b/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.cc index 37ab153..8a4a8d85 100644 --- a/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.cc +++ b/components/webapps/browser/android/installable/installable_ambient_badge_message_controller.cc
@@ -9,6 +9,7 @@ #include "components/strings/grit/components_strings.h" #include "components/url_formatter/elide_url.h" #include "components/webapps/browser/android/installable/installable_ambient_badge_client.h" +#include "components/webapps/browser/android/webapps_icon_utils.h" #include "ui/base/l10n/l10n_util.h" namespace webapps { @@ -50,6 +51,9 @@ // TODO(crbug.com/1247374): Add support for maskable primary icon. message_->DisableIconTint(); message_->SetIcon(icon); + message_->EnableLargeIcon(true); + message_->SetIconRoundedCornerRadius( + WebappsIconUtils::GetIdealIconCornerRadiusPxForPromptUI()); message_->SetPrimaryButtonText(l10n_util::GetStringUTF16(IDS_INSTALL)); messages::MessageDispatcherBridge::Get()->EnqueueMessage( message_.get(), web_contents, messages::MessageScopeType::NAVIGATION,
diff --git a/components/webapps/browser/android/java/res/values/dimens.xml b/components/webapps/browser/android/java/res/values/dimens.xml index f23bf14..8887412e 100644 --- a/components/webapps/browser/android/java/res/values/dimens.xml +++ b/components/webapps/browser/android/java/res/values/dimens.xml
@@ -3,7 +3,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<resources xmlns:tools="http://schemas.android.com/tools"> +<resources> <!-- Web app dimensions There are two possible layouts for splash screens, which is chosen based on whether an icon was auto-generated by Chrome and whether the icon is bigger than a threshold. --> @@ -20,4 +20,5 @@ <dimen name="webapk_adaptive_icon_size">83dp</dimen> <dimen name="webapk_monochrome_icon_size">24dp</dimen> + <dimen name="webapk_prompt_ui_icon_radius">16dp</dimen> </resources>
diff --git a/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsIconUtils.java b/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsIconUtils.java index 879e5a96..691658f 100644 --- a/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsIconUtils.java +++ b/components/webapps/browser/android/java/src/org/chromium/components/webapps/WebappsIconUtils.java
@@ -196,6 +196,16 @@ } /** + * Returns the ideal size for prompt UI icon corner radius. + * @return the dimensions in pixels which the prompt UI should use as the corner radius. + */ + @CalledByNative + public static int getIdealIconCornerRadiusPxForPromptUI() { + Context context = ContextUtils.getApplicationContext(); + return context.getResources().getDimensionPixelSize(R.dimen.webapk_prompt_ui_icon_radius); + } + + /** * Check the running Android version supports adaptive icon (i.e. API level >= 26) */ public static boolean doesAndroidSupportMaskableIcons() {
diff --git a/components/webapps/browser/android/webapps_icon_utils.cc b/components/webapps/browser/android/webapps_icon_utils.cc index d63d342..8fe7b1a7 100644 --- a/components/webapps/browser/android/webapps_icon_utils.cc +++ b/components/webapps/browser/android/webapps_icon_utils.cc
@@ -139,6 +139,11 @@ : SkBitmap(); } +int WebappsIconUtils::GetIdealIconCornerRadiusPxForPromptUI() { + return Java_WebappsIconUtils_getIdealIconCornerRadiusPxForPromptUI( + base::android::AttachCurrentThread()); +} + void WebappsIconUtils::SetIdealShortcutSizeForTesting(int size) { g_ideal_shortcut_icon_size = size; }
diff --git a/components/webapps/browser/android/webapps_icon_utils.h b/components/webapps/browser/android/webapps_icon_utils.h index f2ce24c..b39c37d 100644 --- a/components/webapps/browser/android/webapps_icon_utils.h +++ b/components/webapps/browser/android/webapps_icon_utils.h
@@ -53,6 +53,8 @@ const GURL& url, bool* is_generated); + static int GetIdealIconCornerRadiusPxForPromptUI(); + static void SetIdealShortcutSizeForTesting(int size); };
diff --git a/components/zucchini/mapped_file_unittest.cc b/components/zucchini/mapped_file_unittest.cc index e3ee6dc..56014b0 100644 --- a/components/zucchini/mapped_file_unittest.cc +++ b/components/zucchini/mapped_file_unittest.cc
@@ -33,7 +33,7 @@ { using base::File; File file(file_path_, File::FLAG_CREATE_ALWAYS | File::FLAG_READ | - File::FLAG_WRITE | File::FLAG_SHARE_DELETE | + File::FLAG_WRITE | File::FLAG_WIN_SHARE_DELETE | File::FLAG_CAN_DELETE_ON_CLOSE); MappedFileWriter file_writer(file_path_, std::move(file), 10); EXPECT_FALSE(file_writer.HasError()); @@ -49,7 +49,7 @@ { using base::File; File file(file_path_, File::FLAG_CREATE_ALWAYS | File::FLAG_READ | - File::FLAG_WRITE | File::FLAG_SHARE_DELETE | + File::FLAG_WRITE | File::FLAG_WIN_SHARE_DELETE | File::FLAG_CAN_DELETE_ON_CLOSE); MappedFileWriter file_writer(file_path_, std::move(file), 10); EXPECT_FALSE(file_writer.HasError());
diff --git a/components/zucchini/zucchini_commands.cc b/components/zucchini/zucchini_commands.cc index 0699cbec..225fc25 100644 --- a/components/zucchini/zucchini_commands.cc +++ b/components/zucchini/zucchini_commands.cc
@@ -60,7 +60,7 @@ CHECK_EQ(1U, params.file_paths.size()); base::File input_file(params.file_paths[0], base::File::FLAG_OPEN | base::File::FLAG_READ | - base::File::FLAG_SHARE_DELETE); + base::File::FLAG_WIN_SHARE_DELETE); zucchini::MappedFileReader input(std::move(input_file)); if (input.HasError()) { LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": " @@ -80,7 +80,7 @@ CHECK_EQ(1U, params.file_paths.size()); base::File input_file(params.file_paths[0], base::File::FLAG_OPEN | base::File::FLAG_READ | - base::File::FLAG_SHARE_DELETE); + base::File::FLAG_WIN_SHARE_DELETE); zucchini::MappedFileReader input(std::move(input_file)); if (input.HasError()) { LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": " @@ -100,7 +100,7 @@ CHECK_EQ(2U, params.file_paths.size()); using base::File; File old_file(params.file_paths[0], File::FLAG_OPEN | File::FLAG_READ | - base::File::FLAG_SHARE_DELETE); + base::File::FLAG_WIN_SHARE_DELETE); zucchini::MappedFileReader old_image(std::move(old_file)); if (old_image.HasError()) { LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": " @@ -108,7 +108,7 @@ return zucchini::status::kStatusFileReadError; } File new_file(params.file_paths[1], File::FLAG_OPEN | File::FLAG_READ | - base::File::FLAG_SHARE_DELETE); + base::File::FLAG_WIN_SHARE_DELETE); zucchini::MappedFileReader new_image(std::move(new_file)); if (new_image.HasError()) { LOG(ERROR) << "Error with file " << params.file_paths[1].value() << ": " @@ -131,7 +131,7 @@ CHECK_EQ(1U, params.file_paths.size()); base::File image_file(params.file_paths[0], base::File::FLAG_OPEN | base::File::FLAG_READ | - base::File::FLAG_SHARE_DELETE); + base::File::FLAG_WIN_SHARE_DELETE); zucchini::MappedFileReader image(std::move(image_file)); if (image.HasError()) { LOG(ERROR) << "Error with file " << params.file_paths[0].value() << ": "
diff --git a/components/zucchini/zucchini_integration.cc b/components/zucchini/zucchini_integration.cc index bf28b3c..c654a087 100644 --- a/components/zucchini/zucchini_integration.cc +++ b/components/zucchini/zucchini_integration.cc
@@ -184,11 +184,12 @@ std::string imposed_matches) { using base::File; File old_file(old_path, File::FLAG_OPEN | File::FLAG_READ | - base::File::FLAG_SHARE_DELETE); + base::File::FLAG_WIN_SHARE_DELETE); File new_file(new_path, File::FLAG_OPEN | File::FLAG_READ | - base::File::FLAG_SHARE_DELETE); + base::File::FLAG_WIN_SHARE_DELETE); File patch_file(patch_path, File::FLAG_CREATE_ALWAYS | File::FLAG_READ | - File::FLAG_WRITE | File::FLAG_SHARE_DELETE | + File::FLAG_WRITE | + File::FLAG_WIN_SHARE_DELETE | File::FLAG_CAN_DELETE_ON_CLOSE); const FileNames file_names(old_path, new_path, patch_path); return GenerateCommon(std::move(old_file), std::move(new_file), @@ -211,11 +212,11 @@ bool force_keep) { using base::File; File old_file(old_path, File::FLAG_OPEN | File::FLAG_READ | - base::File::FLAG_SHARE_DELETE); + base::File::FLAG_WIN_SHARE_DELETE); File patch_file(patch_path, File::FLAG_OPEN | File::FLAG_READ | - base::File::FLAG_SHARE_DELETE); + base::File::FLAG_WIN_SHARE_DELETE); File new_file(new_path, File::FLAG_CREATE_ALWAYS | File::FLAG_READ | - File::FLAG_WRITE | File::FLAG_SHARE_DELETE | + File::FLAG_WRITE | File::FLAG_WIN_SHARE_DELETE | File::FLAG_CAN_DELETE_ON_CLOSE); const FileNames file_names(old_path, new_path, patch_path); return ApplyCommon(std::move(old_file), std::move(patch_file),
diff --git a/content/browser/accessibility/accessibility_event_recorder_mac.h b/content/browser/accessibility/accessibility_event_recorder_mac.h index 0ba7791..4476109b 100644 --- a/content/browser/accessibility/accessibility_event_recorder_mac.h +++ b/content/browser/accessibility/accessibility_event_recorder_mac.h
@@ -5,10 +5,10 @@ #ifndef CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_EVENT_RECORDER_MAC_H_ #define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_EVENT_RECORDER_MAC_H_ -#include "content/browser/accessibility/accessibility_event_recorder.h" - #include "base/mac/scoped_cftyperef.h" +#include "content/browser/accessibility/accessibility_event_recorder.h" #include "content/browser/accessibility/browser_accessibility_cocoa.h" +#include "content/common/content_export.h" @class BrowserAccessibilityCocoa;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_mac.h b/content/browser/accessibility/accessibility_tree_formatter_mac.h index 47668bb..3b42520 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_mac.h +++ b/content/browser/accessibility/accessibility_tree_formatter_mac.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_ACCESSIBILITY_ACCESSIBILITY_TREE_FORMATTER_MAC_H_ #include "content/browser/accessibility/accessibility_tree_formatter_utils_mac.h" +#include "content/common/content_export.h" #include "ui/accessibility/platform/inspect/ax_tree_formatter_base.h" @class BrowserAccessibilityCocoa;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h b/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h index d03389f..7a46c274 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h +++ b/content/browser/accessibility/accessibility_tree_formatter_utils_mac.h
@@ -7,6 +7,7 @@ #include "content/browser/accessibility/accessibility_tools_utils_mac.h" #include "content/browser/accessibility/browser_accessibility_cocoa.h" +#include "content/common/content_export.h" #include "ui/accessibility/platform/inspect/ax_tree_indexer.h" namespace ui {
diff --git a/content/browser/accessibility/browser_accessibility_android.h b/content/browser/accessibility/browser_accessibility_android.h index 4d7bbe1..6258170 100644 --- a/content/browser/accessibility/browser_accessibility_android.h +++ b/content/browser/accessibility/browser_accessibility_android.h
@@ -13,6 +13,7 @@ #include "base/android/scoped_java_ref.h" #include "content/browser/accessibility/browser_accessibility.h" +#include "content/common/content_export.h" #include "ui/accessibility/ax_node.h" #include "ui/accessibility/platform/ax_platform_node.h"
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.h b/content/browser/accessibility/browser_accessibility_manager_android.h index 3ddc975..bb13dc8 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.h +++ b/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -9,6 +9,7 @@ #include <utility> #include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/common/content_export.h" #include "content/common/render_accessibility.mojom-forward.h" namespace ui {
diff --git a/content/browser/accessibility/browser_accessibility_manager_auralinux.h b/content/browser/accessibility/browser_accessibility_manager_auralinux.h index a10322e..6afb7d2 100644 --- a/content/browser/accessibility/browser_accessibility_manager_auralinux.h +++ b/content/browser/accessibility/browser_accessibility_manager_auralinux.h
@@ -9,6 +9,7 @@ #include "base/gtest_prod_util.h" #include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/common/content_export.h" namespace content { class BrowserAccessibilityAuraLinux;
diff --git a/content/browser/accessibility/browser_accessibility_manager_fuchsia.h b/content/browser/accessibility/browser_accessibility_manager_fuchsia.h index 8845de2..a8a6de4 100644 --- a/content/browser/accessibility/browser_accessibility_manager_fuchsia.h +++ b/content/browser/accessibility/browser_accessibility_manager_fuchsia.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_ACCESSIBILITY_BROWSER_ACCESSIBILITY_MANAGER_FUCHSIA_H_ #include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/common/content_export.h" #include "ui/accessibility/platform/fuchsia/accessibility_bridge_fuchsia.h" namespace content {
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.h b/content/browser/accessibility/browser_accessibility_manager_mac.h index 21fd048a66..875e282 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.h +++ b/content/browser/accessibility/browser_accessibility_manager_mac.h
@@ -14,6 +14,7 @@ #import "content/browser/accessibility/browser_accessibility_cocoa.h" #include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/common/content_export.h" #include "content/public/browser/ax_event_notification_details.h" namespace content {
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.h b/content/browser/accessibility/browser_accessibility_manager_win.h index 2cfd384..5943629d 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.h +++ b/content/browser/accessibility/browser_accessibility_manager_win.h
@@ -13,6 +13,7 @@ #include <vector> #include "content/browser/accessibility/browser_accessibility_manager.h" +#include "content/common/content_export.h" #include "ui/accessibility/platform/ax_platform_node_win.h" namespace content {
diff --git a/content/browser/accessibility/browser_accessibility_state_impl.h b/content/browser/accessibility/browser_accessibility_state_impl.h index 9ba23f5..0520002 100644 --- a/content/browser/accessibility/browser_accessibility_state_impl.h +++ b/content/browser/accessibility/browser_accessibility_state_impl.h
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "build/build_config.h" #include "components/metrics/metrics_provider.h" +#include "content/common/content_export.h" #include "content/public/browser/browser_accessibility_state.h" #include "ui/accessibility/ax_mode.h" #include "ui/accessibility/ax_mode_observer.h"
diff --git a/content/browser/accessibility/web_contents_accessibility_android.h b/content/browser/accessibility/web_contents_accessibility_android.h index 38c3b366..95a6603 100644 --- a/content/browser/accessibility/web_contents_accessibility_android.h +++ b/content/browser/accessibility/web_contents_accessibility_android.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_ACCESSIBILITY_WEB_CONTENTS_ACCESSIBILITY_ANDROID_H_ #include "content/browser/accessibility/web_contents_accessibility.h" +#include "content/common/content_export.h" #include <unordered_map>
diff --git a/content/browser/android/gesture_listener_manager.h b/content/browser/android/gesture_listener_manager.h index 28d335a..3aa2d5d 100644 --- a/content/browser/android/gesture_listener_manager.h +++ b/content/browser/android/gesture_listener_manager.h
@@ -8,6 +8,7 @@ #include "base/android/jni_weak_ref.h" #include "base/android/scoped_java_ref.h" #include "content/browser/android/render_widget_host_connector.h" +#include "content/common/content_export.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" namespace blink {
diff --git a/content/browser/android/nfc_host.cc b/content/browser/android/nfc_host.cc index 0642493..799daa16 100644 --- a/content/browser/android/nfc_host.cc +++ b/content/browser/android/nfc_host.cc
@@ -78,7 +78,7 @@ void NFCHost::RenderFrameHostChanged(RenderFrameHost* old_host, RenderFrameHost* new_host) { // If the main frame has been replaced then close an old NFC connection. - if (!new_host->GetParent()) + if (new_host->IsInPrimaryMainFrame()) Close(); }
diff --git a/content/browser/android/nfc_host_browsertest.cc b/content/browser/android/nfc_host_browsertest.cc new file mode 100644 index 0000000..3faedd0 --- /dev/null +++ b/content/browser/android/nfc_host_browsertest.cc
@@ -0,0 +1,67 @@ +// 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 "content/public/browser/web_contents.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/content_browser_test.h" +#include "content/public/test/content_browser_test_utils.h" +#include "content/public/test/fenced_frame_test_util.h" +#include "content/shell/browser/shell.h" +#include "net/dns/mock_host_resolver.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "services/device/public/cpp/test/scoped_nfc_overrider.h" +#include "url/gurl.h" + +namespace content { + +class NFCHostBrowserTest : public ContentBrowserTest { + public: + NFCHostBrowserTest() { + https_server_.AddDefaultHandlers(GetTestDataFilePath()); + https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_OK); + } + ~NFCHostBrowserTest() override = default; + + protected: + void SetUpOnMainThread() override { + host_resolver()->AddRule("*", "127.0.0.1"); + ASSERT_TRUE(https_server_.Start()); + ContentBrowserTest::SetUpOnMainThread(); + } + + WebContents* web_contents() const { return shell()->web_contents(); } + + // WebNFC needs HTTPS. + net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS}; + test::FencedFrameTestHelper fenced_frame_helper_; +}; + +IN_PROC_BROWSER_TEST_F(NFCHostBrowserTest, FencedFrameCannotCloseNFC) { + device::ScopedNFCOverrider scoped_nfc_overrider; + + GURL main_url(https_server_.GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + // Initialize NFC in the primary main frame. + EXPECT_EQ("success", EvalJs(web_contents()->GetMainFrame(), R"( + const ndef = new NDEFReader(); + new Promise(async resolve => { + try { + await ndef.write("Hello"); + resolve('success'); + } catch (error) { + resolve('failure'); + } + }); + )")); + + // Ensure that fenced frame insertion cannot close the NFC connection. + GURL inner_url(https_server_.GetURL("/title2.html")); + RenderFrameHost* fenced_frame_host = fenced_frame_helper_.CreateFencedFrame( + web_contents()->GetMainFrame(), inner_url); + EXPECT_NE(nullptr, fenced_frame_host); + EXPECT_EQ(true, scoped_nfc_overrider.IsConnected()); +} + +} // namespace content
diff --git a/content/browser/attribution_reporting/attribution_manager_impl.h b/content/browser/attribution_reporting/attribution_manager_impl.h index 28190c5..de42b3cd 100644 --- a/content/browser/attribution_reporting/attribution_manager_impl.h +++ b/content/browser/attribution_reporting/attribution_manager_impl.h
@@ -20,6 +20,7 @@ #include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage.h" #include "content/browser/attribution_reporting/sent_report_info.h" +#include "content/common/content_export.h" #include "storage/browser/quota/special_storage_policy.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/content/browser/attribution_reporting/attribution_storage.h b/content/browser/attribution_reporting/attribution_storage.h index 949063a1..89a07b5ee 100644 --- a/content/browser/attribution_reporting/attribution_storage.h +++ b/content/browser/attribution_reporting/attribution_storage.h
@@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/storable_source.h" +#include "content/common/content_export.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace base {
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index cf45609..0a710f2 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -870,8 +870,7 @@ RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a); // 2) Navigate to B. - EXPECT_TRUE(ExecJs(shell(), JsReplace("location = $1;", url_b.spec()))); - EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + ASSERT_TRUE(NavigateToURLFromRenderer(shell(), url_b)); RenderFrameHostImpl* rfh_b = current_frame_host(); RenderFrameDeletedObserver delete_observer_rfh_b(rfh_b); EXPECT_FALSE(delete_observer_rfh_a.deleted()); @@ -983,7 +982,7 @@ // 2) Navigate to B. The previous document can't enter the BackForwardCache, // because of the popup. - ASSERT_TRUE(ExecJs(rfh_a.get(), JsReplace("location = $1;", url_b.spec()))); + ASSERT_TRUE(NavigateToURLFromRenderer(rfh_a.get(), url_b)); ASSERT_TRUE(rfh_a.WaitUntilRenderFrameDeleted()); RenderFrameHostImplWrapper rfh_b(current_frame_host()); EXPECT_EQ(2u, rfh_b->GetSiteInstance()->GetRelatedActiveContentsCount()); @@ -993,6 +992,12 @@ ASSERT_TRUE(ExecJs(rfh_b.get(), "history.back();")); ASSERT_TRUE(rfh_b.WaitUntilRenderFrameDeleted()); + ExpectNotRestored( + {BackForwardCacheMetrics::NotRestoredReason::kRelatedActiveContentsExist, + BackForwardCacheMetrics::NotRestoredReason::kBrowsingInstanceNotSwapped}, + {}, {ShouldSwapBrowsingInstance::kNo_HasRelatedActiveContents}, {}, {}, + FROM_HERE); + // 4) Make the popup drop the window.opener connection. It happens when the // user does an omnibox-initiated navigation, which happens in a new // BrowsingInstance. @@ -1003,9 +1008,7 @@ // 5) Navigate to B again. As the scripting relationship with the popup is // now severed, the current page (|rfh_a_new|) can enter back-forward cache. - ASSERT_TRUE( - ExecJs(rfh_a_new.get(), JsReplace("location = $1;", url_b.spec()))); - ASSERT_TRUE(WaitForLoadStop(web_contents())); + ASSERT_TRUE(NavigateToURLFromRenderer(rfh_a_new.get(), url_b)); EXPECT_FALSE(rfh_a_new.IsRenderFrameDeleted()); EXPECT_TRUE(rfh_a_new->IsInBackForwardCache()); @@ -1019,6 +1022,55 @@ EXPECT_TRUE(rfh_b_new->IsInBackForwardCache()); } +// A popup will prevent a page from entering BFCache. Test that after closing a +// popup, the page is not stopped from entering. This tries to close the popup +// at the last moment. +IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, WindowOpenThenClose) { + net::test_server::ControllableHttpResponse response(embedded_test_server(), + "/title2.html"); + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url_a(embedded_test_server()->GetURL("a.test", "/title1.html")); + GURL url_b(embedded_test_server()->GetURL("b.test", "/title2.html")); + + // Navigate to A. + ASSERT_TRUE(NavigateToURL(shell(), url_a)); + RenderFrameHostImplWrapper rfh_a(current_frame_host()); + EXPECT_EQ(1u, rfh_a->GetSiteInstance()->GetRelatedActiveContentsCount()); + + // Open a popup. + Shell* popup = OpenPopup(rfh_a.get(), url_a, ""); + EXPECT_EQ(2u, rfh_a->GetSiteInstance()->GetRelatedActiveContentsCount()); + + // Start navigating to B, the response will be delayed. + TestNavigationObserver observer(web_contents()); + shell()->LoadURL(url_b); + + // When the request is received, close the popup. + response.WaitForRequest(); + RenderFrameHostImplWrapper rfh_popup(popup->web_contents()->GetMainFrame()); + ASSERT_TRUE(ExecJs(rfh_popup.get(), "window.close();")); + ASSERT_TRUE(rfh_popup.WaitUntilRenderFrameDeleted()); + + EXPECT_EQ(1u, rfh_a->GetSiteInstance()->GetRelatedActiveContentsCount()); + + // Send the response. + response.Send(net::HTTP_OK, "text/html", "foo"); + response.Done(); + observer.Wait(); + + // A is in BFCache. + EXPECT_EQ(0u, rfh_a->GetSiteInstance()->GetRelatedActiveContentsCount()); + ASSERT_TRUE(rfh_a->IsInBackForwardCache()); + + // Go back. + web_contents()->GetController().GoBack(); + ASSERT_TRUE(WaitForLoadStop(shell()->web_contents())); + + // A is restored from BFCache. + EXPECT_FALSE(rfh_a.IsRenderFrameDeleted()); + ExpectRestored(FROM_HERE); +} + // Navigate from A(B) to C and go back. IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, BasicIframe) { ASSERT_TRUE(embedded_test_server()->Start()); @@ -2635,6 +2687,14 @@ 1), base::Bucket( static_cast<int>( + blink::EventPageShowPersisted::kBrowserYesInRenderer), + 1), + base::Bucket( + static_cast<int>( + blink::EventPageShowPersisted::kBrowserYesInRendererWithPage), + 1), + base::Bucket( + static_cast<int>( blink::EventPageShowPersisted:: kYesInBrowser_BackForwardCache_WillCommitNavigationToCachedEntry), 1), @@ -2726,8 +2786,7 @@ StartRecordingEvents(rfh_a); // 2) Navigate to B. - EXPECT_TRUE(ExecJs(shell(), JsReplace("location = $1;", url_b.spec()))); - EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + ASSERT_TRUE(NavigateToURLFromRenderer(shell(), url_b)); RenderFrameHostImpl* rfh_b = current_frame_host(); RenderFrameDeletedObserver delete_observer_rfh_b(rfh_b); @@ -8042,6 +8101,66 @@ EXPECT_FALSE(fenced_frame_host->IsInBackForwardCache()); } +// A testing subclass that limits the cache size to 1 for ease of testing +// evictions. +class CacheSizeOneBackForwardCacheBrowserTest + : public BackForwardCacheBrowserTest { + protected: + void SetUpCommandLine(base::CommandLine* command_line) override { + EnableFeatureAndSetParams(features::kBackForwardCache, "cache_size", + base::NumberToString(1)); + BackForwardCacheBrowserTest::SetUpCommandLine(command_line); + } +}; + +IN_PROC_BROWSER_TEST_F(CacheSizeOneBackForwardCacheBrowserTest, + ReplacedNavigationEntry) { + // Set the bfcache value to 1 to ensure that the test fails if a page + // that replaces the current history entry is stored in back-forward cache. + ASSERT_TRUE(embedded_test_server()->Start()); + GURL url_a(embedded_test_server()->GetURL("a.test", "/title1.html")); + GURL url_b(embedded_test_server()->GetURL("b.test", "/title1.html")); + GURL url_c(embedded_test_server()->GetURL("c.test", "/title1.html")); + + // 1) Navigate to A. + EXPECT_TRUE(NavigateToURL(shell(), url_a)); + RenderFrameHostImplWrapper rfh_a(current_frame_host()); + + // 2) Navigate to B. + EXPECT_TRUE(NavigateToURL(shell(), url_b)); + RenderFrameHostImplWrapper rfh_b(current_frame_host()); + EXPECT_FALSE(rfh_a.IsRenderFrameDeleted()); + EXPECT_TRUE(rfh_a->IsInBackForwardCache()); + EXPECT_FALSE(rfh_b->IsInBackForwardCache()); + + // 3) Navigate to a new page by replacing the location. The old page can't + // be navigated back to and we should not store it in the back-forward + // cache. + EXPECT_TRUE( + ExecJs(shell(), JsReplace("window.location.replace($1);", url_c))); + EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + RenderFrameHostImplWrapper rfh_c(current_frame_host()); + + // 4) Confirm A is still in BackForwardCache and it wasn't evicted due to the + // cache size limit, which would happen if we tried to store a new page in the + // cache in the previous step. + EXPECT_FALSE(rfh_a.IsRenderFrameDeleted()); + EXPECT_TRUE(rfh_a->IsInBackForwardCache()); + + // 5) Confirm that navigating backwards goes back to A. + shell()->web_contents()->GetController().GoBack(); + ASSERT_TRUE(WaitForLoadStop(web_contents())); + EXPECT_EQ(rfh_a.get(), current_frame_host()); + EXPECT_FALSE(rfh_a->IsInBackForwardCache()); + EXPECT_EQ(rfh_a->GetVisibilityState(), PageVisibilityState::kVisible); + + // Go forward again, should return to C + shell()->web_contents()->GetController().GoForward(); + ASSERT_TRUE(WaitForLoadStop(web_contents())); + EXPECT_EQ(rfh_c.get(), current_frame_host()); + EXPECT_EQ(rfh_c->GetVisibilityState(), PageVisibilityState::kVisible); +} + // BEFORE ADDING A NEW TEST HERE // Read the note at the top about the other files you could add it to. } // namespace content
diff --git a/content/browser/back_forward_cache_features_browsertest.cc b/content/browser/back_forward_cache_features_browsertest.cc index 3bc0b98..ba75cd5 100644 --- a/content/browser/back_forward_cache_features_browsertest.cc +++ b/content/browser/back_forward_cache_features_browsertest.cc
@@ -34,7 +34,8 @@ #include "third_party/blink/public/mojom/app_banner/app_banner.mojom.h" // This file contains back-/forward-cache tests for web-platform features and -// APIs. +// APIs. It was forked from +// https://source.chromium.org/chromium/chromium/src/+/main:content/browser/back_forward_cache_browsertest.cc;drc=1288c1bd6a81785cd85b965d61820a7cd87a0e9c // // When adding tests for new features please also add WPTs. See // third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/README.md @@ -1049,8 +1050,7 @@ rfh_a->UseDummyStickyBackForwardCacheDisablingFeatureForTesting(); // 3) Navigate cross-site, renderer-inititated. - EXPECT_TRUE(ExecJs(shell(), JsReplace("location = $1;", url_b.spec()))); - EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + ASSERT_TRUE(NavigateToURLFromRenderer(shell(), url_b)); // The previous page won't get into the back-forward cache because of the // blocklisted features. Because we used sticky blocklisted features, we will // not do a proactive BrowsingInstance swap. @@ -1215,8 +1215,7 @@ // 3) Navigate cross-site, renderer-inititated. // The previous page won't get into the back-forward cache because of the // blocklisted feature. - EXPECT_TRUE(ExecJs(shell(), JsReplace("location = $1;", url_b.spec()))); - EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + ASSERT_TRUE(NavigateToURLFromRenderer(shell(), url_b)); // Because we only used non-sticky blocklisted features, we will still do a // proactive BrowsingInstance swap. EXPECT_FALSE(site_instance_a->IsRelatedSiteInstance(
diff --git a/content/browser/back_forward_cache_network_request_browsertest.cc b/content/browser/back_forward_cache_network_request_browsertest.cc index 68c1ab9..aafb63b 100644 --- a/content/browser/back_forward_cache_network_request_browsertest.cc +++ b/content/browser/back_forward_cache_network_request_browsertest.cc
@@ -12,6 +12,8 @@ #include "net/test/embedded_test_server/controllable_http_response.h" // This file contains back-/forward-cache tests for fetching from the network. +// It was forked from +// https://source.chromium.org/chromium/chromium/src/+/main:content/browser/back_forward_cache_browsertest.cc;drc=748acc7b301b489567691500c558c5fde8cfd538 // // When adding tests please also add WPTs. See // third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/README.md
diff --git a/content/browser/back_forward_cache_no_store_browsertest.cc b/content/browser/back_forward_cache_no_store_browsertest.cc index b48014a..2479825 100644 --- a/content/browser/back_forward_cache_no_store_browsertest.cc +++ b/content/browser/back_forward_cache_no_store_browsertest.cc
@@ -16,7 +16,8 @@ #include "net/test/embedded_test_server/controllable_http_response.h" // This file contains back-/forward-cache tests for the -// `Cache-control: no-store` header. +// `Cache-control: no-store` header. It was forked from +// https://source.chromium.org/chromium/chromium/src/+/main:content/browser/back_forward_cache_browsertest.cc;drc=b339487e39ad6ae93af30fa8fcb37dc61bd138ec // // When adding tests please also add WPTs. See // third_party/blink/web_tests/external/wpt/html/browsers/browsing-the-web/back-forward-cache/README.md
diff --git a/content/browser/background_fetch/background_fetch_delegate_proxy.h b/content/browser/background_fetch/background_fetch_delegate_proxy.h index f53ef08..75101ab 100644 --- a/content/browser/background_fetch/background_fetch_delegate_proxy.h +++ b/content/browser/background_fetch/background_fetch_delegate_proxy.h
@@ -15,6 +15,7 @@ #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" #include "content/browser/background_fetch/background_fetch_request_info.h" +#include "content/common/content_export.h" #include "content/public/browser/background_fetch_delegate.h" #include "content/public/browser/background_fetch_description.h" #include "content/public/browser/background_fetch_response.h"
diff --git a/content/browser/background_sync/one_shot_background_sync_service_impl.h b/content/browser/background_sync/one_shot_background_sync_service_impl.h index b03518b..c3f0f39 100644 --- a/content/browser/background_sync/one_shot_background_sync_service_impl.h +++ b/content/browser/background_sync/one_shot_background_sync_service_impl.h
@@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "content/browser/background_sync/background_sync_manager.h" #include "content/browser/background_sync/background_sync_registration_helper.h" +#include "content/common/content_export.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "third_party/blink/public/mojom/background_sync/background_sync.mojom.h"
diff --git a/content/browser/background_sync/periodic_background_sync_service_impl.h b/content/browser/background_sync/periodic_background_sync_service_impl.h index 0a03a09..1a57b2f 100644 --- a/content/browser/background_sync/periodic_background_sync_service_impl.h +++ b/content/browser/background_sync/periodic_background_sync_service_impl.h
@@ -15,6 +15,7 @@ #include "base/memory/weak_ptr.h" #include "content/browser/background_sync/background_sync_manager.h" #include "content/browser/background_sync/background_sync_registration_helper.h" +#include "content/common/content_export.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "third_party/blink/public/mojom/background_sync/background_sync.mojom.h"
diff --git a/content/browser/browser_child_process_host_impl.h b/content/browser/browser_child_process_host_impl.h index ae46614..3668871 100644 --- a/content/browser/browser_child_process_host_impl.h +++ b/content/browser/browser_child_process_host_impl.h
@@ -22,6 +22,7 @@ #include "content/browser/tracing/tracing_service_controller.h" #include "content/common/child_process.mojom.h" #include "content/common/child_process_host_impl.h" +#include "content/common/content_export.h" #include "content/public/browser/browser_child_process_host.h" #include "content/public/browser/child_process_data.h" #include "content/public/common/child_process_host.h"
diff --git a/content/browser/browser_main_loop.h b/content/browser/browser_main_loop.h index 2a0cccc9..475ca9f 100644 --- a/content/browser/browser_main_loop.h +++ b/content/browser/browser_main_loop.h
@@ -14,6 +14,7 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "content/browser/browser_process_io_thread.h" +#include "content/common/content_export.h" #include "content/public/browser/browser_main_runner.h" #include "media/media_buildflags.h" #include "services/viz/public/mojom/compositing/compositing_mode_watcher.mojom.h"
diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index c3a88e31..cd1ca88 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h
@@ -22,6 +22,7 @@ #include "base/memory/weak_ptr.h" #include "build/build_config.h" +#include "content/common/content_export.h" #include "content/public/browser/browser_plugin_guest_delegate.h" #include "content/public/browser/guest_host.h" #include "content/public/browser/web_contents_observer.h"
diff --git a/content/browser/browser_process_io_thread.cc b/content/browser/browser_process_io_thread.cc index 6922dda3..787395fb 100644 --- a/content/browser/browser_process_io_thread.cc +++ b/content/browser/browser_process_io_thread.cc
@@ -14,6 +14,7 @@ #include "base/threading/hang_watcher.h" #include "base/threading/thread_restrictions.h" #include "base/trace_event/memory_dump_manager.h" +#include "build/chromeos_buildflags.h" #include "content/browser/browser_child_process_host_impl.h" #include "content/browser/browser_thread_impl.h" #include "content/browser/notification_service_impl.h" @@ -156,7 +157,7 @@ #if BUILDFLAG(CLANG_PROFILING) // On profiling build, browser_tests runs 10x slower. const int kMaxSecondsToWaitForNetworkProcess = 100; -#elif defined(OS_CHROMEOS) +#elif BUILDFLAG(IS_CHROMEOS_ASH) // ChromeOS will kill the browser process if it doesn't shut down within // 3 seconds, so make sure we wait for less than that. const int kMaxSecondsToWaitForNetworkProcess = 1;
diff --git a/content/browser/browser_url_handler_impl.h b/content/browser/browser_url_handler_impl.h index ceea966..fe49499 100644 --- a/content/browser/browser_url_handler_impl.h +++ b/content/browser/browser_url_handler_impl.h
@@ -10,6 +10,7 @@ #include "base/gtest_prod_util.h" #include "base/memory/singleton.h" +#include "content/common/content_export.h" #include "content/public/browser/browser_url_handler.h" class GURL;
diff --git a/content/browser/browsing_data/browsing_data_filter_builder_impl.h b/content/browser/browsing_data/browsing_data_filter_builder_impl.h index 96b47d3..2d6da15 100644 --- a/content/browser/browsing_data/browsing_data_filter_builder_impl.h +++ b/content/browser/browsing_data/browsing_data_filter_builder_impl.h
@@ -7,6 +7,7 @@ #include <set> +#include "content/common/content_export.h" #include "content/public/browser/browsing_data_filter_builder.h" #include "url/origin.h"
diff --git a/content/browser/browsing_data/same_site_data_remover_impl.h b/content/browser/browsing_data/same_site_data_remover_impl.h index a4d591bf..d3ecc5b3 100644 --- a/content/browser/browsing_data/same_site_data_remover_impl.h +++ b/content/browser/browsing_data/same_site_data_remover_impl.h
@@ -9,6 +9,7 @@ #include <string> #include "base/callback.h" +#include "content/common/content_export.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h"
diff --git a/content/browser/browsing_instance.cc b/content/browser/browsing_instance.cc index 6b154dd..1311d340 100644 --- a/content/browser/browsing_instance.cc +++ b/content/browser/browsing_instance.cc
@@ -204,4 +204,49 @@ return SiteInfo::Create(isolation_context_, url_info_with_partition); } +int BrowsingInstance::EstimateOriginAgentClusterOverhead() { + DCHECK(SiteIsolationPolicy::IsProcessIsolationForOriginAgentClusterEnabled()); + + std::set<SiteInfo> site_info_set; + std::set<SiteInfo> site_info_set_no_oac; + + // The following computes an estimate of how many additional processes have + // been created to deal with OriginAgentCluster (OAC) headers. When OAC + // headers forces an additional process, that corresponds to the SiteInfo's + // is_origin_keyed_ flag being set. To compute the estimate, we use the set of + // unique SiteInstances (each represented by a unique SiteInfo) in each + // BrowsingInstance as a proxy for the set of different RenderProcesses. We + // start with the total count of SiteInfos, then we create a new set of + // SiteInfos created by resetting the is_origin_keyed_ flag on each of the + // SiteInfos (along with any corresponding adjustments to the site_url_ and + // process_lock_url_ to reflect the possible conversion from origin to site). + // The assumption here is that SiteInfos that forced a new process due to OAC + // may no longer be unique once these values are reset, and as such the new + // set will have less elements than the original set, with the difference + // being the count of extra SiteInstances due to OAC. There are cases where + // ignoring the OAC header would still result in an extra process, e.g. when + // the SiteInfo's origin appears in the command-line origin isolation list. + // + // The estimate is computed using several simplifying assumptions: + // 1) We only consider HTTPS SiteInfos to compute the additional SiteInfos. + // This assumption should generally be valid, since we don't apply + // is_origin_keyed_ to non-HTTPS schemes. + // 2) We assume that SiteInfos from multiple BrowsingInstances aren't + // coalesced into a single RenderProcess. While this isn't true in general, + // it is difficult in practice to account for, so we don't try to. + for (auto& entry : site_instance_map_) { + const SiteInfo& site_info = entry.first; + GURL process_lock_url = site_info.process_lock_url(); + if (!process_lock_url.SchemeIs(url::kHttpsScheme)) + continue; + + site_info_set.insert(site_info); + site_info_set_no_oac.insert( + site_info.GetNonOriginKeyedEquivalentForMetrics(isolation_context_)); + } + DCHECK_GE(site_info_set.size(), site_info_set_no_oac.size()); + int result = site_info_set.size() - site_info_set_no_oac.size(); + return result; +} + } // namespace content
diff --git a/content/browser/browsing_instance.h b/content/browser/browsing_instance.h index 564ed316..f77c1fb6 100644 --- a/content/browser/browsing_instance.h +++ b/content/browser/browsing_instance.h
@@ -187,6 +187,10 @@ // Note: This should not be used by code outside this class. SiteInfo ComputeSiteInfoForURL(const UrlInfo& url_info) const; + // Computes the number of extra SiteInstances for each site due to OAC's + // splitting a site into isolated origins. + int EstimateOriginAgentClusterOverhead(); + // Map of SiteInfo to SiteInstance, to ensure we only have one SiteInstance // per SiteInfo. See https://crbug.com/1085275#c2 for the rationale behind // why SiteInfo is the right class to key this on.
diff --git a/content/browser/buckets/bucket_context.cc b/content/browser/buckets/bucket_context.cc index 6caab7da..ba22324 100644 --- a/content/browser/buckets/bucket_context.cc +++ b/content/browser/buckets/bucket_context.cc
@@ -25,14 +25,16 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); } -void BucketContext::Initialize() { +void BucketContext::Initialize( + scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); #if DCHECK_IS_ON() DCHECK(!initialize_called_) << __func__ << " called twice"; initialize_called_ = true; #endif // DCHECK_IS_ON() content::GetIOThreadTaskRunner({})->PostTask( - FROM_HERE, base::BindOnce(&BucketContext::InitializeOnIOThread, this)); + FROM_HERE, base::BindOnce(&BucketContext::InitializeOnIOThread, this, + std::move(quota_manager_proxy))); } void BucketContext::BindBucketManagerHost( @@ -50,11 +52,13 @@ std::move(receiver), mojo::GetBadMessageCallback())); } -void BucketContext::InitializeOnIOThread() { +void BucketContext::InitializeOnIOThread( + scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy) { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(!bucket_manager_) << __func__ << " called more than once"; - bucket_manager_ = std::make_unique<BucketManager>(); + bucket_manager_ = + std::make_unique<BucketManager>(std::move(quota_manager_proxy)); } void BucketContext::BindBucketManagerHostOnIOThread(
diff --git a/content/browser/buckets/bucket_context.h b/content/browser/buckets/bucket_context.h index 362a285..5707b196 100644 --- a/content/browser/buckets/bucket_context.h +++ b/content/browser/buckets/bucket_context.h
@@ -13,6 +13,7 @@ #include "base/task/sequenced_task_runner_helpers.h" #include "base/thread_annotations.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "storage/browser/quota/quota_manager_proxy.h" #include "third_party/blink/public/mojom/buckets/bucket_manager_host.mojom-forward.h" #include "url/origin.h" @@ -37,7 +38,8 @@ BucketContext(const BucketContext&) = delete; BucketContext& operator=(const BucketContext&) = delete; - void Initialize(); + void Initialize( + scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy); // Posts task on IO thread and calls BindBucketManagerHostOnIOThread to create // BucketManagerHost and bind blink::mojom::BucketManagerHost receiver. @@ -51,7 +53,8 @@ ~BucketContext(); - void InitializeOnIOThread(); + void InitializeOnIOThread( + scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy); // Must be called on the IO thread. This will create a BucketManagerHost // and bind the blink::mojom::BucketManagerHost receiver.
diff --git a/content/browser/buckets/bucket_host.cc b/content/browser/buckets/bucket_host.cc index aaa3938f..9ccffe1 100644 --- a/content/browser/buckets/bucket_host.cc +++ b/content/browser/buckets/bucket_host.cc
@@ -5,15 +5,17 @@ #include "content/browser/buckets/bucket_host.h" #include "base/bind.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "content/browser/buckets/bucket_manager.h" #include "content/browser/buckets/bucket_manager_host.h" namespace content { BucketHost::BucketHost(BucketManagerHost* bucket_manager_host, - std::string name, + const storage::BucketInfo& bucket_info, blink::mojom::BucketPoliciesPtr policies) : bucket_manager_host_(bucket_manager_host), - bucket_name_(std::move(name)), + bucket_info_(bucket_info), policies_(std::move(policies)) { receivers_.set_disconnect_handler(base::BindRepeating( &BucketHost::OnReceiverDisconnected, base::Unretained(this))); @@ -64,7 +66,7 @@ if (!receivers_.empty()) return; // Destroys `this`. - bucket_manager_host_->RemoveBucketHost(bucket_name_); + bucket_manager_host_->RemoveBucketHost(bucket_info_.name); } } // namespace content
diff --git a/content/browser/buckets/bucket_host.h b/content/browser/buckets/bucket_host.h index c9ea15b..40dc9ca 100644 --- a/content/browser/buckets/bucket_host.h +++ b/content/browser/buckets/bucket_host.h
@@ -5,9 +5,11 @@ #ifndef CONTENT_BROWSER_BUCKETS_BUCKET_HOST_H_ #define CONTENT_BROWSER_BUCKETS_BUCKET_HOST_H_ +#include "components/services/storage/public/cpp/buckets/bucket_info.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver_set.h" #include "third_party/blink/public/mojom/buckets/bucket_manager_host.mojom.h" +#include "third_party/blink/public/mojom/quota/quota_types.mojom.h" namespace content { @@ -22,7 +24,7 @@ class BucketHost : public blink::mojom::BucketHost { public: BucketHost(BucketManagerHost* bucket_manager_host, - std::string name, + const storage::BucketInfo& bucket_info, blink::mojom::BucketPoliciesPtr policies); ~BucketHost() override; @@ -44,12 +46,11 @@ private: void OnReceiverDisconnected(); - // |bucket_manager_host_| is valid throughout lifetime of `this` because it - // owns `this` and is therefore guaranteed to outlive it. + // Raw pointer use is safe here because BucketManagerHost owns this + // BucketHost. BucketManagerHost* bucket_manager_host_; - // TODO(ayui): Temporarily used as bucket ID. - const std::string bucket_name_; + const storage::BucketInfo bucket_info_; // TODO(ayui): The authoritative source of bucket policies should be the // buckets database.
diff --git a/content/browser/buckets/bucket_manager.cc b/content/browser/buckets/bucket_manager.cc index 50af9ae..c1369fd 100644 --- a/content/browser/buckets/bucket_manager.cc +++ b/content/browser/buckets/bucket_manager.cc
@@ -9,7 +9,10 @@ namespace content { -BucketManager::BucketManager() = default; +BucketManager::BucketManager( + scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy) + : quota_manager_proxy_(std::move(quota_manager_proxy)) {} + BucketManager::~BucketManager() = default; void BucketManager::BindReceiver(
diff --git a/content/browser/buckets/bucket_manager.h b/content/browser/buckets/bucket_manager.h index ace167f..2dbce0f 100644 --- a/content/browser/buckets/bucket_manager.h +++ b/content/browser/buckets/bucket_manager.h
@@ -13,6 +13,7 @@ #include "base/types/pass_key.h" #include "content/common/content_export.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "storage/browser/quota/quota_manager_proxy.h" #include "third_party/blink/public/mojom/buckets/bucket_manager_host.mojom-forward.h" #include "url/origin.h" @@ -27,7 +28,8 @@ // them mark their Bucket instance as closed. class CONTENT_EXPORT BucketManager { public: - BucketManager(); + explicit BucketManager( + scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy); ~BucketManager(); BucketManager(const BucketManager&) = delete; @@ -43,12 +45,18 @@ void OnHostReceiverDisconnect(BucketManagerHost* host, base::PassKey<BucketManagerHost>); + storage::QuotaManagerProxy* quota_manager_proxy() const { + return quota_manager_proxy_.get(); + } + private: SEQUENCE_CHECKER(sequence_checker_); // Owns all instances of BucketManagerHost associated with a StoragePartition. std::map<url::Origin, std::unique_ptr<BucketManagerHost>> hosts_ GUARDED_BY_CONTEXT(sequence_checker_); + + const scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy_; }; } // namespace content
diff --git a/content/browser/buckets/bucket_manager_host.cc b/content/browser/buckets/bucket_manager_host.cc index 5a70218..c2781f2 100644 --- a/content/browser/buckets/bucket_manager_host.cc +++ b/content/browser/buckets/bucket_manager_host.cc
@@ -5,11 +5,42 @@ #include "content/browser/buckets/bucket_manager_host.h" #include "base/containers/contains.h" +#include "base/strings/string_util.h" #include "base/types/pass_key.h" +#include "components/services/storage/public/cpp/buckets/bucket_info.h" #include "content/browser/buckets/bucket_manager.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" namespace content { +namespace { + +bool IsValidBucketName(const std::string& name) { + // Details on bucket name validation and reasoning explained in + // https://github.com/WICG/storage-buckets/blob/gh-pages/explainer.md + if (name.empty() || name.length() >= 64) + return false; + + // The name must only contain characters in a restricted set. + for (char ch : name) { + if (base::IsAsciiLower(ch)) + continue; + if (base::IsAsciiDigit(ch)) + continue; + if (ch == '_' || ch == '-') + continue; + return false; + } + + // The first character in the name is more restricted. + if (name[0] == '_' || name[0] == '-') + return false; + return true; +} + +} // namespace + BucketManagerHost::BucketManagerHost(BucketManager* manager, url::Origin origin) : manager_(manager), origin_(std::move(origin)) { DCHECK(manager != nullptr); @@ -32,29 +63,43 @@ void BucketManagerHost::OpenBucket(const std::string& name, blink::mojom::BucketPoliciesPtr policy, OpenBucketCallback callback) { + if (!IsValidBucketName(name)) { + receivers_.ReportBadMessage("Invalid bucket name"); + return; + } + auto it = bucket_map_.find(name); if (it != bucket_map_.end()) { std::move(callback).Run(it->second->CreateStorageBucketBinding()); return; } - auto bucket = std::make_unique<BucketHost>(this, name, std::move(policy)); - auto pending_remote = bucket->CreateStorageBucketBinding(); - bucket_map_.emplace(name, std::move(bucket)); - std::move(callback).Run(std::move(pending_remote)); + manager_->quota_manager_proxy()->GetOrCreateBucket( + blink::StorageKey(origin_), name, base::SequencedTaskRunnerHandle::Get(), + base::BindOnce(&BucketManagerHost::DidGetBucket, + weak_factory_.GetWeakPtr(), std::move(policy), + std::move(callback))); } void BucketManagerHost::Keys(KeysCallback callback) { std::vector<std::string> keys; for (auto& bucket : bucket_map_) keys.push_back(bucket.first); + // TODO(ayui): Update to retrieve from QuotaManager. std::move(callback).Run(keys, true); } void BucketManagerHost::DeleteBucket(const std::string& name, DeleteBucketCallback callback) { - bucket_map_.erase(name); - std::move(callback).Run(true); + if (!IsValidBucketName(name)) { + receivers_.ReportBadMessage("Invalid bucket name"); + return; + } + + manager_->quota_manager_proxy()->DeleteBucket( + blink::StorageKey(origin_), name, base::SequencedTaskRunnerHandle::Get(), + base::BindOnce(&BucketManagerHost::DidDeleteBucket, + weak_factory_.GetWeakPtr(), name, std::move(callback))); } void BucketManagerHost::RemoveBucketHost(const std::string& bucket_name) { @@ -67,4 +112,36 @@ manager_->OnHostReceiverDisconnect(this, base::PassKey<BucketManagerHost>()); } +void BucketManagerHost::DidGetBucket( + blink::mojom::BucketPoliciesPtr policy, + OpenBucketCallback callback, + storage::QuotaErrorOr<storage::BucketInfo> result) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + if (!result.ok()) { + // Getting a bucket can fail if there is a database error. + std::move(callback).Run(mojo::NullRemote()); + return; + } + + const auto& bucket = result.value(); + auto bucket_host = + std::make_unique<BucketHost>(this, bucket, std::move(policy)); + auto pending_remote = bucket_host->CreateStorageBucketBinding(); + bucket_map_.emplace(bucket.name, std::move(bucket_host)); + std::move(callback).Run(std::move(pending_remote)); +} + +void BucketManagerHost::DidDeleteBucket(const std::string& bucket_name, + DeleteBucketCallback callback, + blink::mojom::QuotaStatusCode status) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (status != blink::mojom::QuotaStatusCode::kOk) { + std::move(callback).Run(false); + return; + } + bucket_map_.erase(bucket_name); + std::move(callback).Run(true); +} + } // namespace content
diff --git a/content/browser/buckets/bucket_manager_host.h b/content/browser/buckets/bucket_manager_host.h index 7336ca7..b672fe9 100644 --- a/content/browser/buckets/bucket_manager_host.h +++ b/content/browser/buckets/bucket_manager_host.h
@@ -6,11 +6,18 @@ #define CONTENT_BROWSER_BUCKETS_BUCKET_MANAGER_HOST_H_ #include "base/sequence_checker.h" +#include "components/services/storage/public/cpp/quota_error_or.h" #include "content/browser/buckets/bucket_host.h" +#include "mojo/public/cpp/bindings/message.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "third_party/blink/public/mojom/buckets/bucket_manager_host.mojom.h" +#include "third_party/blink/public/mojom/quota/quota_types.mojom-shared.h" #include "url/origin.h" +namespace storage { +struct BucketInfo; +} // namespace storage + namespace content { class BucketManager; @@ -57,6 +64,13 @@ // Called when a receiver in the receiver set is disconnected. void OnReceiverDisconnect(); + void DidGetBucket(blink::mojom::BucketPoliciesPtr policy, + OpenBucketCallback callback, + storage::QuotaErrorOr<storage::BucketInfo> result); + + void DidDeleteBucket(const std::string& bucket_name, + DeleteBucketCallback callback, + blink::mojom::QuotaStatusCode status); SEQUENCE_CHECKER(sequence_checker_); // Raw pointer is safe because BucketManager owns this BucketManagerHost, and @@ -66,13 +80,14 @@ // The origin of the frame or worker connected to this BucketManagerHost. const url::Origin origin_; - // TODO(ayui): Temporary map of buckets. This will eventually be stored in its - // own database and connect to IndexDB, Cache, Blob Storage, etc. + // Map of currently open/used buckets for an origin. std::map<std::string, std::unique_ptr<BucketHost>> bucket_map_; // Add receivers for frames & workers for `origin_` associated with // the StoragePartition that owns `manager_`. mojo::ReceiverSet<blink::mojom::BucketManagerHost> receivers_; + + base::WeakPtrFactory<BucketManagerHost> weak_factory_{this}; }; } // namespace content
diff --git a/content/browser/buckets/bucket_manager_host_unittest.cc b/content/browser/buckets/bucket_manager_host_unittest.cc new file mode 100644 index 0000000..e954a0e --- /dev/null +++ b/content/browser/buckets/bucket_manager_host_unittest.cc
@@ -0,0 +1,171 @@ +// 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 <memory> + +#include "base/files/scoped_temp_dir.h" +#include "base/run_loop.h" +#include "base/test/bind.h" +#include "base/test/task_environment.h" +#include "base/test/test_future.h" +#include "components/services/storage/public/cpp/buckets/bucket_info.h" +#include "components/services/storage/public/cpp/quota_error_or.h" +#include "content/browser/buckets/bucket_manager.h" +#include "content/browser/buckets/bucket_manager_host.h" +#include "mojo/public/cpp/test_support/test_utils.h" +#include "storage/browser/test/mock_quota_manager.h" +#include "storage/browser/test/mock_quota_manager_proxy.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" +#include "third_party/blink/public/mojom/buckets/bucket_manager_host.mojom.h" +#include "third_party/blink/public/mojom/quota/quota_types.mojom.h" +#include "url/origin.h" + +namespace content { + +namespace { + +constexpr char kTestUrl[] = "https://www.google.com"; + +} // namespace + +class BucketManagerHostTest : public testing::Test { + public: + void SetUp() override { + ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); + + quota_manager_ = base::MakeRefCounted<storage::MockQuotaManager>( + /*is_incognito=*/false, data_dir_.GetPath(), + base::ThreadTaskRunnerHandle::Get().get(), + /*special storage policy=*/nullptr); + quota_manager_proxy_ = base::MakeRefCounted<storage::MockQuotaManagerProxy>( + quota_manager_.get(), base::ThreadTaskRunnerHandle::Get()); + bucket_manager_ = + std::make_unique<BucketManager>(quota_manager_proxy_.get()); + bucket_manager_->BindReceiver( + url::Origin::Create(GURL(kTestUrl)), + bucket_manager_host_remote_.BindNewPipeAndPassReceiver(), + base::DoNothing()); + EXPECT_TRUE(bucket_manager_host_remote_.is_bound()); + } + + ~BucketManagerHostTest() override = default; + + protected: + base::ScopedTempDir data_dir_; + + // These tests need a full TaskEnvironment because it uses the thread pool for + // querying QuotaDatabase + base::test::TaskEnvironment task_environment_; + + mojo::Remote<blink::mojom::BucketManagerHost> bucket_manager_host_remote_; + std::unique_ptr<BucketManager> bucket_manager_; + scoped_refptr<storage::MockQuotaManager> quota_manager_; + scoped_refptr<storage::MockQuotaManagerProxy> quota_manager_proxy_; +}; + +TEST_F(BucketManagerHostTest, OpenBucket) { + base::RunLoop run_loop; + bucket_manager_host_remote_->OpenBucket( + "inbox_bucket", blink::mojom::BucketPolicies::New(), + base::BindLambdaForTesting( + [&](mojo::PendingRemote<blink::mojom::BucketHost> remote) { + EXPECT_TRUE(remote.is_valid()); + run_loop.Quit(); + })); + run_loop.Run(); + + // Check that bucket is in QuotaDatabase. + base::test::TestFuture<storage::QuotaErrorOr<storage::BucketInfo>> + bucket_future; + quota_manager_->GetBucket( + blink::StorageKey::CreateFromStringForTesting(kTestUrl), "inbox_bucket", + blink::mojom::StorageType::kTemporary, bucket_future.GetCallback()); + auto result = bucket_future.Take(); + EXPECT_TRUE(result.ok()); + EXPECT_GT(result->id.value(), 0u); +} + +TEST_F(BucketManagerHostTest, OpenBucketValidateName) { + const std::vector<std::pair</*is_valid=*/bool, std::string>> names = { + {false, ""}, + {false, " "}, + {false, "2021/01/01"}, + {false, "_bucket_with_underscore_start"}, + {false, "-bucket-with-dash-start"}, + {false, "UpperCaseBucketName"}, + {false, + "a_bucket_name_that_is_too_long_and_exceeds_sixty_four_characters_"}, + {true, "1"}, + {true, "bucket_with_underscore"}, + {true, "bucket-with-dash"}, + {true, "2021_01_01"}, + {true, "2021-01-01"}, + {true, "a_bucket_name_under_sixty_four_characters"}}; + + for (auto it = names.begin(); it < names.end(); ++it) { + mojo::Remote<blink::mojom::BucketManagerHost> remote; + bucket_manager_->BindReceiver(url::Origin::Create(GURL(kTestUrl)), + remote.BindNewPipeAndPassReceiver(), + base::DoNothing()); + EXPECT_TRUE(remote.is_bound()); + + if (it->first) { + base::RunLoop run_loop; + remote->OpenBucket( + it->second, blink::mojom::BucketPolicies::New(), + base::BindLambdaForTesting( + [&](mojo::PendingRemote<blink::mojom::BucketHost> remote) { + EXPECT_EQ(remote.is_valid(), it->first); + run_loop.Quit(); + })); + run_loop.Run(); + } else { + mojo::test::BadMessageObserver bad_message_observer; + remote->OpenBucket(it->second, blink::mojom::BucketPolicies::New(), + blink::mojom::BucketManagerHost::OpenBucketCallback()); + remote.FlushForTesting(); + EXPECT_EQ("Invalid bucket name", + bad_message_observer.WaitForBadMessage()); + } + } +} + +TEST_F(BucketManagerHostTest, DeleteBucket) { + base::RunLoop run_loop; + bucket_manager_host_remote_->OpenBucket( + "inbox_bucket", blink::mojom::BucketPolicies::New(), + base::BindLambdaForTesting( + [&](mojo::PendingRemote<blink::mojom::BucketHost> remote) { + EXPECT_TRUE(remote.is_valid()); + run_loop.Quit(); + })); + run_loop.Run(); + + base::test::TestFuture<bool> delete_future; + bucket_manager_host_remote_->DeleteBucket("inbox_bucket", + delete_future.GetCallback()); + bool deleted = delete_future.Get(); + EXPECT_TRUE(deleted); + + // Check that bucket is not in QuotaDatabase. + base::test::TestFuture<storage::QuotaErrorOr<storage::BucketInfo>> + bucket_future; + quota_manager_->GetBucket( + blink::StorageKey::CreateFromStringForTesting(kTestUrl), "inbox_bucket", + blink::mojom::StorageType::kTemporary, bucket_future.GetCallback()); + auto result = bucket_future.Take(); + EXPECT_FALSE(result.ok()); + EXPECT_EQ(result.error(), storage::QuotaError::kNotFound); +} + +TEST_F(BucketManagerHostTest, DeleteInvalidBucketName) { + mojo::test::BadMessageObserver bad_message_observer; + bucket_manager_host_remote_->DeleteBucket("InvalidBucket", base::DoNothing()); + bucket_manager_host_remote_.FlushForTesting(); + EXPECT_EQ("Invalid bucket name", bad_message_observer.WaitForBadMessage()); +} + +} // namespace content
diff --git a/content/browser/cache_storage/cache_storage_index.h b/content/browser/cache_storage/cache_storage_index.h index cc29b3d..6772d86 100644 --- a/content/browser/cache_storage/cache_storage_index.h +++ b/content/browser/cache_storage/cache_storage_index.h
@@ -11,6 +11,7 @@ #include "base/gtest_prod_util.h" #include "content/browser/cache_storage/cache_storage.h" +#include "content/common/content_export.h" namespace content {
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage.h b/content/browser/cache_storage/legacy/legacy_cache_storage.h index 25f8b90..d80fba3 100644 --- a/content/browser/cache_storage/legacy/legacy_cache_storage.h +++ b/content/browser/cache_storage/legacy/legacy_cache_storage.h
@@ -23,6 +23,7 @@ #include "content/browser/cache_storage/cache_storage_manager.h" #include "content/browser/cache_storage/cache_storage_scheduler_types.h" #include "content/browser/cache_storage/legacy/legacy_cache_storage_cache.h" +#include "content/common/content_export.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/blink/public/common/storage_key/storage_key.h"
diff --git a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h index 1dde452..08f10802 100644 --- a/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h +++ b/content/browser/cache_storage/legacy/legacy_cache_storage_cache.h
@@ -21,6 +21,7 @@ #include "content/browser/cache_storage/cache_storage_handle.h" #include "content/browser/cache_storage/cache_storage_manager.h" #include "content/browser/cache_storage/scoped_writable_entry.h" +#include "content/common/content_export.h" #include "net/base/completion_once_callback.h" #include "net/base/io_buffer.h" #include "net/disk_cache/disk_cache.h"
diff --git a/content/browser/child_process_security_policy_impl.h b/content/browser/child_process_security_policy_impl.h index beb689d..01904ae 100644 --- a/content/browser/child_process_security_policy_impl.h +++ b/content/browser/child_process_security_policy_impl.h
@@ -25,6 +25,7 @@ #include "content/browser/isolation_context.h" #include "content/browser/origin_agent_cluster_isolation_state.h" #include "content/browser/site_instance_impl.h" +#include "content/common/content_export.h" #include "content/public/browser/child_process_security_policy.h" #include "storage/common/file_system/file_system_types.h" #include "url/origin.h"
diff --git a/content/browser/client_hints/client_hints.h b/content/browser/client_hints/client_hints.h index a51f193..78583c53 100644 --- a/content/browser/client_hints/client_hints.h +++ b/content/browser/client_hints/client_hints.h
@@ -8,6 +8,7 @@ #include <memory> #include <string> +#include "content/common/content_export.h" #include "content/public/browser/client_hints_controller_delegate.h" #include "net/http/http_request_headers.h" #include "services/network/public/mojom/parsed_headers.mojom-forward.h"
diff --git a/content/browser/cross_origin_opener_policy_browsertest.cc b/content/browser/cross_origin_opener_policy_browsertest.cc index 2ceb8a7..32be26e 100644 --- a/content/browser/cross_origin_opener_policy_browsertest.cc +++ b/content/browser/cross_origin_opener_policy_browsertest.cc
@@ -2301,6 +2301,25 @@ EXPECT_NE(group_4, group_1); } +// A test to make sure that loading a page with COOP/COEP headers doesn't set +// is_origin_keyed() on the SiteInstance's SiteInfo. +IN_PROC_BROWSER_TEST_P(CrossOriginOpenerPolicyBrowserTest, + CoopCoepNotOriginKeyed) { + GURL isolated_page( + https_server()->GetURL("a.com", + "/set-header?" + "Cross-Origin-Opener-Policy: same-origin&" + "Cross-Origin-Embedder-Policy: require-corp")); + + EXPECT_TRUE(NavigateToURL(shell(), isolated_page)); + SiteInstanceImpl* current_si = current_frame_host()->GetSiteInstance(); + EXPECT_TRUE(current_si->IsCrossOriginIsolated()); + // Use of COOP/COEP headers should not cause SiteInfo::is_origin_keyed() to + // return true. The metrics that track OriginAgentCluster isolation expect + // is_origin_keyed() to refer only to the OriginAgentCluster header. + EXPECT_FALSE(current_si->GetSiteInfo().requires_origin_keyed_process()); +} + // This test is flaky on Win, Mac, Linux and ChromeOS: https://crbug.com/1125998 #if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \ defined(OS_CHROMEOS)
diff --git a/content/browser/devtools/protocol/input_handler.cc b/content/browser/devtools/protocol/input_handler.cc index 7cc2fab0..18ccc68 100644 --- a/content/browser/devtools/protocol/input_handler.cc +++ b/content/browser/devtools/protocol/input_handler.cc
@@ -133,6 +133,7 @@ bool GetMouseEventButton(const std::string& button, blink::WebPointerProperties::Button* event_button, int* event_modifiers) { + *event_modifiers = blink::WebInputEvent::kFromDebugger; if (button.empty()) return true; @@ -140,19 +141,19 @@ *event_button = blink::WebMouseEvent::Button::kNoButton; } else if (button == Input::MouseButtonEnum::Left) { *event_button = blink::WebMouseEvent::Button::kLeft; - *event_modifiers = blink::WebInputEvent::kLeftButtonDown; + *event_modifiers |= blink::WebInputEvent::kLeftButtonDown; } else if (button == Input::MouseButtonEnum::Middle) { *event_button = blink::WebMouseEvent::Button::kMiddle; - *event_modifiers = blink::WebInputEvent::kMiddleButtonDown; + *event_modifiers |= blink::WebInputEvent::kMiddleButtonDown; } else if (button == Input::MouseButtonEnum::Right) { *event_button = blink::WebMouseEvent::Button::kRight; - *event_modifiers = blink::WebInputEvent::kRightButtonDown; + *event_modifiers |= blink::WebInputEvent::kRightButtonDown; } else if (button == Input::MouseButtonEnum::Back) { *event_button = blink::WebMouseEvent::Button::kBack; - *event_modifiers = blink::WebInputEvent::kBackButtonDown; + *event_modifiers |= blink::WebInputEvent::kBackButtonDown; } else if (button == Input::MouseButtonEnum::Forward) { *event_button = blink::WebMouseEvent::Button::kForward; - *event_modifiers = blink::WebInputEvent::kForwardButtonDown; + *event_modifiers |= blink::WebInputEvent::kForwardButtonDown; } else { return false; } @@ -1368,7 +1369,7 @@ if (!synthetic_pointer_driver_) { synthetic_pointer_driver_ = - SyntheticPointerDriver::Create(gesture_source_type); + SyntheticPointerDriver::Create(gesture_source_type, true); } std::unique_ptr<SyntheticPointerAction> synthetic_gesture = std::make_unique<SyntheticPointerAction>(action_list_params); @@ -1564,6 +1565,7 @@ SyntheticPinchGestureParams gesture_params; const int kDefaultRelativeSpeed = 800; + gesture_params.from_devtools_debugger = true; gesture_params.scale_factor = scale_factor; gesture_params.anchor = CssPixelsToPointF(x, y, page_scale_factor_); if (!PointIsWithinContents(gesture_params.anchor)) { @@ -1613,6 +1615,7 @@ } SyntheticSmoothScrollGestureParams gesture_params; + gesture_params.from_devtools_debugger = true; const bool kDefaultPreventFling = true; const int kDefaultSpeed = 800; @@ -1724,6 +1727,7 @@ const int kDefaultTapCount = 1; gesture_params.position = CssPixelsToPointF(x, y, page_scale_factor_); + gesture_params.from_devtools_debugger = true; if (!PointIsWithinContents(gesture_params.position)) { callback->sendFailure(Response::InvalidParams("Position out of bounds")); return;
diff --git a/content/browser/devtools/shared_worker_devtools_manager.h b/content/browser/devtools/shared_worker_devtools_manager.h index d4a9017..fa4263a 100644 --- a/content/browser/devtools/shared_worker_devtools_manager.h +++ b/content/browser/devtools/shared_worker_devtools_manager.h
@@ -11,6 +11,7 @@ #include "base/gtest_prod_util.h" #include "base/memory/singleton.h" #include "base/unguessable_token.h" +#include "content/common/content_export.h" #include "content/public/browser/devtools_agent_host.h" #include "third_party/blink/public/mojom/devtools/devtools_agent.mojom.h"
diff --git a/content/browser/devtools/worker_devtools_manager.h b/content/browser/devtools/worker_devtools_manager.h index cdfab5e4a..180fff6 100644 --- a/content/browser/devtools/worker_devtools_manager.h +++ b/content/browser/devtools/worker_devtools_manager.h
@@ -10,6 +10,7 @@ #include "base/memory/singleton.h" #include "content/browser/devtools/devtools_agent_host_impl.h" #include "content/browser/devtools/devtools_throttle_handle.h" +#include "content/common/content_export.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/global_routing_id.h" #include "third_party/blink/public/mojom/devtools/devtools_agent.mojom.h"
diff --git a/content/browser/download/drag_download_util.h b/content/browser/download/drag_download_util.h index 57c9e0f2..10260a2 100644 --- a/content/browser/download/drag_download_util.h +++ b/content/browser/download/drag_download_util.h
@@ -10,6 +10,7 @@ #include "base/files/file.h" #include "base/memory/ref_counted.h" #include "content/browser/download/drag_download_file.h" +#include "content/common/content_export.h" #include "ui/base/dragdrop/download_file_interface.h" class GURL;
diff --git a/content/browser/file_system_access/file_system_access_capacity_allocation_host_impl.h b/content/browser/file_system_access/file_system_access_capacity_allocation_host_impl.h index c6619f6..51a3769 100644 --- a/content/browser/file_system_access/file_system_access_capacity_allocation_host_impl.h +++ b/content/browser/file_system_access/file_system_access_capacity_allocation_host_impl.h
@@ -8,6 +8,7 @@ #include "base/memory/weak_ptr.h" #include "base/types/pass_key.h" #include "content/browser/file_system_access/file_system_access_manager_impl.h" +#include "content/common/content_export.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" #include "storage/browser/file_system/file_system_context.h"
diff --git a/content/browser/file_system_access/file_system_access_file_delegate_host_impl.h b/content/browser/file_system_access/file_system_access_file_delegate_host_impl.h index ad8615e..0d1068b 100644 --- a/content/browser/file_system_access/file_system_access_file_delegate_host_impl.h +++ b/content/browser/file_system_access/file_system_access_file_delegate_host_impl.h
@@ -7,6 +7,7 @@ #include "components/services/storage/public/cpp/big_io_buffer.h" #include "content/browser/file_system_access/file_system_access_manager_impl.h" +#include "content/common/content_export.h" #include "storage/browser/file_system/file_stream_reader.h" #include "storage/browser/file_system/file_system_url.h" #include "third_party/blink/public/mojom/file_system_access/file_system_access_file_delegate_host.mojom.h"
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index 0251fbd..060f822 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc
@@ -20,7 +20,6 @@ #include "base/system/sys_info.h" #include "base/values.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "cc/base/switches.h" #include "components/viz/common/features.h" #include "content/browser/compositor/image_transport_factory.h" @@ -154,6 +153,18 @@ "Accelerated video decode has been disabled, either via blocklist, " "about:flags or the command line."), true}, + {"video_encode", + SafeGetFeatureStatus(gpu_feature_info, + gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE), +#if defined(OS_LINUX) + !base::FeatureList::IsEnabled(media::kVaapiVideoEncodeLinux), +#else + command_line.HasSwitch(switches::kDisableAcceleratedVideoEncode), +#endif // defined(OS_LINUX) + DisableInfo::Problem( + "Accelerated video encode has been disabled, either via blocklist, " + "about:flags or the command line."), + true}, {"rasterization", SafeGetFeatureStatus(gpu_feature_info, gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION), @@ -393,7 +404,7 @@ int num_processors = base::SysInfo::NumberOfProcessors(); #if defined(OS_ANDROID) || \ - (BUILDFLAG(IS_CHROMEOS_ASH) && defined(ARCH_CPU_ARM_FAMILY)) + (defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)) // Android and ChromeOS ARM devices may report 6 to 8 CPUs for big.LITTLE // configurations. Limit the number of raster threads based on maximum of // 4 big cores.
diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h index 9b850c0..8e80ced 100644 --- a/content/browser/gpu/gpu_data_manager_impl.h +++ b/content/browser/gpu/gpu_data_manager_impl.h
@@ -18,6 +18,7 @@ #include "base/thread_annotations.h" #include "base/values.h" #include "build/build_config.h" +#include "content/common/content_export.h" #include "content/public/browser/gpu_data_manager.h" #include "content/public/common/three_d_api_types.h" #include "gpu/config/device_perf_info.h"
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.h b/content/browser/gpu/gpu_data_manager_impl_private.h index ce7af71..14749a1 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.h +++ b/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -23,6 +23,7 @@ #include "base/values.h" #include "build/build_config.h" #include "content/browser/gpu/gpu_data_manager_impl.h" +#include "content/common/content_export.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/display/display_observer.h" #include "ui/gl/gpu_preference.h"
diff --git a/content/browser/gpu/gpu_feature_checker_impl.h b/content/browser/gpu/gpu_feature_checker_impl.h index 23ba1b01..3f25fcc2 100644 --- a/content/browser/gpu/gpu_feature_checker_impl.h +++ b/content/browser/gpu/gpu_feature_checker_impl.h
@@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/memory/ref_counted.h" +#include "content/common/content_export.h" #include "content/public/browser/gpu_data_manager_observer.h" #include "content/public/browser/gpu_feature_checker.h" #include "gpu/config/gpu_feature_type.h"
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 9d8fa4f0..8373813 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -230,10 +230,7 @@ sandbox::policy::switches::kGpuSandboxFailuresFatal, sandbox::policy::switches::kDisableGpuSandbox, sandbox::policy::switches::kNoSandbox, -// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch -// of lacros-chrome is complete. -#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_ASH) && \ - !BUILDFLAG(IS_CHROMEOS_LACROS) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) switches::kDisableDevShmUsage, #endif #if defined(OS_WIN)
diff --git a/content/browser/host_zoom_map_impl.h b/content/browser/host_zoom_map_impl.h index 4be66727..df9b8143 100644 --- a/content/browser/host_zoom_map_impl.h +++ b/content/browser/host_zoom_map_impl.h
@@ -12,6 +12,7 @@ #include "base/compiler_specific.h" #include "base/task/sequenced_task_runner_helpers.h" +#include "content/common/content_export.h" #include "content/public/browser/host_zoom_map.h" namespace content {
diff --git a/content/browser/indexed_db/indexed_db_callbacks.h b/content/browser/indexed_db/indexed_db_callbacks.h index 88e667c..2dab7eb 100644 --- a/content/browser/indexed_db/indexed_db_callbacks.h +++ b/content/browser/indexed_db/indexed_db_callbacks.h
@@ -15,6 +15,7 @@ #include "base/sequence_checker.h" #include "content/browser/indexed_db/indexed_db_database_error.h" #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" +#include "content/common/content_export.h" #include "mojo/public/cpp/bindings/associated_remote.h" #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "storage/browser/blob/blob_storage_context.h"
diff --git a/content/browser/indexed_db/indexed_db_connection.h b/content/browser/indexed_db/indexed_db_connection.h index c409ef48..0db3f65 100644 --- a/content/browser/indexed_db/indexed_db_connection.h +++ b/content/browser/indexed_db/indexed_db_connection.h
@@ -14,6 +14,7 @@ #include "base/memory/weak_ptr.h" #include "content/browser/indexed_db/indexed_db_database.h" #include "content/browser/indexed_db/indexed_db_storage_key_state_handle.h" +#include "content/common/content_export.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" namespace content {
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h index 10e0931..6819308 100644 --- a/content/browser/indexed_db/indexed_db_context_impl.h +++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -27,6 +27,7 @@ #include "components/services/storage/public/mojom/storage_policy_update.mojom.h" #include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" +#include "content/common/content_export.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver_set.h"
diff --git a/content/browser/indexed_db/indexed_db_control_wrapper.h b/content/browser/indexed_db/indexed_db_control_wrapper.h index f8aa5270..6c4a811 100644 --- a/content/browser/indexed_db/indexed_db_control_wrapper.h +++ b/content/browser/indexed_db/indexed_db_control_wrapper.h
@@ -9,6 +9,7 @@ #include "components/services/storage/public/mojom/indexed_db_control.mojom.h" #include "components/services/storage/public/mojom/storage_policy_update.mojom.h" #include "content/browser/indexed_db/indexed_db_context_impl.h" +#include "content/common/content_export.h" #include "storage/browser/quota/storage_policy_observer.h" namespace blink {
diff --git a/content/browser/indexed_db/indexed_db_cursor.h b/content/browser/indexed_db/indexed_db_cursor.h index 4c87ac9..ec3d620e 100644 --- a/content/browser/indexed_db/indexed_db_cursor.h +++ b/content/browser/indexed_db/indexed_db_cursor.h
@@ -14,6 +14,7 @@ #include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_database.h" #include "content/browser/indexed_db/indexed_db_transaction.h" +#include "content/common/content_export.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h"
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.h b/content/browser/indexed_db/indexed_db_factory_impl.h index 09373f0..dea35ce 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.h +++ b/content/browser/indexed_db/indexed_db_factory_impl.h
@@ -31,6 +31,7 @@ #include "content/browser/indexed_db/indexed_db_factory.h" #include "content/browser/indexed_db/indexed_db_storage_key_state_handle.h" #include "content/browser/indexed_db/indexed_db_task_helper.h" +#include "content/common/content_export.h" #include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/leveldatabase/src/include/leveldb/status.h"
diff --git a/content/browser/indexed_db/indexed_db_transaction.h b/content/browser/indexed_db/indexed_db_transaction.h index 2a7ba17..f6d91afbe 100644 --- a/content/browser/indexed_db/indexed_db_transaction.h +++ b/content/browser/indexed_db/indexed_db_transaction.h
@@ -26,6 +26,7 @@ #include "content/browser/indexed_db/indexed_db_database_error.h" #include "content/browser/indexed_db/indexed_db_external_object_storage.h" #include "content/browser/indexed_db/indexed_db_task_helper.h" +#include "content/common/content_export.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h"
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h index e2d3c4f0..3f4c684 100644 --- a/content/browser/loader/navigation_url_loader_impl.h +++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -10,6 +10,7 @@ #include "content/browser/loader/navigation_url_loader.h" #include "content/browser/loader/single_request_url_loader_factory.h" #include "content/browser/navigation_subresource_loader_params.h" +#include "content/common/content_export.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/ssl_status.h"
diff --git a/content/browser/media/android/browser_gpu_video_accelerator_factories.cc b/content/browser/media/android/browser_gpu_video_accelerator_factories.cc index 4f8b975..46ffa34 100644 --- a/content/browser/media/android/browser_gpu_video_accelerator_factories.cc +++ b/content/browser/media/android/browser_gpu_video_accelerator_factories.cc
@@ -79,7 +79,11 @@ BrowserGpuVideoAcceleratorFactories::~BrowserGpuVideoAcceleratorFactories() = default; -bool BrowserGpuVideoAcceleratorFactories::IsGpuVideoAcceleratorEnabled() { +bool BrowserGpuVideoAcceleratorFactories::IsGpuVideoDecodeAcceleratorEnabled() { + return false; +} + +bool BrowserGpuVideoAcceleratorFactories::IsGpuVideoEncodeAcceleratorEnabled() { return false; }
diff --git a/content/browser/media/android/browser_gpu_video_accelerator_factories.h b/content/browser/media/android/browser_gpu_video_accelerator_factories.h index d0698ed2..09c6e50f 100644 --- a/content/browser/media/android/browser_gpu_video_accelerator_factories.h +++ b/content/browser/media/android/browser_gpu_video_accelerator_factories.h
@@ -31,7 +31,8 @@ private: // media::GpuVideoAcceleratorFactories implementation. - bool IsGpuVideoAcceleratorEnabled() override; + bool IsGpuVideoDecodeAcceleratorEnabled() override; + bool IsGpuVideoEncodeAcceleratorEnabled() override; void GetChannelToken( gpu::mojom::GpuChannel::GetChannelTokenCallback cb) override; int32_t GetCommandBufferRouteId() override;
diff --git a/content/browser/media/capture/web_contents_frame_tracker.h b/content/browser/media/capture/web_contents_frame_tracker.h index 5e88bcd..96c9e73 100644 --- a/content/browser/media/capture/web_contents_frame_tracker.h +++ b/content/browser/media/capture/web_contents_frame_tracker.h
@@ -12,6 +12,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "components/viz/common/surfaces/frame_sink_id.h" +#include "content/common/content_export.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_media_capture_id.h"
diff --git a/content/browser/media/media_stream_web_contents_observer.h b/content/browser/media/media_stream_web_contents_observer.h index cab6c85..45a4bcb8 100644 --- a/content/browser/media/media_stream_web_contents_observer.h +++ b/content/browser/media/media_stream_web_contents_observer.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_MEDIA_MEDIA_STREAM_WEB_CONTENTS_OBSERVER_H_ #define CONTENT_BROWSER_MEDIA_MEDIA_STREAM_WEB_CONTENTS_OBSERVER_H_ +#include "content/common/content_export.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" @@ -26,4 +27,4 @@ } // namespace content -#endif // CONTENT_BROWSER_MEDIA_MEDIA_STREAM_WEB_CONTENTS_OBSERVER_H_ \ No newline at end of file +#endif // CONTENT_BROWSER_MEDIA_MEDIA_STREAM_WEB_CONTENTS_OBSERVER_H_
diff --git a/content/browser/notifications/notification_storage.h b/content/browser/notifications/notification_storage.h index 7378782..16fc6c2 100644 --- a/content/browser/notifications/notification_storage.h +++ b/content/browser/notifications/notification_storage.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_NOTIFICATIONS_NOTIFICATION_STORAGE_H_ #include "content/browser/service_worker/service_worker_context_wrapper.h" +#include "content/common/content_export.h" #include "content/public/browser/platform_notification_context.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
diff --git a/content/browser/prerender/prerender_attributes.h b/content/browser/prerender/prerender_attributes.h index 6960efd..db412cc 100644 --- a/content/browser/prerender/prerender_attributes.h +++ b/content/browser/prerender/prerender_attributes.h
@@ -7,6 +7,7 @@ #include <string> +#include "content/common/content_export.h" #include "content/public/common/referrer.h" #include "services/metrics/public/cpp/ukm_source_id.h" #include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h"
diff --git a/content/browser/prerender/prerender_browsertest.cc b/content/browser/prerender/prerender_browsertest.cc index 60e7c05..a87c57a 100644 --- a/content/browser/prerender/prerender_browsertest.cc +++ b/content/browser/prerender/prerender_browsertest.cc
@@ -11,6 +11,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/ignore_result.h" #include "base/memory/weak_ptr.h" +#include "base/metrics/metrics_hashes.h" #include "base/run_loop.h" #include "base/scoped_observation.h" #include "base/synchronization/lock.h" @@ -88,6 +89,10 @@ #include "ui/shell_dialogs/select_file_dialog_factory.h" #include "url/gurl.h" +#if BUILDFLAG(ENABLE_PLUGINS) +#include "content/common/pepper_plugin.mojom.h" +#endif // BUILDFLAG(ENABLE_PLUGINS) + using ::testing::Exactly; namespace content { @@ -110,6 +115,10 @@ } } +int32_t InterfaceNameHasher(const std::string& interface_name) { + return static_cast<int32_t>(base::HashMetricNameAs32Bits(interface_name)); +} + RenderFrameHost* FindRenderFrameHost(Page& page, const GURL& url) { return content::FrameMatchingPredicate( page, base::BindRepeating(&content::FrameHasSourceUrl, url)); @@ -894,7 +903,8 @@ AssertPrerenderHistoryLength(host_id, prerender_frame_host); EXPECT_EQ("state1", EvalJs(prerender_frame_host, "history.state")); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); EXPECT_TRUE(capturer.did_replace_entry()); } @@ -912,7 +922,8 @@ AssertPrerenderHistoryLength(host_id, prerender_frame_host); EXPECT_EQ("state2", EvalJs(prerender_frame_host, "history.state")); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); EXPECT_TRUE(capturer.did_replace_entry()); } @@ -933,7 +944,8 @@ // history.state should be replaced with a fragment navigation. EXPECT_EQ(nullptr, EvalJs(prerender_frame_host, "history.state")); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); EXPECT_TRUE(capturer.did_replace_entry()); } @@ -1082,7 +1094,8 @@ TestNavigationHistory(k2ndUrl, 1, 3); EXPECT_EQ(nullptr, EvalJs(web_contents(), "history.state")); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); } @@ -1094,7 +1107,8 @@ TestNavigationHistory(kPrerenderingUrl, 2, 3); EXPECT_EQ("teststate", EvalJs(web_contents(), "history.state")); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); } } @@ -1900,6 +1914,9 @@ histogram_tester.ExpectUniqueSample( "Prerender.Experimental.PrerenderCancelledInterface", PrerenderCancelledInterface::kUnknown, 1); + histogram_tester.ExpectUniqueSample( + "Prerender.Experimental.PrerenderUnknownCancelledInterface", + InterfaceNameHasher(mojom::TestInterfaceForCancel::Name_), 1); SetBrowserClientForTesting(old_browser_client); } @@ -1948,6 +1965,9 @@ histogram_tester.ExpectUniqueSample( "Prerender.Experimental.PrerenderCancelledInterface", PrerenderCancelledInterface::kUnknown, 1); + histogram_tester.ExpectUniqueSample( + "Prerender.Experimental.PrerenderUnknownCancelledInterface", + InterfaceNameHasher(mojom::TestInterfaceForCancel::Name_), 1); } // Tests that mojo capability control will crash the prerender if the browser @@ -2671,6 +2691,12 @@ histogram_tester.ExpectUniqueSample( "Prerender.Experimental.PrerenderHostFinalStatus", PrerenderHost::FinalStatus::kMojoBinderPolicy, 1); + histogram_tester.ExpectUniqueSample( + "Prerender.Experimental.PrerenderCancelledInterface", + PrerenderCancelledInterface::kUnknown, 1); + histogram_tester.ExpectUniqueSample( + "Prerender.Experimental.PrerenderUnknownCancelledInterface", + InterfaceNameHasher(mojom::PepperHost::Name_), 1); // TODO(https://crbug.com/1215031): Remove this reload after fixing the issue. // Now a document cannot trigger prerendering twice, even if the first started @@ -2683,6 +2709,12 @@ histogram_tester.ExpectUniqueSample( "Prerender.Experimental.PrerenderHostFinalStatus", PrerenderHost::FinalStatus::kMojoBinderPolicy, 2); + histogram_tester.ExpectUniqueSample( + "Prerender.Experimental.PrerenderCancelledInterface", + PrerenderCancelledInterface::kUnknown, 2); + histogram_tester.ExpectUniqueSample( + "Prerender.Experimental.PrerenderUnknownCancelledInterface", + InterfaceNameHasher(mojom::PepperHost::Name_), 2); } #endif // BUILDFLAG(ENABLE_PLUGINS)
diff --git a/content/browser/prerender/prerender_metrics.cc b/content/browser/prerender/prerender_metrics.cc index 0b9e3289..4b07481 100644 --- a/content/browser/prerender/prerender_metrics.cc +++ b/content/browser/prerender/prerender_metrics.cc
@@ -5,6 +5,7 @@ #include "content/browser/prerender/prerender_metrics.h" #include "base/metrics/histogram_functions.h" +#include "base/metrics/metrics_hashes.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" @@ -24,6 +25,10 @@ return PrerenderCancelledInterface::kUnknown; } +int32_t InterfaceNameHasher(const std::string& interface_name) { + return static_cast<int32_t>(base::HashMetricNameAs32Bits(interface_name)); +} + } // namespace // Called by MojoBinderPolicyApplier. This function records the Mojo interface @@ -33,6 +38,14 @@ GetCancelledInterfaceType(interface_name); base::UmaHistogramEnumeration( "Prerender.Experimental.PrerenderCancelledInterface", interface_type); + if (interface_type == PrerenderCancelledInterface::kUnknown) { + // These interfaces can be required by embedders, or not set to kCancel + // expclitly, e.g., channel-associated interfaces. Record these interfaces + // with the sparse histogram to ensure all of them are tracked. + base::UmaHistogramSparse( + "Prerender.Experimental.PrerenderUnknownCancelledInterface", + InterfaceNameHasher(interface_name)); + } } void RecordPrerenderTriggered(ukm::SourceId ukm_id) {
diff --git a/content/browser/renderer_host/ancestor_throttle.h b/content/browser/renderer_host/ancestor_throttle.h index 3a740c1..eb954b3 100644 --- a/content/browser/renderer_host/ancestor_throttle.h +++ b/content/browser/renderer_host/ancestor_throttle.h
@@ -9,6 +9,7 @@ #include <string> #include "base/gtest_prod_util.h" +#include "content/common/content_export.h" #include "content/public/browser/navigation_throttle.h" #include "services/network/public/mojom/content_security_policy.mojom-forward.h" #include "services/network/public/mojom/x_frame_options.mojom-forward.h"
diff --git a/content/browser/renderer_host/back_forward_cache_can_store_document_result.h b/content/browser/renderer_host/back_forward_cache_can_store_document_result.h index 753cca2..fc4dcf9 100644 --- a/content/browser/renderer_host/back_forward_cache_can_store_document_result.h +++ b/content/browser/renderer_host/back_forward_cache_can_store_document_result.h
@@ -13,6 +13,7 @@ #include "base/trace_event/typed_macros.h" #include "content/browser/renderer_host/back_forward_cache_metrics.h" #include "content/browser/renderer_host/should_swap_browsing_instance.h" +#include "content/common/content_export.h" #include "content/public/browser/back_forward_cache.h" #include "content/public/browser/render_frame_host.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/content/browser/renderer_host/back_forward_cache_impl.cc b/content/browser/renderer_host/back_forward_cache_impl.cc index 38818e9..ac7cb84 100644 --- a/content/browser/renderer_host/back_forward_cache_impl.cc +++ b/content/browser/renderer_host/back_forward_cache_impl.cc
@@ -98,7 +98,7 @@ if (!IsBackForwardCacheEnabled()) return false; static constexpr base::FeatureParam<bool> content_injection_supported( - &features::kBackForwardCache, "content_injection_supported", false); + &features::kBackForwardCache, "content_injection_supported", true); return content_injection_supported.Get(); }
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.h b/content/browser/renderer_host/browser_compositor_view_mac.h index e70feb3..84a6ed0 100644 --- a/content/browser/renderer_host/browser_compositor_view_mac.h +++ b/content/browser/renderer_host/browser_compositor_view_mac.h
@@ -13,6 +13,7 @@ #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "components/viz/common/surfaces/scoped_surface_id_allocator.h" #include "content/browser/renderer_host/delegated_frame_host.h" +#include "content/common/content_export.h" #include "ui/compositor/compositor.h" #include "ui/compositor/compositor_observer.h" #include "ui/compositor/layer_observer.h"
diff --git a/content/browser/renderer_host/frame_navigation_entry.h b/content/browser/renderer_host/frame_navigation_entry.h index 1c5656fc..f584cfa 100644 --- a/content/browser/renderer_host/frame_navigation_entry.h +++ b/content/browser/renderer_host/frame_navigation_entry.h
@@ -10,6 +10,7 @@ #include "base/memory/ref_counted.h" #include "content/browser/renderer_host/policy_container_host.h" #include "content/browser/site_instance_impl.h" +#include "content/common/content_export.h" #include "content/public/common/referrer.h" #include "services/network/public/cpp/resource_request_body.h" #include "services/network/public/cpp/shared_url_loader_factory.h"
diff --git a/content/browser/renderer_host/input/fling_controller.h b/content/browser/renderer_host/input/fling_controller.h index b1b84341..5614a28 100644 --- a/content/browser/renderer_host/input/fling_controller.h +++ b/content/browser/renderer_host/input/fling_controller.h
@@ -7,6 +7,7 @@ #include "content/browser/renderer_host/input/touchpad_tap_suppression_controller.h" #include "content/browser/renderer_host/input/touchscreen_tap_suppression_controller.h" +#include "content/common/content_export.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h" #include "ui/events/blink/fling_booster.h"
diff --git a/content/browser/renderer_host/input/fling_scheduler.h b/content/browser/renderer_host/input/fling_scheduler.h index 4380bbe..b0b88bf 100644 --- a/content/browser/renderer_host/input/fling_scheduler.h +++ b/content/browser/renderer_host/input/fling_scheduler.h
@@ -7,6 +7,7 @@ #include "content/browser/renderer_host/input/fling_controller.h" #include "content/browser/renderer_host/input/fling_scheduler_base.h" +#include "content/common/content_export.h" #include "ui/compositor/compositor_animation_observer.h" namespace ui {
diff --git a/content/browser/renderer_host/input/fling_scheduler_mac.h b/content/browser/renderer_host/input/fling_scheduler_mac.h index d84d7d4..5876b0b 100644 --- a/content/browser/renderer_host/input/fling_scheduler_mac.h +++ b/content/browser/renderer_host/input/fling_scheduler_mac.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_RENDERER_HOST_INPUT_FLING_SCHEDULER_MAC_H_ #include "content/browser/renderer_host/input/fling_scheduler.h" +#include "content/common/content_export.h" namespace content {
diff --git a/content/browser/renderer_host/input/input_disposition_handler.h b/content/browser/renderer_host/input/input_disposition_handler.h index 41f7084..8695c334 100644 --- a/content/browser/renderer_host/input/input_disposition_handler.h +++ b/content/browser/renderer_host/input/input_disposition_handler.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_RENDERER_HOST_INPUT_INPUT_DISPOSITION_HANDLER_H_ #include "content/browser/renderer_host/event_with_latency_info.h" +#include "content/common/content_export.h" #include "content/public/browser/native_web_keyboard_event.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h"
diff --git a/content/browser/renderer_host/input/input_injector_impl.h b/content/browser/renderer_host/input/input_injector_impl.h index 6595ce8..8ae7d45b 100644 --- a/content/browser/renderer_host/input/input_injector_impl.h +++ b/content/browser/renderer_host/input/input_injector_impl.h
@@ -9,6 +9,7 @@ #include "content/browser/renderer_host/input/synthetic_gesture.h" #include "content/browser/renderer_host/render_frame_host_impl.h" +#include "content/common/content_export.h" #include "content/common/input/input_injector.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
diff --git a/content/browser/renderer_host/input/input_router.h b/content/browser/renderer_host/input/input_router.h index 0e22be11..64cc7a613 100644 --- a/content/browser/renderer_host/input/input_router.h +++ b/content/browser/renderer_host/input/input_router.h
@@ -10,6 +10,7 @@ #include "content/browser/renderer_host/event_with_latency_info.h" #include "content/browser/renderer_host/input/gesture_event_queue.h" #include "content/browser/renderer_host/input/passthrough_touch_event_queue.h" +#include "content/common/content_export.h" #include "content/public/browser/native_web_keyboard_event.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/content/browser/renderer_host/input/input_router_impl.h b/content/browser/renderer_host/input/input_router_impl.h index ed03640..938da09 100644 --- a/content/browser/renderer_host/input/input_router_impl.h +++ b/content/browser/renderer_host/input/input_router_impl.h
@@ -21,6 +21,7 @@ #include "content/browser/renderer_host/input/passthrough_touch_event_queue.h" #include "content/browser/renderer_host/input/touch_action_filter.h" #include "content/browser/renderer_host/input/touchpad_pinch_event_queue.h" +#include "content/common/content_export.h" #include "content/common/input/input_event_stream_validator.h" #include "content/public/browser/native_web_keyboard_event.h" #include "mojo/public/cpp/bindings/pending_remote.h"
diff --git a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc index db6bbafc..c5848f1 100644 --- a/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc +++ b/content/browser/renderer_host/input/synthetic_gesture_target_aura.cc
@@ -63,12 +63,19 @@ aura::Window* window = GetWindow(); aura::WindowTreeHost* host = window->GetHost(); - for (const auto& event : events) { - event->ConvertLocationToTarget(window, host->window()); - ui::EventDispatchDetails details = - event_injector_.Inject(host, event.get()); - if (details.dispatcher_destroyed) - break; + for (auto& event : events) { + // Synthetic events from devtools debugger need to be dispatched explicitly + // to the target window. Otherwise they will end up in the active tab + // which might be different from the target. + if (web_touch.GetModifiers() & blink::WebInputEvent::kFromDebugger) { + window->delegate()->OnEvent(event.get()); + } else { + event->ConvertLocationToTarget(window, host->window()); + ui::EventDispatchDetails details = + event_injector_.Inject(host, event.get()); + if (details.dispatcher_destroyed) + break; + } } } @@ -97,11 +104,18 @@ wheel_precision_y_ = delta_y - wheel_event.y_offset(); aura::Window* window = GetWindow(); - wheel_event.ConvertLocationToTarget(window, window->GetRootWindow()); - ui::EventDispatchDetails details = - event_injector_.Inject(window->GetHost(), &wheel_event); - if (details.dispatcher_destroyed) - return; + // Synthetic events from devtools debugger need to be dispatched explicitly + // to the target window. Otherwise they will end up in the active tab + // which might be different from the target. + if (web_wheel.GetModifiers() & blink::WebInputEvent::kFromDebugger) { + window->delegate()->OnEvent(&wheel_event); + } else { + wheel_event.ConvertLocationToTarget(window, window->GetRootWindow()); + ui::EventDispatchDetails details = + event_injector_.Inject(window->GetHost(), &wheel_event); + if (details.dispatcher_destroyed) + return; + } } void SyntheticGestureTargetAura::DispatchWebGestureEventToPlatform( @@ -123,8 +137,15 @@ web_gesture.PositionInWidget().y(), flags, web_gesture.TimeStamp(), pinch_details); - pinch_event.ConvertLocationToTarget(window, window->GetRootWindow()); - event_injector_.Inject(window->GetHost(), &pinch_event); + // Synthetic events from devtools debugger need to be dispatched explicitly + // to the target window. Otherwise they will end up in the active tab + // which might be different from the target. + if (web_gesture.GetModifiers() & blink::WebInputEvent::kFromDebugger) { + window->delegate()->OnEvent(&pinch_event); + } else { + pinch_event.ConvertLocationToTarget(window, window->GetRootWindow()); + event_injector_.Inject(window->GetHost(), &pinch_event); + } return; } @@ -138,8 +159,15 @@ web_gesture.data.fling_start.velocity_x, web_gesture.data.fling_start.velocity_y, 0, 0, 2, momentum_phase, ui::ScrollEventPhase::kNone); - scroll_event.ConvertLocationToTarget(window, window->GetRootWindow()); - event_injector_.Inject(window->GetHost(), &scroll_event); + // Synthetic events from devtools debugger need to be dispatched explicitly + // to the target window. Otherwise they will end up in the active tab + // which might be different from the target. + if (web_gesture.GetModifiers() & blink::WebInputEvent::kFromDebugger) { + window->delegate()->OnEvent(&scroll_event); + } else { + scroll_event.ConvertLocationToTarget(window, window->GetRootWindow()); + event_injector_.Inject(window->GetHost(), &scroll_event); + } } void SyntheticGestureTargetAura::DispatchWebMouseEventToPlatform( @@ -164,12 +192,19 @@ changed_button_flags, pointer_details); aura::Window* window = GetWindow(); - mouse_event.ConvertLocationToTarget(window, window->GetRootWindow()); mouse_event.SetClickCount(web_mouse_event.click_count); - ui::EventDispatchDetails details = - event_injector_.Inject(window->GetHost(), &mouse_event); - if (details.dispatcher_destroyed) - return; + // Synthetic events from devtools debugger need to be dispatched explicitly + // to the target window. Otherwise they will end up in the active tab + // which might be different from the target. + if (web_mouse_event.GetModifiers() & blink::WebInputEvent::kFromDebugger) { + window->delegate()->OnEvent(&mouse_event); + } else { + mouse_event.ConvertLocationToTarget(window, window->GetRootWindow()); + ui::EventDispatchDetails details = + event_injector_.Inject(window->GetHost(), &mouse_event); + if (details.dispatcher_destroyed) + return; + } } content::mojom::GestureSourceType
diff --git a/content/browser/renderer_host/input/synthetic_smooth_drag_gesture.h b/content/browser/renderer_host/input/synthetic_smooth_drag_gesture.h index 124b187..54fc41f0 100644 --- a/content/browser/renderer_host/input/synthetic_smooth_drag_gesture.h +++ b/content/browser/renderer_host/input/synthetic_smooth_drag_gesture.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_SMOOTH_DRAG_GESTURE_H_ #include "content/browser/renderer_host/input/synthetic_smooth_move_gesture.h" +#include "content/common/content_export.h" #include "content/common/input/synthetic_smooth_drag_gesture_params.h"
diff --git a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h index a067945..b8c5385 100644 --- a/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h +++ b/content/browser/renderer_host/input/synthetic_smooth_scroll_gesture.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_RENDERER_HOST_INPUT_SYNTHETIC_SMOOTH_SCROLL_GESTURE_H_ #include "content/browser/renderer_host/input/synthetic_smooth_move_gesture.h" +#include "content/common/content_export.h" #include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
diff --git a/content/browser/renderer_host/input/touch_emulator.h b/content/browser/renderer_host/input/touch_emulator.h index e1fb53f..965d3c0 100644 --- a/content/browser/renderer_host/input/touch_emulator.h +++ b/content/browser/renderer_host/input/touch_emulator.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/containers/queue.h" #include "content/browser/renderer_host/input/touch_emulator_client.h" +#include "content/common/content_export.h" #include "content/common/cursors/webcursor.h" #include "third_party/blink/public/common/input/web_touch_event.h" #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h"
diff --git a/content/browser/renderer_host/media/audio_output_authorization_handler.h b/content/browser/renderer_host/media/audio_output_authorization_handler.h index 701c4892..ede9b88b 100644 --- a/content/browser/renderer_host/media/audio_output_authorization_handler.h +++ b/content/browser/renderer_host/media/audio_output_authorization_handler.h
@@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "content/browser/renderer_host/media/media_stream_manager.h" +#include "content/common/content_export.h" #include "media/audio/audio_device_description.h" #include "media/base/audio_parameters.h" #include "media/base/output_device_info.h"
diff --git a/content/browser/renderer_host/media/in_process_video_capture_provider.h b/content/browser/renderer_host/media/in_process_video_capture_provider.h index 3c8f937..3686dda 100644 --- a/content/browser/renderer_host/media/in_process_video_capture_provider.h +++ b/content/browser/renderer_host/media/in_process_video_capture_provider.h
@@ -8,6 +8,7 @@ #include "base/memory/ref_counted.h" #include "base/task/single_thread_task_runner.h" #include "content/browser/renderer_host/media/video_capture_provider.h" +#include "content/common/content_export.h" #include "media/capture/video/video_capture_system.h" namespace content {
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy.h b/content/browser/renderer_host/media/media_stream_ui_proxy.h index 8f51f721..2fd04a1 100644 --- a/content/browser/renderer_host/media/media_stream_ui_proxy.h +++ b/content/browser/renderer_host/media/media_stream_ui_proxy.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" #include "build/build_config.h" +#include "content/common/content_export.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/media_stream_request.h" #include "third_party/blink/public/common/mediastream/media_stream_request.h"
diff --git a/content/browser/renderer_host/media/service_video_capture_device_launcher.h b/content/browser/renderer_host/media/service_video_capture_device_launcher.h index b9c052c..8da03b9 100644 --- a/content/browser/renderer_host/media/service_video_capture_device_launcher.h +++ b/content/browser/renderer_host/media/service_video_capture_device_launcher.h
@@ -7,6 +7,7 @@ #include "content/browser/renderer_host/media/ref_counted_video_source_provider.h" #include "content/browser/renderer_host/media/video_capture_provider.h" +#include "content/common/content_export.h" #include "content/public/browser/video_capture_device_launcher.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/video_capture/public/mojom/device_factory.mojom.h"
diff --git a/content/browser/renderer_host/media/service_video_capture_provider.h b/content/browser/renderer_host/media/service_video_capture_provider.h index 8d98e7f0..c04b3d0e 100644 --- a/content/browser/renderer_host/media/service_video_capture_provider.h +++ b/content/browser/renderer_host/media/service_video_capture_provider.h
@@ -11,6 +11,7 @@ #include "build/chromeos_buildflags.h" #include "content/browser/renderer_host/media/ref_counted_video_source_provider.h" #include "content/browser/renderer_host/media/video_capture_provider.h" +#include "content/common/content_export.h" #include "content/public/browser/service_process_host.h" #include "services/video_capture/public/mojom/video_capture_service.mojom.h"
diff --git a/content/browser/renderer_host/media/video_capture_provider_switcher.h b/content/browser/renderer_host/media/video_capture_provider_switcher.h index 6eb0ca2..fd7c1c9 100644 --- a/content/browser/renderer_host/media/video_capture_provider_switcher.h +++ b/content/browser/renderer_host/media/video_capture_provider_switcher.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_PROVIDER_SWITCHER_H_ #include "content/browser/renderer_host/media/video_capture_provider.h" +#include "content/common/content_export.h" namespace content {
diff --git a/content/browser/renderer_host/navigation_controller_impl.cc b/content/browser/renderer_host/navigation_controller_impl.cc index 05a905b..ee19733 100644 --- a/content/browser/renderer_host/navigation_controller_impl.cc +++ b/content/browser/renderer_host/navigation_controller_impl.cc
@@ -1176,7 +1176,7 @@ #if defined(OS_ANDROID) // TODO(crbug.com/1266277): Clean up the logic of setting // |overriding_user_agent_changed| post-launch. - if (base::FeatureList::IsEnabled(features::kRequestDesktopSiteGlobal)) { + if (base::FeatureList::IsEnabled(features::kRequestDesktopSiteExceptions)) { // Must honor user agent overrides in the |navigation_request|, such as // from things like RequestDesktopSiteWebContentsObserverAndroid. As a // result, besides comparing |pending_entry_|'s user agent against @@ -1201,7 +1201,7 @@ #if defined(OS_ANDROID) // TODO(crbug.com/1266277): Clean up the logic of setting // |overriding_user_agent_changed| post-launch. - if (base::FeatureList::IsEnabled(features::kRequestDesktopSiteGlobal)) { + if (base::FeatureList::IsEnabled(features::kRequestDesktopSiteExceptions)) { // Must honor user agent overrides in the |navigation_request|, such as // from things like RequestDesktopSiteWebContentsObserverAndroid. As a // result, besides checking |pending_entry_|'s user agent, also need to @@ -1283,18 +1283,18 @@ // renderer. Limit this to a very narrow set of conditions to avoid risks to // other navigation types. See https://crbug.com/900036. // TODO(crbug.com/926009): Handle history.pushState() as well. - bool keep_pending_entry = is_same_document_navigation && - details->type == NAVIGATION_TYPE_EXISTING_ENTRY && - pending_entry_ && - !PendingEntryMatchesRequest(navigation_request); + bool keep_pending_entry = + is_same_document_navigation && + details->type == NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY && + pending_entry_ && !PendingEntryMatchesRequest(navigation_request); switch (details->type) { - case NAVIGATION_TYPE_NEW_ENTRY: + case NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY: RendererDidNavigateToNewEntry( rfh, params, details->is_same_document, details->did_replace_entry, previous_document_was_activated, navigation_request); break; - case NAVIGATION_TYPE_EXISTING_ENTRY: + case NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY: RendererDidNavigateToExistingEntry(rfh, params, details->is_same_document, was_restored, navigation_request, keep_pending_entry); @@ -1443,7 +1443,7 @@ // this may or may not be the main frame. if (!rfh->GetParent()) { trace_return.set_return_reason("new entry, no parent, new entry"); - return NAVIGATION_TYPE_NEW_ENTRY; + return NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY; } // When this is a new subframe navigation, we should have a committed page @@ -1502,7 +1502,7 @@ // as new with replacement. trace_return.set_return_reason( "nav entry 0, last committed, existing entry"); - return NAVIGATION_TYPE_EXISTING_ENTRY; + return NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY; } if (pending_entry_ && pending_entry_->GetUniqueID() == nav_entry_id) { @@ -1514,7 +1514,7 @@ if (pending_entry_->site_instance() && pending_entry_->site_instance() != rfh->GetSiteInstance()) { trace_return.set_return_reason("pending matching nav entry, new entry"); - return NAVIGATION_TYPE_NEW_ENTRY; + return NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY; } if (pending_entry_index_ == -1) { @@ -1527,7 +1527,7 @@ if (!GetLastCommittedEntry() || GetLastCommittedEntry()->site_instance() != rfh->GetSiteInstance()) { trace_return.set_return_reason("new pending, new entry"); - return NAVIGATION_TYPE_NEW_ENTRY; + return NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY; } // Otherwise, this happens when you press enter in the URL bar to reload. @@ -1537,7 +1537,7 @@ // do this.) Therefore we want to just ignore the pending entry and go // back to where we were (the "existing entry"). trace_return.set_return_reason("new pending, existing (same) entry"); - return NAVIGATION_TYPE_EXISTING_ENTRY; + return NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY; } } @@ -1545,7 +1545,7 @@ // no last committed entry, we must consider it a new navigation instead. if (!GetLastCommittedEntry()) { trace_return.set_return_reason("no last committed, new entry"); - return NAVIGATION_TYPE_NEW_ENTRY; + return NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY; } if (navigation_request->commit_params().intended_as_new_entry) { @@ -1553,7 +1553,7 @@ // got cleared in the meanwhile. Classify as EXISTING_ENTRY because we may // or may not have a pending entry. trace_return.set_return_reason("intended as new entry, existing entry"); - return NAVIGATION_TYPE_EXISTING_ENTRY; + return NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY; } if (navigation_request->DidEncounterError() && @@ -1565,7 +1565,7 @@ // have a pending entry. trace_return.set_return_reason( "unreachable, matching pending, existing entry"); - return NAVIGATION_TYPE_EXISTING_ENTRY; + return NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY; } // Now we know that the notification is for an existing entry; find it. @@ -1576,13 +1576,13 @@ // The renderer has committed a navigation to an entry that no longer // exists. Because the renderer is showing that page, resurrect that entry. trace_return.set_return_reason("existing entry -1, new entry"); - return NAVIGATION_TYPE_NEW_ENTRY; + return NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY; } // Since we weeded out "new" navigations above, we know this is an existing // (back/forward) navigation. trace_return.set_return_reason("default return, existing entry"); - return NAVIGATION_TYPE_EXISTING_ENTRY; + return NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY; } void NavigationControllerImpl::UpdateNavigationEntryDetails(
diff --git a/content/browser/renderer_host/navigation_controller_impl.h b/content/browser/renderer_host/navigation_controller_impl.h index d577458..8a15c23 100644 --- a/content/browser/renderer_host/navigation_controller_impl.h +++ b/content/browser/renderer_host/navigation_controller_impl.h
@@ -23,6 +23,7 @@ #include "content/browser/renderer_host/navigation_controller_delegate.h" #include "content/browser/renderer_host/navigation_entry_impl.h" #include "content/browser/ssl/ssl_manager.h" +#include "content/common/content_export.h" #include "content/common/navigation_client.mojom-forward.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_type.h"
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc index 1fd8dd1..9730b80 100644 --- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -2258,7 +2258,7 @@ FrameNavigateParamsCapturer capturer(root); NavigateFrameToURL(root, error_url); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); NavigationEntry* entry = controller.GetLastCommittedEntry(); EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType()); EXPECT_EQ(2, controller.GetEntryCount()); @@ -2273,7 +2273,7 @@ FrameNavigateParamsCapturer capturer(root); NavigateFrameToURL(root, error_url); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.did_replace_entry()); NavigationEntry* entry = controller.GetLastCommittedEntry(); EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType()); @@ -2297,7 +2297,7 @@ FrameNavigateParamsCapturer capturer(root); NavigateFrameToURL(root, url2); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_FALSE(capturer.did_replace_entry()); NavigationEntry* entry = controller.GetLastCommittedEntry(); EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType()); @@ -2311,7 +2311,8 @@ FrameNavigateParamsCapturer capturer(root); controller.GoBack(); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.did_replace_entry()); NavigationEntry* entry = controller.GetLastCommittedEntry(); EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType()); @@ -2326,7 +2327,7 @@ FrameNavigateParamsCapturer capturer(root); controller.GoForward(); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.did_replace_entry()); NavigationEntry* entry = controller.GetLastCommittedEntry(); EXPECT_NE(PAGE_TYPE_ERROR, entry->GetPageType()); @@ -2343,7 +2344,7 @@ FrameNavigateParamsCapturer capturer(root); RendererLocationReplace(shell(), error_url); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.did_replace_entry()); NavigationEntry* entry = controller.GetLastCommittedEntry(); EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType()); @@ -2362,7 +2363,7 @@ FrameNavigateParamsCapturer capturer(root); RendererLocationReplace(shell(), error_url); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.did_replace_entry()); NavigationEntry* entry = controller.GetLastCommittedEntry(); EXPECT_EQ(PAGE_TYPE_ERROR, entry->GetPageType()); @@ -2491,8 +2492,8 @@ // Various tests for navigation type classifications. TODO(avi): It's rather // bogus that the same info is in two different enums; http://crbug.com/453555. -// Verify that navigations for NAVIGATION_TYPE_NEW_ENTRY are correctly -// classified. +// Verify that navigations for NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY are +// correctly classified. IN_PROC_BROWSER_TEST_P(NavigationControllerBrowserTest, NavigationTypeClassification_NewEntry) { EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL))); @@ -2514,7 +2515,7 @@ // transition? Lots of these transitions should be cleaned up. EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_LINK)); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); } @@ -2530,7 +2531,7 @@ capturer.Wait(); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_LINK)); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); // The FrameNavigationEntry and NavigationEntry are not reused. @@ -2550,7 +2551,7 @@ capturer.Wait(); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_LINK)); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); // The FrameNavigationEntry and NavigationEntry are not reused. @@ -2572,7 +2573,7 @@ capturer.Wait(); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_LINK)); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); // The FrameNavigationEntry and NavigationEntry are not reused. @@ -2593,7 +2594,7 @@ capturer.Wait(); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_LINK)); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); // The FrameNavigationEntry and NavigationEntry are not reused. @@ -2617,7 +2618,7 @@ capturer.transition(), ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT))); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.did_replace_entry()); EXPECT_FALSE(capturer.is_same_document()); @@ -2629,8 +2630,8 @@ } } -// Verify that navigations for NAVIGATION_TYPE_EXISTING_ENTRY are correctly -// classified. +// Verify that navigations for NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY are +// correctly classified. IN_PROC_BROWSER_TEST_P(NavigationControllerBrowserTest, NavigationTypeClassification_ExistingEntry) { GURL url1(embedded_test_server()->GetURL( @@ -2656,7 +2657,8 @@ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FORWARD_BACK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR))); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); } @@ -2670,7 +2672,8 @@ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FORWARD_BACK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR))); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); } @@ -2684,7 +2687,8 @@ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FORWARD_BACK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR))); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); } @@ -2698,7 +2702,8 @@ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FORWARD_BACK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR))); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); } @@ -2712,7 +2717,8 @@ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FORWARD_BACK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR))); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); } @@ -2726,7 +2732,8 @@ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FORWARD_BACK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR))); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); } @@ -2742,7 +2749,8 @@ capturer.Wait(); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_RELOAD)); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); // We reused the last committed entry for this navigation. @@ -2761,7 +2769,8 @@ shell()->web_contents()->GetMainFrame()->Reload(); capturer.Wait(); // We're classifying this as EXISTING_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_RELOAD)); @@ -2785,7 +2794,8 @@ capturer.transition(), ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT))); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); // We reused the last committed entry for this navigation. @@ -2817,7 +2827,8 @@ EXPECT_FALSE(reload_observer.last_navigation_succeeded()); // We're classifying this as EXISTING_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_RELOAD)); @@ -2840,7 +2851,8 @@ EXPECT_FALSE(reload_observer.last_navigation_succeeded()); // We're classifying this as EXISTING_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_RELOAD)); @@ -2866,7 +2878,7 @@ EXPECT_TRUE(reload_observer.last_navigation_succeeded()); // We're classifying this as NEW_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_RELOAD)); @@ -2892,7 +2904,7 @@ capturer.transition(), ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT))); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.did_replace_entry()); EXPECT_FALSE(capturer.is_same_document()); @@ -2919,9 +2931,10 @@ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT))); // Different from cross-document replacement which would be classified as - // NAVIGATION_TYPE_NEW_ENTRY, same-document replacement is classified as - // NAVIGATION_TYPE_EXISTING_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + // NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, same-document replacement is + // classified as NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY. + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.did_replace_entry()); EXPECT_TRUE(capturer.is_same_document()); @@ -2946,9 +2959,10 @@ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT))); // Different from history.pushState() which would be classified as - // NAVIGATION_TYPE_NEW_ENTRY, replaceState() will be classified as - // NAVIGATION_TYPE_EXISTING_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + // NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, replaceState() will be classified + // as NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY. + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.did_replace_entry()); EXPECT_TRUE(capturer.is_same_document()); @@ -2980,7 +2994,8 @@ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FORWARD_BACK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR))); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); } @@ -2993,7 +3008,8 @@ capturer.transition(), ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FORWARD_BACK))); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); } @@ -3014,7 +3030,8 @@ ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FORWARD_BACK | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR))); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); } @@ -3027,7 +3044,8 @@ capturer.transition(), ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_FORWARD_BACK))); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); } } @@ -3061,7 +3079,8 @@ capturer.Wait(); // The navigation got converted into a reload, and we're classifying this as // EXISTING_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); // Ensure the pending entry was cleared after commit. EXPECT_FALSE(shell()->web_contents()->GetController().GetPendingEntry()); @@ -3083,7 +3102,7 @@ EXPECT_TRUE(NavigateToURLFromRenderer(root, url1)); capturer.Wait(); // We're classifying this as NEW_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); // The navigation replaced the previously committed entry with a new entry. // This differs than the browser-initiated case's behavior, but it's OK. @@ -3106,7 +3125,7 @@ EXPECT_TRUE(ExecJs(root, JsReplace("location.replace($1);", url1))); capturer.Wait(); // We're classifying this as NEW_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); // The navigation replaced the previously committed entry with a new entry. EXPECT_TRUE(capturer.did_replace_entry()); @@ -3135,7 +3154,7 @@ EXPECT_FALSE(NavigateToURLFromRenderer(shell(), url1)); capturer.Wait(); // We're classifying this as NEW_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); // The navigation replaced the previously committed entry. EXPECT_TRUE(capturer.did_replace_entry()); @@ -3152,7 +3171,8 @@ shell()->Reload(); capturer.Wait(); // We're classifying this as EXISTING_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); // The navigation reused the previously committed error page entry. EXPECT_FALSE(capturer.did_replace_entry()); @@ -3171,7 +3191,7 @@ EXPECT_FALSE(NavigateToURL(shell(), url1)); capturer.Wait(); // We're classifying this as NEW_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); // The navigation replaced the previously committed entry. EXPECT_TRUE(capturer.did_replace_entry()); @@ -3190,7 +3210,7 @@ EXPECT_TRUE(NavigateToURL(shell(), url1)); capturer.Wait(); // We're classifying this as NEW_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); // The navigation added a new entry. // TODO(https://crbug.com/1188956): This should replace the last committed @@ -3221,7 +3241,7 @@ contents()->GetController().LoadURLWithParams(params); capturer.Wait(); // We're classifying this as NEW_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); // The navigation replaced the previously committed entry with a new entry. EXPECT_TRUE(capturer.did_replace_entry()); @@ -3255,7 +3275,7 @@ capturer.Wait(); // We're classifying this as NEW_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); // The navigation replaced the previously committed entry with a new entry // because the navigation resulted in an error page. @@ -3293,7 +3313,8 @@ capturer.Wait(); // The navigation got converted into a reload, and we're classifying this as // EXISTING_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); // Ensure the pending entry was cleared after commit. EXPECT_FALSE(shell()->web_contents()->GetController().GetPendingEntry()); @@ -3317,7 +3338,8 @@ capturer.Wait(); // The navigation got converted into a reload, and we're classifying this as // EXISTING_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); // We reuse the last committed entry for this navigation. EXPECT_FALSE(capturer.did_replace_entry()); @@ -3357,13 +3379,14 @@ capturer.Wait(); // Since it started out as a browser-initiated same-URL navigation, it got - // converted to a reload and classified as NAVIGATION_TYPE_EXISTING_ENTRY - // and reuses the previous entry, even though it ended up at a different URL - // than before. + // converted to a reload and classified as + // NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY and reuses the previous entry, + // even though it ended up at a different URL than before. // TODO(https://crbug.com/1247185): Perhaps this should be classified as - // NAVIGATION_TYPE_NEW_ENTRY with replacement instead, to be consistent with - // reloads that redirected cross-site. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + // NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY with replacement instead, to be + // consistent with reloads that redirected cross-site. + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.did_replace_entry()); EXPECT_EQ(previous_entry, controller.GetLastCommittedEntry()); @@ -3385,8 +3408,8 @@ // Since it started out as a renderer-initiated same-URL navigation, it got // converted to a replacement navigation, so it's classified as - // NAVIGATION_TYPE_NEW_ENTRY. - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + // NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY. + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.did_replace_entry()); EXPECT_NE(previous_entry, controller.GetLastCommittedEntry()); @@ -3414,7 +3437,7 @@ // It started out as a same-URL navigation, but since it was a POST // navigation, it didn't get converted to replacement. - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_FALSE(capturer.did_replace_entry()); EXPECT_NE(previous_entry, controller.GetLastCommittedEntry()); @@ -3454,7 +3477,8 @@ capturer.Wait(); // We're classifying this as EXISTING_ENTRY because the navigation got // converted into a reload. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); // Since we did a reload, it's not classified as a same-document navigation. EXPECT_FALSE(capturer.is_same_document()); @@ -3483,7 +3507,8 @@ // with replacement. // TODO(rakina): did_replace_entry should be false since we're not actually // doing any replacement. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.did_replace_entry()); EXPECT_EQ(previous_entry, controller.GetLastCommittedEntry()); EXPECT_EQ(1, controller.GetEntryCount()); @@ -3597,7 +3622,7 @@ capturer.Wait(); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_LINK)); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); // The navigation should add a new entry to the session history, and not // do any entry replacement. @@ -3857,9 +3882,9 @@ } // Navigates |web_contents| to |url| then checks if its navigation type is - // NAVIGATION_TYPE_NEW_ENTRY and whether other related properties are - // consistent with the type. Whether the navigation is renderer-initiated or - // not depends on the renderer vs browser initiated parameter of this test + // NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY and whether other related properties + // are consistent with the type. Whether the navigation is renderer-initiated + // or not depends on the renderer vs browser initiated parameter of this test // class. void NavigateWindowAndCheckNavigationTypeIsNewEntry( WebContentsImpl* web_contents, @@ -3890,7 +3915,7 @@ capturer.Wait(); load_details_observer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_FALSE(capturer.did_replace_entry()); // Check both NavigationHandle and LoadCommittedDetails for whether this was @@ -4506,7 +4531,8 @@ capturer.Wait(); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_RELOAD)); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); // Check that the renderer is still alive and no new navigation entry is // added. EXPECT_TRUE(ExecJs(new_shell, "true")); @@ -4522,7 +4548,8 @@ capturer.Wait(); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_RELOAD)); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); // Check that the renderer is still alive and no new navigation entry is // added. EXPECT_TRUE(ExecJs(new_shell, "true")); @@ -4560,7 +4587,8 @@ ASSERT_EQ(2U, capturer.navigation_types().size()); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transitions()[0], ui::PAGE_TRANSITION_LINK)); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_types()[0]); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, + capturer.navigation_types()[0]); EXPECT_FALSE(capturer.did_replace_entries()[0]); // The transition used for the second navigation indicates that it is a // client-side redirect. @@ -4568,7 +4596,8 @@ capturer.transitions()[1], ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT))); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_types()[1]); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, + capturer.navigation_types()[1]); // The client-side redirect results in the replacement of the previous // entry. EXPECT_TRUE(capturer.did_replace_entries()[1]); @@ -4695,7 +4724,7 @@ capturer.Wait(); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_LINK)); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); } @@ -4707,7 +4736,7 @@ capturer.Wait(); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_LINK)); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); } @@ -5033,7 +5062,7 @@ std::string script = "history.pushState({}, '', 'pushed')"; EXPECT_TRUE(ExecJs(root, script)); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); } @@ -5079,7 +5108,8 @@ std::string script = "history.replaceState({}, '', 'replaced')"; EXPECT_TRUE(ExecJs(root, script)); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); } @@ -5152,7 +5182,7 @@ std::string script = "history.pushState({}, 'foo', 'foo')"; EXPECT_TRUE(ExecJs(root, script)); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); } @@ -5210,7 +5240,7 @@ std::string script = "history.pushState({}, 'foo', 'foo')"; EXPECT_TRUE(ExecJs(root, script)); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); } @@ -7972,7 +8002,8 @@ capturer.Wait(); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_RELOAD)); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_FALSE(capturer.is_same_document()); } @@ -9784,7 +9815,8 @@ // The fact that there was a pending entry shouldn't interfere with the // classification. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); } } @@ -9870,7 +9902,7 @@ std::string script = "history.pushState({}, '', 'pushed')"; EXPECT_TRUE(ExecJs(root, script)); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.is_same_document()); } @@ -10253,7 +10285,8 @@ // This gets classified as EXISTING_ENTRY since it's a same-document // replacement. Note that a cross-document location.replace() would've been // classified as NEW_ENTRY instead. - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); EXPECT_EQ(url1_bar, contents()->GetLastCommittedURL()); EXPECT_EQ(3, controller.GetEntryCount()); @@ -10600,7 +10633,7 @@ capturer.transition(), ui::PageTransitionFromInt(ui::PAGE_TRANSITION_LINK | ui::PAGE_TRANSITION_CLIENT_REDIRECT))); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(capturer.did_replace_entry()); } @@ -13623,7 +13656,7 @@ "/navigation_controller/simple_page_2.html")); NavigateFrameToURL(root, main_url_2); capturer.Wait(); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); EXPECT_TRUE(ui::PageTransitionTypeIncludingQualifiersIs( capturer.transition(), ui::PAGE_TRANSITION_LINK)); EXPECT_EQ(3, controller.GetEntryCount()); @@ -13990,7 +14023,8 @@ EXPECT_FALSE(observer.last_navigation_succeeded()); EXPECT_EQ(net::ERR_HTTP_RESPONSE_CODE_FAILURE, observer.last_net_error_code()); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, observer.last_navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, + observer.last_navigation_type()); EXPECT_EQ(PAGE_TYPE_ERROR, controller.GetLastCommittedEntry()->GetPageType()); @@ -14007,7 +14041,7 @@ EXPECT_FALSE(reload_observer.last_navigation_succeeded()); EXPECT_EQ(net::ERR_HTTP_RESPONSE_CODE_FAILURE, reload_observer.last_net_error_code()); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, reload_observer.last_navigation_type()); EXPECT_EQ(PAGE_TYPE_ERROR, controller.GetLastCommittedEntry()->GetPageType()); @@ -14022,7 +14056,7 @@ EXPECT_FALSE(same_url_observer.last_navigation_succeeded()); EXPECT_EQ(net::ERR_HTTP_RESPONSE_CODE_FAILURE, same_url_observer.last_net_error_code()); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, same_url_observer.last_navigation_type()); EXPECT_EQ(PAGE_TYPE_ERROR, controller.GetLastCommittedEntry()->GetPageType()); @@ -14813,11 +14847,12 @@ IsolationContext(shell()->web_contents()->GetBrowserContext()), url3), root->current_frame_host()->GetSiteInstance()->GetSiteInfo()); - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, capturer.navigation_type()); } else { EXPECT_EQ(initial_site_instance, root->current_frame_host()->GetSiteInstance()); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, capturer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + capturer.navigation_type()); } }
diff --git a/content/browser/renderer_host/navigation_controller_impl_unittest.cc b/content/browser/renderer_host/navigation_controller_impl_unittest.cc index 593bc48..8c0cdf4 100644 --- a/content/browser/renderer_host/navigation_controller_impl_unittest.cc +++ b/content/browser/renderer_host/navigation_controller_impl_unittest.cc
@@ -1779,7 +1779,7 @@ EXPECT_EQ(1U, navigation_entry_committed_counter_); navigation_entry_committed_counter_ = 0; - EXPECT_EQ(NAVIGATION_TYPE_NEW_ENTRY, observer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, observer.navigation_type()); EXPECT_EQ(controller.GetEntryCount(), 1); EXPECT_EQ(controller.GetLastCommittedEntryIndex(), 0); EXPECT_TRUE(controller.GetLastCommittedEntry()); @@ -1831,7 +1831,8 @@ // ... and now the renderer sends a commit for the first navigation. LoadCommittedDetailsObserver observer(contents()); navigation1->Commit(); - EXPECT_EQ(NAVIGATION_TYPE_EXISTING_ENTRY, observer.navigation_type()); + EXPECT_EQ(NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + observer.navigation_type()); } // Tests navigation via link click within a subframe. A new navigation entry
diff --git a/content/browser/renderer_host/navigation_entry_impl.h b/content/browser/renderer_host/navigation_entry_impl.h index deb9716..4227205 100644 --- a/content/browser/renderer_host/navigation_entry_impl.h +++ b/content/browser/renderer_host/navigation_entry_impl.h
@@ -18,6 +18,7 @@ #include "content/browser/renderer_host/back_forward_cache_metrics.h" #include "content/browser/renderer_host/frame_navigation_entry.h" #include "content/browser/site_instance_impl.h" +#include "content/common/content_export.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/navigation_entry.h"
diff --git a/content/browser/renderer_host/navigation_entry_restore_context_impl.h b/content/browser/renderer_host/navigation_entry_restore_context_impl.h index 842078c..5925d9b 100644 --- a/content/browser/renderer_host/navigation_entry_restore_context_impl.h +++ b/content/browser/renderer_host/navigation_entry_restore_context_impl.h
@@ -8,6 +8,7 @@ #include <map> #include <string> +#include "content/common/content_export.h" #include "content/public/browser/navigation_entry_restore_context.h" class GURL;
diff --git a/content/browser/renderer_host/navigation_throttle_runner.h b/content/browser/renderer_host/navigation_throttle_runner.h index 3f1e948..fcba72a 100644 --- a/content/browser/renderer_host/navigation_throttle_runner.h +++ b/content/browser/renderer_host/navigation_throttle_runner.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" #include "content/public/browser/navigation_throttle.h" namespace content {
diff --git a/content/browser/renderer_host/navigator.cc b/content/browser/renderer_host/navigator.cc index eb472165c..fb997dd 100644 --- a/content/browser/renderer_host/navigator.cc +++ b/content/browser/renderer_host/navigator.cc
@@ -221,7 +221,6 @@ GURL url_; ukm::SourceId ukm_source_id_; bool is_browser_initiated_before_unload_; - base::TimeDelta before_unload_delay_; // Timestamps before_unload_(start|end)_ give the time it took to run // beforeunloads dispatched from the browser process. For browser-initated @@ -976,21 +975,18 @@ void Navigator::LogBeforeUnloadTime( base::TimeTicks renderer_before_unload_start_time, base::TimeTicks renderer_before_unload_end_time, - base::TimeTicks before_unload_sent_time) { + base::TimeTicks before_unload_sent_time, + bool for_legacy) { if (!navigation_data_) return; - // Only stores the beforeunload delay if we're tracking a browser initiated - // navigation and it happened later than the navigation request. - if (navigation_data_->is_browser_initiated_before_unload_ && - renderer_before_unload_start_time > navigation_data_->start_time_) { - navigation_data_->before_unload_delay_ = - renderer_before_unload_end_time - renderer_before_unload_start_time; - } // LogBeforeUnloadTime is called once for each cross-process frame. Once all // beforeunloads complete, the timestamps in navigation_data will be the // timestamps of the beforeunload that blocked the navigation the longest. - if (!base::TimeTicks::IsConsistentAcrossProcesses()) { + // `for_legacy` indicates this is being called as the result of a PostTask(), + // which did not go to the renderer so that the times do not need to be + // adjusted. + if (!base::TimeTicks::IsConsistentAcrossProcesses() && !for_legacy) { // These timestamps come directly from the renderer so they might need to be // converted to local time stamps. blink::InterProcessTimeTicksConverter converter(
diff --git a/content/browser/renderer_host/navigator.h b/content/browser/renderer_host/navigator.h index 92ab96bd..8a3cf98 100644 --- a/content/browser/renderer_host/navigator.h +++ b/content/browser/renderer_host/navigator.h
@@ -191,10 +191,12 @@ void CancelNavigation(FrameTreeNode* frame_tree_node); // Called to record the time it took to execute the beforeunload hook for the - // current navigation. + // current navigation. See RenderFrameHostImpl::SendBeforeUnload() for details + // on `for_legacy`. void LogBeforeUnloadTime(base::TimeTicks renderer_before_unload_start_time, base::TimeTicks renderer_before_unload_end_time, - base::TimeTicks before_unload_sent_time); + base::TimeTicks before_unload_sent_time, + bool for_legacy); // Called to record the time that the RenderFrameHost told the renderer to // commit the current navigation.
diff --git a/content/browser/renderer_host/navigator_delegate.h b/content/browser/renderer_host/navigator_delegate.h index 1a263ba..b1deb8d9 100644 --- a/content/browser/renderer_host/navigator_delegate.h +++ b/content/browser/renderer_host/navigator_delegate.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_NAVIGATOR_DELEGATE_H_ #define CONTENT_BROWSER_RENDERER_HOST_NAVIGATOR_DELEGATE_H_ +#include "content/common/content_export.h" #include "content/common/navigation_client.mojom.h" #include "content/public/browser/allow_service_worker_result.h" #include "content/public/browser/cookie_access_details.h"
diff --git a/content/browser/renderer_host/pepper/pepper_file_ref_host.h b/content/browser/renderer_host/pepper/pepper_file_ref_host.h index 6d3a7e7..9f0b8dd 100644 --- a/content/browser/renderer_host/pepper/pepper_file_ref_host.h +++ b/content/browser/renderer_host/pepper/pepper_file_ref_host.h
@@ -10,6 +10,7 @@ #include <string> #include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" #include "content/public/browser/browser_ppapi_host.h" #include "ppapi/c/pp_file_info.h" #include "ppapi/c/pp_instance.h"
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 50b529b..3a7abac 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -1663,7 +1663,7 @@ beforeunload_initiator->ProcessBeforeUnloadCompletedFromFrame( /*proceed=*/true, /*treat_as_final_completion_callback=*/false, this, /*is_frame_being_destroyed=*/true, approx_renderer_start_time, - base::TimeTicks::Now()); + base::TimeTicks::Now(), /*for_legacy=*/false); } if (prefetched_signed_exchange_cache_) @@ -4380,7 +4380,8 @@ bool proceed, bool treat_as_final_completion_callback, const base::TimeTicks& renderer_before_unload_start_time, - const base::TimeTicks& renderer_before_unload_end_time) { + const base::TimeTicks& renderer_before_unload_end_time, + bool for_legacy) { TRACE_EVENT_NESTABLE_ASYNC_END1( "navigation", "RenderFrameHostImpl BeforeUnload", TRACE_ID_LOCAL(this), "render_frame_host", this); @@ -4401,7 +4402,7 @@ initiator->ProcessBeforeUnloadCompletedFromFrame( proceed, treat_as_final_completion_callback, this, /*is_frame_being_destroyed=*/false, renderer_before_unload_start_time, - renderer_before_unload_end_time); + renderer_before_unload_end_time, for_legacy); } RenderFrameHostImpl* RenderFrameHostImpl::GetBeforeUnloadInitiator() { @@ -4418,7 +4419,8 @@ RenderFrameHostImpl* frame, bool is_frame_being_destroyed, const base::TimeTicks& renderer_before_unload_start_time, - const base::TimeTicks& renderer_before_unload_end_time) { + const base::TimeTicks& renderer_before_unload_end_time, + bool for_legacy) { // Check if we need to wait for more beforeunload completion callbacks. If // |proceed| is false, we know the navigation or window close will be aborted, // so we don't need to wait for beforeunload completion callbacks from any @@ -4442,7 +4444,7 @@ !renderer_before_unload_end_time.is_null()) { base::TimeTicks before_unload_completed_time = base::TimeTicks::Now(); - if (!base::TimeTicks::IsConsistentAcrossProcesses()) { + if (!base::TimeTicks::IsConsistentAcrossProcesses() && !for_legacy) { // TimeTicks is not consistent across processes and we are passing // TimeTicks across process boundaries so we need to compensate for any // skew between the processes. Here we are converting the renderer's @@ -4469,7 +4471,7 @@ frame_tree_node_->navigator().LogBeforeUnloadTime( renderer_before_unload_start_time, renderer_before_unload_end_time, - send_before_unload_start_time_); + send_before_unload_start_time_, for_legacy); } // Resets beforeunload waiting state. @@ -7483,6 +7485,7 @@ bool send_ipc, bool is_reload) { bool found_beforeunload = false; + bool run_beforeunload_for_legacy = false; for (FrameTreeNode* node : frame_tree()->SubtreeNodes(frame_tree_node_)) { RenderFrameHostImpl* rfh = node->current_frame_host(); @@ -7497,12 +7500,12 @@ continue; // Only run beforeunload in frames that have registered a beforeunload - // handler. - bool should_run_beforeunload = rfh->has_before_unload_handler_; - if (rfh == this && !base::FeatureList::IsEnabled( - features::kAvoidUnnecessaryBeforeUnloadCheck)) { - should_run_beforeunload = true; - } + // handler. See description of SendBeforeUnload() for details on simulating + // beforeunload for legacy reasons. + const bool run_beforeunload_for_legacy_frame = + rfh == this && !rfh->has_before_unload_handler_; + const bool should_run_beforeunload = + rfh->has_before_unload_handler_ || run_beforeunload_for_legacy_frame; if (!should_run_beforeunload) continue; @@ -7542,11 +7545,28 @@ if (has_same_site_ancestor) continue; + if (run_beforeunload_for_legacy_frame && + base::FeatureList::IsEnabled( + features::kAvoidUnnecessaryBeforeUnloadCheck)) { + // Wait to schedule until all frames have been processed. The legacy + // beforeunload is not needed if another frame has a beforeunload + // handler. + run_beforeunload_for_legacy = true; + continue; + } + + run_beforeunload_for_legacy = false; + // Add |rfh| to the list of frames that need to receive beforeunload // ACKs. beforeunload_pending_replies_.insert(rfh); - SendBeforeUnload(is_reload, rfh->GetWeakPtr()); + SendBeforeUnload(is_reload, rfh->GetWeakPtr(), /*for_legacy=*/false); + } + + if (run_beforeunload_for_legacy) { + beforeunload_pending_replies_.insert(this); + SendBeforeUnload(is_reload, GetWeakPtr(), /*for_legacy=*/true); } return found_beforeunload; @@ -7562,7 +7582,8 @@ base::BindOnce(&RenderFrameHostImpl::ProcessBeforeUnloadCompleted, weak_ptr_factory_.GetWeakPtr(), proceed, /*treat_as_final_completion_callback=*/true, - approx_renderer_start_time, base::TimeTicks::Now())); + approx_renderer_start_time, base::TimeTicks::Now(), + /*for_legacy=*/false)); } bool RenderFrameHostImpl::ShouldDispatchBeforeUnload( @@ -10977,7 +10998,8 @@ base::TimeTicks approx_renderer_start_time = send_before_unload_start_time_; ProcessBeforeUnloadCompleted( /*proceed=*/true, /*treat_as_final_completion_callback=*/true, - approx_renderer_start_time, base::TimeTicks::Now()); + approx_renderer_start_time, base::TimeTicks::Now(), + /*for_legacy=*/false); } // When a frame enters pending deletion, it waits for itself and its children @@ -11065,18 +11087,32 @@ void RenderFrameHostImpl::SendBeforeUnload( bool is_reload, - base::WeakPtr<RenderFrameHostImpl> rfh) { + base::WeakPtr<RenderFrameHostImpl> rfh, + bool for_legacy) { auto before_unload_closure = base::BindOnce( - [](base::WeakPtr<RenderFrameHostImpl> impl, bool proceed, + [](base::WeakPtr<RenderFrameHostImpl> impl, bool for_legacy, bool proceed, base::TimeTicks renderer_before_unload_start_time, base::TimeTicks renderer_before_unload_end_time) { if (!impl) return; impl->ProcessBeforeUnloadCompleted( proceed, /*treat_as_final_completion_callback=*/false, - renderer_before_unload_start_time, renderer_before_unload_end_time); + renderer_before_unload_start_time, renderer_before_unload_end_time, + for_legacy); }, - rfh); + rfh, for_legacy); + if (for_legacy) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce( + [](blink::mojom::LocalFrame::BeforeUnloadCallback callback, + base::TimeTicks start_time) { + std::move(callback).Run(/*proceed=*/true, start_time, + base::TimeTicks::Now()); + }, + std::move(before_unload_closure), send_before_unload_start_time_)); + return; + } // Experiment to run beforeunload handlers at a higher priority in the // renderer. See crubug.com/1042118. if (base::FeatureList::IsEnabled(features::kHighPriorityBeforeUnload)) {
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index 8224588..cf25d72 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -2459,8 +2459,16 @@ BuildCommitFailedNavigationCallback(NavigationRequest* navigation_request); // Protected / virtual so it can be overridden by tests. + // If `for_legacy` is true, the beforeunload handler is not actually present, + // nor required to run. In this case the renderer is not notified, but + // PostTask() is used. PostTask() is used because synchronously proceeding + // with navigation could lead to reentrancy problems. In particular, there + // are tests and android WebView using NavigationThrottles to navigate from + // WillStartRequest(). If PostTask() is not used, then CHECKs would trigger + // in a NavigationController. See https://crbug.com/365039 for more details. virtual void SendBeforeUnload(bool is_reload, - base::WeakPtr<RenderFrameHostImpl> impl); + base::WeakPtr<RenderFrameHostImpl> impl, + bool for_legacy); private: friend class RenderFrameHostPermissionsPolicyTest; @@ -2897,12 +2905,14 @@ // |treat_as_final_completion_callback| is true, the frame should stop waiting // for any further completion callbacks from subframes. Completion callbacks // invoked from the renderer set |treat_as_final_completion_callback| to - // false, whereas a beforeunload timeout sets it to true. + // false, whereas a beforeunload timeout sets it to true. See + // SendBeforeUnload() for details on `for_legacy`. void ProcessBeforeUnloadCompleted( bool proceed, bool treat_as_final_completion_callback, const base::TimeTicks& renderer_before_unload_start_time, - const base::TimeTicks& renderer_before_unload_end_time); + const base::TimeTicks& renderer_before_unload_end_time, + bool for_legacy); // Find the frame that triggered the beforeunload handler to run in this // frame, which might be the frame itself or its ancestor. This will @@ -2918,14 +2928,15 @@ // been invoked on. If a beforeunload timeout occurred, // |treat_as_final_completion_callback| is set to true. // |is_frame_being_destroyed| is set to true if this was called as part of - // destroying |frame|. + // destroying |frame|. See SendBeforeUnload() for details on `for_legacy`. void ProcessBeforeUnloadCompletedFromFrame( bool proceed, bool treat_as_final_completion_callback, RenderFrameHostImpl* frame, bool is_frame_being_destroyed, const base::TimeTicks& renderer_before_unload_start_time, - const base::TimeTicks& renderer_before_unload_end_time); + const base::TimeTicks& renderer_before_unload_end_time, + bool for_legacy); // Helper function to check whether the current frame and its subframes need // to run beforeunload and, if |send_ipc| is true, send all the necessary
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 4d347915d..c6e35d1 100644 --- a/content/browser/renderer_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_browsertest.cc
@@ -582,7 +582,8 @@ using RenderFrameHostImpl::RenderFrameHostImpl; void SendBeforeUnload(bool is_reload, - base::WeakPtr<RenderFrameHostImpl> rfh) override { + base::WeakPtr<RenderFrameHostImpl> rfh, + bool for_legacy) override { rfh->GetAssociatedLocalFrame()->BeforeUnload(is_reload, base::DoNothing()); } @@ -6539,4 +6540,45 @@ EXPECT_TRUE(child_b->IsErrorDocument()); } +class RenderFrameHostImplAvoidUnnecessaryBeforeUnloadBrowserTest + : public RenderFrameHostImplBeforeUnloadBrowserTest { + public: + RenderFrameHostImplAvoidUnnecessaryBeforeUnloadBrowserTest() { + scoped_feature_list_.InitAndEnableFeature( + features::kAvoidUnnecessaryBeforeUnloadCheck); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +// Ensure that navigating with a frame tree of A(B(A)) results in the right +// number of beforeunload messages sent when the feature +// `kAvoidUnnecessaryBeforeUnloadCheck` is set. +IN_PROC_BROWSER_TEST_F( + RenderFrameHostImplAvoidUnnecessaryBeforeUnloadBrowserTest, + RendererInitiatedNavigationInABA) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b(a))")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + + // Install a beforeunload handler to send a ping from both a's. + FrameTreeNode* root = web_contents()->GetPrimaryFrameTree().root(); + InstallBeforeUnloadHandler(root->child_at(0)->child_at(0), SEND_PING); + + // Disable beforeunload timer to prevent flakiness. + PrepContentsForBeforeUnloadTest(web_contents()); + + // Navigate the main frame. + DOMMessageQueue msg_queue; + GURL new_url(embedded_test_server()->GetURL("c.com", "/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), new_url)); + + // We should have received one pings (for the grandchild 'a'). + EXPECT_EQ(1, RetrievePingsFromMessageQueue(&msg_queue)); + + // We shouldn't have seen any beforeunload dialogs. + EXPECT_EQ(0, dialog_manager()->num_beforeunload_dialogs_seen()); +} + } // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_impl_unittest.cc b/content/browser/renderer_host/render_frame_host_impl_unittest.cc index 7a19df3..9736b6d 100644 --- a/content/browser/renderer_host/render_frame_host_impl_unittest.cc +++ b/content/browser/renderer_host/render_frame_host_impl_unittest.cc
@@ -8,6 +8,7 @@ #include "content/browser/renderer_host/navigation_controller_impl.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/public/common/content_features.h" +#include "content/public/test/fake_local_frame.h" #include "content/public/test/test_utils.h" #include "content/test/navigation_simulator_impl.h" #include "content/test/test_render_view_host.h" @@ -344,26 +345,78 @@ grandchild_frame->GetNetworkIsolationKey().GetNonce().value()); } -TEST_F(RenderFrameHostImplTest, NoBeforeUnloadCheckForBrowserInitiated) { +// FakeLocalFrame implementation that records calls to BeforeUnload(). +class FakeLocalFrameWithBeforeUnload : public content::FakeLocalFrame { + public: + explicit FakeLocalFrameWithBeforeUnload(TestRenderFrameHost* test_host) { + Init(test_host->GetRemoteAssociatedInterfaces()); + } + + bool was_before_unload_called() const { return was_before_unload_called_; } + + void RunBeforeUnloadCallback() { + ASSERT_TRUE(before_unload_callback_); + std::move(before_unload_callback_) + .Run(true, base::TimeTicks::Now(), base::TimeTicks::Now()); + } + + // FakeLocalFrame: + void BeforeUnload(bool is_reload, BeforeUnloadCallback callback) override { + was_before_unload_called_ = true; + before_unload_callback_ = std::move(callback); + } + + private: + bool was_before_unload_called_ = false; + BeforeUnloadCallback before_unload_callback_; +}; + +// Verifies BeforeUnload() is not sent to renderer if there is no before +// unload handler present. +TEST_F(RenderFrameHostImplTest, BeforeUnloadNotSentToRenderer) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndEnableFeature( features::kAvoidUnnecessaryBeforeUnloadCheck); - contents()->GetController().LoadURLWithParams( - NavigationController::LoadURLParams( - GURL("https://example.com/navigation.html"))); + FakeLocalFrameWithBeforeUnload local_frame(contents()->GetMainFrame()); + auto simulator = NavigationSimulatorImpl::CreateBrowserInitiated( + GURL("https://example.com/simple.html"), contents()); + simulator->set_block_invoking_before_unload_completed_callback(true); + simulator->Start(); + EXPECT_TRUE( + contents()->GetMainFrame()->is_waiting_for_beforeunload_completion()); + EXPECT_FALSE(local_frame.was_before_unload_called()); + // This is necessary to trigger FakeLocalFrameWithBeforeUnload to be bound. + contents()->GetMainFrame()->FlushLocalFrameMessages(); + // This runs a MessageLoop, which also results in the PostTask() scheduled + // completing. + local_frame.FlushMessages(); + EXPECT_FALSE(local_frame.was_before_unload_called()); + // Because of the nested message loops run by the previous calls, the task + // that RenderFrameHostImpl will have also completed. EXPECT_FALSE( contents()->GetMainFrame()->is_waiting_for_beforeunload_completion()); } -TEST_F(RenderFrameHostImplTest, BeforeUnloadCheckForBrowserInitiated) { +// Verifies BeforeUnloadNotSentToRenderer() is sent to renderer. +TEST_F(RenderFrameHostImplTest, BeforeUnloadSentToRenderer) { base::test::ScopedFeatureList scoped_feature_list; scoped_feature_list.InitAndDisableFeature( features::kAvoidUnnecessaryBeforeUnloadCheck); - contents()->GetController().LoadURLWithParams( - NavigationController::LoadURLParams( - GURL("https://example.com/navigation.html"))); + FakeLocalFrameWithBeforeUnload local_frame(contents()->GetMainFrame()); + auto simulator = NavigationSimulatorImpl::CreateBrowserInitiated( + GURL("https://example.com/simple.html"), contents()); + simulator->set_block_invoking_before_unload_completed_callback(true); + simulator->Start(); EXPECT_TRUE( contents()->GetMainFrame()->is_waiting_for_beforeunload_completion()); + // This is necessary to trigger FakeLocalFrameWithBeforeUnload to be bound. + contents()->GetMainFrame()->FlushLocalFrameMessages(); + local_frame.FlushMessages(); + EXPECT_TRUE(local_frame.was_before_unload_called()); + EXPECT_TRUE( + contents()->GetMainFrame()->is_waiting_for_beforeunload_completion()); + // Needed to avoid DCHECK in mojo if callback is not run. + local_frame.RunBeforeUnloadCallback(); } } // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc index 02bb9a0..e2e5a428 100644 --- a/content/browser/renderer_host/render_frame_host_manager_browsertest.cc +++ b/content/browser/renderer_host/render_frame_host_manager_browsertest.cc
@@ -4817,7 +4817,7 @@ // TODO(nasko): Investigate making a failing reload of a successful // navigation be classified as NEW_ENTRY instead, since with error page // isolation it involves a SiteInstance swap. - EXPECT_EQ(NavigationType::NAVIGATION_TYPE_EXISTING_ENTRY, + EXPECT_EQ(NavigationType::NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, reload_observer.last_navigation_type()); } EXPECT_EQ(3, nav_controller.GetEntryCount()); @@ -4834,7 +4834,7 @@ shell()->web_contents()->GetController().Reload(ReloadType::NORMAL, false); reload_observer.Wait(); EXPECT_FALSE(reload_observer.last_navigation_succeeded()); - EXPECT_EQ(NavigationType::NAVIGATION_TYPE_EXISTING_ENTRY, + EXPECT_EQ(NavigationType::NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, reload_observer.last_navigation_type()); } EXPECT_EQ(process_id, @@ -4853,7 +4853,7 @@ // The successful reload should be classified as a NEW_ENTRY navigation // with replacement, since it needs to stay at the same entry in session // history, but needs a new entry because of the change in SiteInstance. - EXPECT_EQ(NavigationType::NAVIGATION_TYPE_NEW_ENTRY, + EXPECT_EQ(NavigationType::NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, reload_observer.last_navigation_type()); } EXPECT_EQ(3, nav_controller.GetEntryCount()); @@ -4876,7 +4876,7 @@ // TODO(nasko): Investigate making a failing reload of a successful // navigation be classified as NEW_ENTRY instead, since with error page // isolation it involves a SiteInstance swap. - EXPECT_EQ(NavigationType::NAVIGATION_TYPE_EXISTING_ENTRY, + EXPECT_EQ(NavigationType::NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, reload_observer.last_navigation_type()); } EXPECT_EQ(3, nav_controller.GetEntryCount()); @@ -4895,7 +4895,7 @@ EXPECT_TRUE(reload_observer.last_navigation_succeeded()); // TODO(nasko): Investigate making renderer initiated reloads that change // SiteInstance be classified as NEW_ENTRY as well. - EXPECT_EQ(NavigationType::NAVIGATION_TYPE_EXISTING_ENTRY, + EXPECT_EQ(NavigationType::NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, reload_observer.last_navigation_type()); } EXPECT_EQ(3, nav_controller.GetEntryCount()); @@ -5199,10 +5199,10 @@ // with replacement, since it needs to stay at the same entry in session // history, but needs a new entry because of the change in SiteInstance. // (the same as expectations in the ErrorPageNavigationReload test above). - EXPECT_EQ(NavigationType::NAVIGATION_TYPE_NEW_ENTRY, + EXPECT_EQ(NavigationType::NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, reload_observer.last_navigation_type()); } else { - EXPECT_EQ(NavigationType::NAVIGATION_TYPE_EXISTING_ENTRY, + EXPECT_EQ(NavigationType::NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, reload_observer.last_navigation_type()); } }
diff --git a/content/browser/renderer_host/render_frame_metadata_provider_impl.h b/content/browser/renderer_host/render_frame_metadata_provider_impl.h index 1f985de..ed4085df 100644 --- a/content/browser/renderer_host/render_frame_metadata_provider_impl.h +++ b/content/browser/renderer_host/render_frame_metadata_provider_impl.h
@@ -10,6 +10,7 @@ #include "base/time/time.h" #include "build/build_config.h" #include "cc/mojom/render_frame_metadata.mojom.h" +#include "content/common/content_export.h" #include "content/public/browser/render_frame_metadata_provider.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h"
diff --git a/content/browser/renderer_host/render_frame_proxy_host.h b/content/browser/renderer_host/render_frame_proxy_host.h index c48b8ca5..419a37d 100644 --- a/content/browser/renderer_host/render_frame_proxy_host.h +++ b/content/browser/renderer_host/render_frame_proxy_host.h
@@ -11,6 +11,7 @@ #include "base/callback_forward.h" #include "content/browser/site_instance_impl.h" +#include "content/common/content_export.h" #include "content/common/frame.mojom.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h"
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h index 5ea35d5..b4d9327 100644 --- a/content/browser/renderer_host/render_message_filter.h +++ b/content/browser/renderer_host/render_message_filter.h
@@ -14,6 +14,7 @@ #include "base/memory/weak_ptr.h" #include "base/task/sequenced_task_runner_helpers.h" #include "build/build_config.h" +#include "content/common/content_export.h" #include "content/common/render_message_filter.mojom.h" #include "content/public/browser/browser_associated_interface.h" #include "content/public/browser/browser_message_filter.h"
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index ea72307c..91731a3 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -26,6 +26,7 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_owner_delegate.h" #include "content/browser/site_instance_impl.h" +#include "content/common/content_export.h" #include "content/common/render_message_filter.mojom.h" #include "content/public/browser/global_routing_id.h" #include "content/public/browser/notification_observer.h"
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 569f772..3d20ce70 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -45,6 +45,7 @@ #include "content/browser/renderer_host/render_widget_host_delegate.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/scheduler/browser_task_executor.h" +#include "content/common/content_export.h" #include "content/common/frame.mojom-forward.h" #include "content/public/browser/render_process_host_observer.h" #include "content/public/browser/render_widget_host.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h index 13bb94e..2ea76f1 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h +++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper.h
@@ -10,6 +10,7 @@ #include "base/gtest_prod_util.h" #import "content/app_shim_remote_cocoa/render_widget_host_view_cocoa.h" #include "content/browser/renderer_host/render_widget_host_view_mac.h" +#include "content/common/content_export.h" namespace content {
diff --git a/content/browser/renderer_host/renderer_sandboxed_process_launcher_delegate.h b/content/browser/renderer_host/renderer_sandboxed_process_launcher_delegate.h index bf78e0d..29d99ad 100644 --- a/content/browser/renderer_host/renderer_sandboxed_process_launcher_delegate.h +++ b/content/browser/renderer_host/renderer_sandboxed_process_launcher_delegate.h
@@ -7,6 +7,7 @@ #include "base/command_line.h" #include "build/build_config.h" +#include "content/common/content_export.h" #include "content/public/common/sandboxed_process_launcher_delegate.h" #include "sandbox/policy/mojom/sandbox.mojom.h" @@ -50,4 +51,4 @@ } // namespace content -#endif // CONTENT_BROWSER_RENDERER_HOST_RENDERER_SANDBOXED_PROCESS_LAUNCHER_DELEGATE_H_ \ No newline at end of file +#endif // CONTENT_BROWSER_RENDERER_HOST_RENDERER_SANDBOXED_PROCESS_LAUNCHER_DELEGATE_H_
diff --git a/content/browser/resources/attribution_reporting/attribution_internals.html b/content/browser/resources/attribution_reporting/attribution_internals.html index 89a00a3a..253668d 100644 --- a/content/browser/resources/attribution_reporting/attribution_internals.html +++ b/content/browser/resources/attribution_reporting/attribution_internals.html
@@ -18,7 +18,7 @@ Attribution Reporting API Internals </div> <div id="info"> - <p>Attribution reporting is currently <span id="feature-status-content"></span>. + <p>Attribution reporting is currently <span id="feature-status-content"></span> in this browser. </div> <hr> <div id="page-content">
diff --git a/content/browser/scheduler/responsiveness/jank_monitor_impl.h b/content/browser/scheduler/responsiveness/jank_monitor_impl.h index 0dc461a..1ed4ab0 100644 --- a/content/browser/scheduler/responsiveness/jank_monitor_impl.h +++ b/content/browser/scheduler/responsiveness/jank_monitor_impl.h
@@ -16,6 +16,7 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "content/browser/scheduler/responsiveness/metric_source.h" +#include "content/common/content_export.h" #include "content/public/browser/jank_monitor.h" #include "third_party/abseil-cpp/absl/types/optional.h"
diff --git a/content/browser/scheduler/responsiveness/watcher.h b/content/browser/scheduler/responsiveness/watcher.h index 0e5db74..2c24ada 100644 --- a/content/browser/scheduler/responsiveness/watcher.h +++ b/content/browser/scheduler/responsiveness/watcher.h
@@ -10,6 +10,7 @@ #include "base/gtest_prod_util.h" #include "base/time/time.h" #include "content/browser/scheduler/responsiveness/metric_source.h" +#include "content/common/content_export.h" namespace content { namespace responsiveness {
diff --git a/content/browser/service_worker/service_worker_main_resource_loader.h b/content/browser/service_worker/service_worker_main_resource_loader.h index 250a00b..2eca5fd 100644 --- a/content/browser/service_worker/service_worker_main_resource_loader.h +++ b/content/browser/service_worker/service_worker_main_resource_loader.h
@@ -14,6 +14,7 @@ #include "content/browser/loader/navigation_loader_interceptor.h" #include "content/browser/service_worker/embedded_worker_status.h" #include "content/browser/service_worker/service_worker_fetch_dispatcher.h" +#include "content/common/content_export.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h"
diff --git a/content/browser/service_worker/service_worker_metrics.h b/content/browser/service_worker/service_worker_metrics.h index d65889c..3c7769f2 100644 --- a/content/browser/service_worker/service_worker_metrics.h +++ b/content/browser/service_worker/service_worker_metrics.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include "base/time/time.h" +#include "content/common/content_export.h" #include "content/public/browser/service_worker_context.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "ui/base/page_transition_types.h"
diff --git a/content/browser/service_worker/service_worker_process_manager.h b/content/browser/service_worker/service_worker_process_manager.h index dd72f5f4..2a3ff868 100644 --- a/content/browser/service_worker/service_worker_process_manager.h +++ b/content/browser/service_worker/service_worker_process_manager.h
@@ -14,6 +14,7 @@ #include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "content/browser/service_worker/service_worker_metrics.h" +#include "content/common/content_export.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
diff --git a/content/browser/service_worker/service_worker_register_job.h b/content/browser/service_worker/service_worker_register_job.h index 9d2a0df4..6185eb1 100644 --- a/content/browser/service_worker/service_worker_register_job.h +++ b/content/browser/service_worker/service_worker_register_job.h
@@ -14,6 +14,7 @@ #include "content/browser/service_worker/service_worker_register_job_base.h" #include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_update_checker.h" +#include "content/common/content_export.h" #include "content/public/browser/global_routing_id.h" #include "third_party/blink/public/common/service_worker/service_worker_status_code.h" #include "third_party/blink/public/common/storage_key/storage_key.h"
diff --git a/content/browser/service_worker/service_worker_type_converters.h b/content/browser/service_worker/service_worker_type_converters.h index 09ab249..0ca17c8c 100644 --- a/content/browser/service_worker/service_worker_type_converters.h +++ b/content/browser/service_worker/service_worker_type_converters.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_TYPE_CONVERTERS_H_ #include "content/browser/service_worker/service_worker_version.h" +#include "content/common/content_export.h" #include "third_party/blink/public/mojom/service_worker/service_worker_state.mojom.h" namespace mojo {
diff --git a/content/browser/service_worker/service_worker_update_checker.h b/content/browser/service_worker/service_worker_update_checker.h index df8e1fa..c8d3a1e 100644 --- a/content/browser/service_worker/service_worker_update_checker.h +++ b/content/browser/service_worker/service_worker_update_checker.h
@@ -12,6 +12,7 @@ #include "base/callback.h" #include "content/browser/service_worker/service_worker_single_script_update_checker.h" #include "content/browser/service_worker/service_worker_updated_script_loader.h" +#include "content/common/content_export.h" namespace network { class SharedURLLoaderFactory;
diff --git a/content/browser/site_info.cc b/content/browser/site_info.cc index 1e6872b..c5d6e0dd 100644 --- a/content/browser/site_info.cc +++ b/content/browser/site_info.cc
@@ -272,6 +272,49 @@ site_info.is_jit_disabled_, site_info.is_pdf_); } +SiteInfo SiteInfo::GetNonOriginKeyedEquivalentForMetrics( + const IsolationContext& isolation_context) const { + SiteInfo non_oac_site_info(*this); + if (requires_origin_keyed_process()) { + DCHECK(process_lock_url_.SchemeIs(url::kHttpsScheme)); + non_oac_site_info.requires_origin_keyed_process_ = false; + + // TODO(wjmaclean): It would probably be better if we just changed + // SiteInstanceImpl::original_url_ to be SiteInfo::original_url_info_ and + // use that to recreate the SiteInfo with origin keying turned off. But + // that's a largish refactor in its own, since it would require making all + // SiteInfo creation go through SiteInfo::CreateInternal. + // We'll do the following for now and do the refactor separately. + // The code below creates a simple non-origin-keyed equivalent for this + // SiteInfo by (1) Converting the process lock to its equivalent by either + // seeing if it has a command-line isolated-origin it should use, and if not + // then just using GetSiteForOrigin to convert it, and (2) doing the same + // for the SiteUrl, but only if the SiteUrl and ProcessLockUrl match + // prior to the conversion, otherwise leave the SiteUrl as is. + auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); + url::Origin result_origin; + // We need to make the following call with a 'null' IsolationContext, + // otherwise the OAC history will just opt us back into an origin-keyed + // SiteInfo. + if (policy->GetMatchingProcessIsolatedOrigin( + IsolationContext(BrowsingInstanceId(0), + isolation_context.browser_or_resource_context()), + url::Origin::Create(process_lock_url_), + false /* origin_requests_isolation */, &result_origin)) { + non_oac_site_info.process_lock_url_ = result_origin.GetURL(); + } else { + non_oac_site_info.process_lock_url_ = + GetSiteForOrigin(url::Origin::Create(process_lock_url_)); + } + // Only convert the site_url_ if it matches the process_lock_url_, otherwise + // leave it alone. This will only matter for hosted apps, and we only expect + // them to differ if an effective URL is defined. + if (site_url_ == process_lock_url_) + non_oac_site_info.site_url_ = non_oac_site_info.process_lock_url_; + } + return non_oac_site_info; +} + SiteInfo& SiteInfo::operator=(const SiteInfo& rhs) = default; bool SiteInfo::IsSamePrincipalWith(const SiteInfo& other) const {
diff --git a/content/browser/site_info.h b/content/browser/site_info.h index b1fafad3..1c7d283 100644 --- a/content/browser/site_info.h +++ b/content/browser/site_info.h
@@ -124,6 +124,13 @@ SiteInfo(const SiteInfo& rhs); ~SiteInfo(); + // This function returns a new SiteInfo which is equivalent to the original, + // except that (1) is_origin_keyed is false, and (2) the remaining SiteInfo + // state is used to compute a new SiteInfo from a UrlInfo reconstructed from + // the original SiteInfo, minus any OAC opt-in request. + SiteInfo GetNonOriginKeyedEquivalentForMetrics( + const IsolationContext& isolation_context) const; + // Returns the site URL associated with all of the documents and workers in // this principal, as described above. //
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc index a76e273..5e0324c 100644 --- a/content/browser/site_instance_impl.cc +++ b/content/browser/site_instance_impl.cc
@@ -1323,4 +1323,8 @@ proto->set_active_rfh_count(active_frame_count_); } +int SiteInstanceImpl::EstimateOriginAgentClusterOverheadForMetrics() { + return browsing_instance_->EstimateOriginAgentClusterOverhead(); +} + } // namespace content
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h index f317370..03cde26a 100644 --- a/content/browser/site_instance_impl.h +++ b/content/browser/site_instance_impl.h
@@ -145,6 +145,7 @@ bool IsGuest() override; SiteInstanceProcessAssignment GetLastProcessAssignmentOutcome() override; void WriteIntoTrace(perfetto::TracedValue context) override; + int EstimateOriginAgentClusterOverheadForMetrics() override; // Write a representation of this object into a trace. void WriteIntoTrace(
diff --git a/content/browser/site_instance_impl_unittest.cc b/content/browser/site_instance_impl_unittest.cc index 74048a3..4d57a91 100644 --- a/content/browser/site_instance_impl_unittest.cc +++ b/content/browser/site_instance_impl_unittest.cc
@@ -146,17 +146,6 @@ SetBrowserClientForTesting(old_browser_client_); RenderProcessHostImpl::set_render_process_host_factory_for_testing(nullptr); - - // http://crbug.com/143565 found SiteInstanceTest leaking an - // AppCacheDatabase. This happens because some part of the test indirectly - // calls StoragePartitionImplMap::PostCreateInitialization(), which posts - // a task to the IO thread to create the AppCacheDatabase. Since the - // message loop is not running, the AppCacheDatabase ends up getting - // created when DrainMessageLoop() gets called at the end of a test case. - // Immediately after, the test case ends and the AppCacheDatabase gets - // scheduled for deletion. Here, call DrainMessageLoop() again so the - // AppCacheDatabase actually gets deleted. - DrainMessageLoop(); } void set_privileged_process_id(int process_id) { @@ -1972,4 +1961,26 @@ .storage_partition_config()); } +TEST_F(SiteInstanceTest, GetNonOriginKeyedEquivalentPreservesIsPdf) { + auto origin_isolation_request = static_cast<UrlInfo::OriginIsolationRequest>( + UrlInfo::OriginIsolationRequest::kOriginAgentCluster | + UrlInfo::OriginIsolationRequest::kRequiresOriginKeyedProcess); + UrlInfo url_info_pdf_with_oac( + UrlInfoInit(GURL("https://foo.com/test.pdf")) + .WithOriginIsolationRequest(origin_isolation_request) + .WithIsPdf(true)); + SiteInfo site_info_pdf_with_origin_key = + SiteInfo::Create(IsolationContext(context()), url_info_pdf_with_oac); + SiteInfo site_info_pdf_no_origin_key = + site_info_pdf_with_origin_key.GetNonOriginKeyedEquivalentForMetrics( + IsolationContext(context())); + + // Verify that the non-origin-keyed equivalent still has the is_pdf flag set + // but has the is_origin_keyed flag cleared. + EXPECT_TRUE(site_info_pdf_with_origin_key.is_pdf()); + EXPECT_TRUE(site_info_pdf_no_origin_key.is_pdf()); + EXPECT_TRUE(site_info_pdf_with_origin_key.requires_origin_keyed_process()); + EXPECT_FALSE(site_info_pdf_no_origin_key.requires_origin_keyed_process()); +} + } // namespace content
diff --git a/content/browser/speech/speech_recognition_manager_impl.h b/content/browser/speech/speech_recognition_manager_impl.h index 7077c2fd..0552f1c 100644 --- a/content/browser/speech/speech_recognition_manager_impl.h +++ b/content/browser/speech/speech_recognition_manager_impl.h
@@ -10,6 +10,7 @@ #include "base/compiler_specific.h" #include "base/containers/flat_map.h" #include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/speech_recognition_event_listener.h" #include "content/public/browser/speech_recognition_manager.h"
diff --git a/content/browser/speech/speech_recognizer_impl.h b/content/browser/speech/speech_recognizer_impl.h index 69a07277..dc96e3e 100644 --- a/content/browser/speech/speech_recognizer_impl.h +++ b/content/browser/speech/speech_recognizer_impl.h
@@ -13,6 +13,7 @@ #include "content/browser/speech/endpointer/endpointer.h" #include "content/browser/speech/speech_recognition_engine.h" #include "content/browser/speech/speech_recognizer.h" +#include "content/common/content_export.h" #include "media/base/audio_capturer_source.h" #include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h" #include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
diff --git a/content/browser/speech/speech_recognizer_impl_android.h b/content/browser/speech/speech_recognizer_impl_android.h index 0abdf042..d9d4bf8 100644 --- a/content/browser/speech/speech_recognizer_impl_android.h +++ b/content/browser/speech/speech_recognizer_impl_android.h
@@ -12,6 +12,7 @@ #include "base/android/scoped_java_ref.h" #include "base/memory/ref_counted.h" #include "content/browser/speech/speech_recognizer.h" +#include "content/common/content_export.h" #include "third_party/blink/public/mojom/speech/speech_recognition_error.mojom.h" #include "third_party/blink/public/mojom/speech/speech_recognition_result.mojom.h"
diff --git a/content/browser/speech/tts_utterance_impl.h b/content/browser/speech/tts_utterance_impl.h index e4f5aee..b5a3b9a 100644 --- a/content/browser/speech/tts_utterance_impl.h +++ b/content/browser/speech/tts_utterance_impl.h
@@ -10,6 +10,7 @@ #include <string> #include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" #include "content/public/browser/tts_utterance.h" namespace base {
diff --git a/content/browser/startup_task_runner.h b/content/browser/startup_task_runner.h index 7713038..417767d3f 100644 --- a/content/browser/startup_task_runner.h +++ b/content/browser/startup_task_runner.h
@@ -9,6 +9,7 @@ #include "base/callback.h" #include "base/task/single_thread_task_runner.h" +#include "content/common/content_export.h" #include "build/build_config.h"
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 414c2c77..3f05c9eb 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -1298,7 +1298,7 @@ cookie_store_manager_->LoadAllSubscriptions(base::DoNothing()); bucket_context_ = base::MakeRefCounted<BucketContext>(); - bucket_context_->Initialize(); + bucket_context_->Initialize(quota_manager_proxy); // The Conversion Measurement API is not available in Incognito mode. if (!is_in_memory() &&
diff --git a/content/browser/storage_partition_impl_map.h b/content/browser/storage_partition_impl_map.h index 5adf9715..b985bdf3 100644 --- a/content/browser/storage_partition_impl_map.h +++ b/content/browser/storage_partition_impl_map.h
@@ -14,6 +14,7 @@ #include "base/gtest_prod_util.h" #include "base/supports_user_data.h" #include "content/browser/storage_partition_impl.h" +#include "content/common/content_export.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition_config.h"
diff --git a/content/browser/tracing/background_reached_code_tracing_observer_android.h b/content/browser/tracing/background_reached_code_tracing_observer_android.h index a65aa79..15bb6d4 100644 --- a/content/browser/tracing/background_reached_code_tracing_observer_android.h +++ b/content/browser/tracing/background_reached_code_tracing_observer_android.h
@@ -8,6 +8,7 @@ #include <memory> #include "content/browser/tracing/background_tracing_manager_impl.h" +#include "content/common/content_export.h" namespace content {
diff --git a/content/browser/tracing/background_startup_tracing_observer.h b/content/browser/tracing/background_startup_tracing_observer.h index 0bd3d6c3..22ac934 100644 --- a/content/browser/tracing/background_startup_tracing_observer.h +++ b/content/browser/tracing/background_startup_tracing_observer.h
@@ -8,6 +8,7 @@ #include <memory> #include "content/browser/tracing/background_tracing_manager_impl.h" +#include "content/common/content_export.h" namespace content {
diff --git a/content/browser/tracing/background_tracing_active_scenario.h b/content/browser/tracing/background_tracing_active_scenario.h index 1b8c7c0b..fb24a4b 100644 --- a/content/browser/tracing/background_tracing_active_scenario.h +++ b/content/browser/tracing/background_tracing_active_scenario.h
@@ -11,6 +11,7 @@ #include "base/memory/weak_ptr.h" #include "content/browser/tracing/background_tracing_config_impl.h" #include "content/browser/tracing/tracing_controller_impl.h" +#include "content/common/content_export.h" #include "content/public/browser/background_tracing_manager.h" #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h"
diff --git a/content/browser/tracing/background_tracing_manager_impl.h b/content/browser/tracing/background_tracing_manager_impl.h index 451112b7..59a27474 100644 --- a/content/browser/tracing/background_tracing_manager_impl.h +++ b/content/browser/tracing/background_tracing_manager_impl.h
@@ -13,6 +13,7 @@ #include "base/no_destructor.h" #include "content/browser/tracing/background_tracing_config_impl.h" +#include "content/common/content_export.h" #include "content/public/browser/background_tracing_manager.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/tracing/public/cpp/perfetto/trace_event_data_source.h"
diff --git a/content/browser/tracing/tracing_ui.h b/content/browser/tracing/tracing_ui.h index 835d4690..aea1bfd 100644 --- a/content/browser/tracing/tracing_ui.h +++ b/content/browser/tracing/tracing_ui.h
@@ -11,6 +11,7 @@ #include <string> #include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" #include "content/public/browser/web_ui_controller.h" namespace base {
diff --git a/content/browser/utility_process_host.cc b/content/browser/utility_process_host.cc index a935d02..d2d1d553 100644 --- a/content/browser/utility_process_host.cc +++ b/content/browser/utility_process_host.cc
@@ -16,7 +16,6 @@ #include "base/i18n/base_i18n_switches.h" #include "base/strings/utf_string_conversions.h" #include "base/task/sequenced_task_runner.h" -#include "build/chromeos_buildflags.h" #include "components/network_session_configurator/common/network_switches.h" #include "content/browser/browser_child_process_host_impl.h" #include "content/browser/gpu/gpu_data_manager_impl.h" @@ -226,10 +225,7 @@ network::switches::kLogNetLog, network::switches::kNetLogCaptureMode, sandbox::policy::switches::kNoSandbox, -// TODO(crbug.com/1052397): Revisit the macro expression once build flag switch -// of lacros-chrome is complete. -#if defined(OS_LINUX) && !BUILDFLAG(IS_CHROMEOS_ASH) && \ - !BUILDFLAG(IS_CHROMEOS_LACROS) +#if defined(OS_LINUX) && !defined(OS_CHROMEOS) switches::kDisableDevShmUsage, #endif #if defined(OS_MAC)
diff --git a/content/browser/web_package/web_bundle_browsertest_base.cc b/content/browser/web_package/web_bundle_browsertest_base.cc index c972258..5d98ad7 100644 --- a/content/browser/web_package/web_bundle_browsertest_base.cc +++ b/content/browser/web_package/web_bundle_browsertest_base.cc
@@ -710,14 +710,14 @@ get_url_for_bundle.Run(url_origin.Resolve("/top-page/")), "Ready"); RunScriptAndObserveNavigation( "Navigate to /1-page/", web_contents, web_contents /* execution_target */, - "location.href = '/1-page/';", {NAVIGATION_TYPE_NEW_ENTRY}, + "location.href = '/1-page/';", {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/1-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/") /* expected_last_inner_url */, "/1-page/ from wbn, /1-page/script from wbn"); RunScriptAndObserveNavigation( "Navigate to /2-page/", web_contents, web_contents /* execution_target */, - "location.href = '/2-page/';", {NAVIGATION_TYPE_NEW_ENTRY}, + "location.href = '/2-page/';", {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/2-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/2-page/") /* expected_last_inner_url */, @@ -725,7 +725,7 @@ RunScriptAndObserveNavigation( "Back navigate to /1-page/", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/1-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/") /* expected_last_inner_url */, @@ -733,7 +733,7 @@ RunScriptAndObserveNavigation( "Back navigate to /top-page/", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/top-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/top-page/") /* expected_last_inner_url */, @@ -741,14 +741,14 @@ RunScriptAndObserveNavigation( "Forward navigate to /1-page/", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/1-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/") /* expected_last_inner_url */, "/1-page/ from wbn, /1-page/script from wbn"); RunScriptAndObserveNavigation( "Reload /1-page/", web_contents, web_contents /* execution_target */, - "location.reload();", {NAVIGATION_TYPE_EXISTING_ENTRY}, + "location.reload();", {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/1-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/") /* expected_last_inner_url */, @@ -756,7 +756,7 @@ RunScriptAndObserveNavigation( "Forward navigate to /2-page/", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/2-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/2-page/") /* expected_last_inner_url */, @@ -782,14 +782,14 @@ get_url_for_bundle.Run(url_origin.Resolve("/top-page/")), "Ready"); RunScriptAndObserveNavigation( "Navigate to /1-page/", web_contents, web_contents /* execution_target */, - "location.href = '/1-page/';", {NAVIGATION_TYPE_NEW_ENTRY}, + "location.href = '/1-page/';", {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/1-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/") /* expected_last_inner_url */, "/1-page/ from wbn, /1-page/script from wbn"); RunScriptAndObserveNavigation( "Navigate to /2-page/", web_contents, web_contents /* execution_target */, - "location.href = '/2-page/';", {NAVIGATION_TYPE_NEW_ENTRY}, + "location.href = '/2-page/';", {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/2-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/2-page/") /* expected_last_inner_url */, @@ -808,21 +808,21 @@ // even if the page is in the web bundle. RunScriptAndObserveNavigation( "Navigate to /4-page/", web_contents, web_contents /* execution_target */, - "location.href = '/4-page/';", {NAVIGATION_TYPE_NEW_ENTRY}, + "location.href = '/4-page/';", {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, url_origin.Resolve("/4-page/") /* expected_last_comitted_url */, url_origin.Resolve("/4-page/") /* expected_last_inner_url */, "/4-page/ from server, /4-page/script from server"); RunScriptAndObserveNavigation( "Back navigate to /3-page/", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, url_origin.Resolve("/3-page/") /* expected_last_comitted_url */, url_origin.Resolve("/3-page/") /* expected_last_inner_url */, "/3-page/ from server, /3-page/script from server"); RunScriptAndObserveNavigation( "Back navigate to /2-page/", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/2-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/2-page/") /* expected_last_inner_url */, @@ -830,7 +830,7 @@ RunScriptAndObserveNavigation( "Back navigate to /1-page/", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/1-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/") /* expected_last_inner_url */, @@ -838,7 +838,7 @@ RunScriptAndObserveNavigation( "Forward navigate to /2-page/", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/2-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/2-page/") /* expected_last_inner_url */, @@ -846,14 +846,14 @@ RunScriptAndObserveNavigation( "Forward navigate to /3-page/", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, url_origin.Resolve("/3-page/") /* expected_last_comitted_url */, url_origin.Resolve("/3-page/") /* expected_last_inner_url */, "/3-page/ from server, /3-page/script from server"); RunScriptAndObserveNavigation( "Forward navigate to /4-page/", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, url_origin.Resolve("/4-page/") /* expected_last_comitted_url */, url_origin.Resolve("/4-page/") /* expected_last_inner_url */, "/4-page/ from server, /4-page/script from server"); @@ -878,14 +878,14 @@ get_url_for_bundle.Run(url_origin.Resolve("/top-page/")), "Ready"); RunScriptAndObserveNavigation( "Navigate to /1-page/", web_contents, web_contents /* execution_target */, - "location.href = '/1-page/';", {NAVIGATION_TYPE_NEW_ENTRY}, + "location.href = '/1-page/';", {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/1-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/") /* expected_last_inner_url */, "/1-page/ from wbn, /1-page/script from wbn"); RunScriptAndObserveNavigation( "Navigate to /2-page/", web_contents, web_contents /* execution_target */, - "location.href = '/2-page/';", {NAVIGATION_TYPE_NEW_ENTRY}, + "location.href = '/2-page/';", {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/2-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/2-page/") /* expected_last_inner_url */, @@ -893,7 +893,7 @@ RunScriptAndObserveNavigation( "Navigate to /server-page/", web_contents, web_contents /* execution_target */, "location.href = '/server-page/';", - {NAVIGATION_TYPE_NEW_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, url_origin.Resolve("/server-page/") /* expected_last_comitted_url */, url_origin.Resolve("/server-page/") /* expected_last_inner_url */, "/server-page/ from server, /server-page/script from server"); @@ -901,21 +901,21 @@ // even if the page is in the web bundle. RunScriptAndObserveNavigation( "Navigate to /3-page/", web_contents, web_contents /* execution_target */, - "location.href = '/3-page/';", {NAVIGATION_TYPE_NEW_ENTRY}, + "location.href = '/3-page/';", {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, url_origin.Resolve("/3-page/") /* expected_last_comitted_url */, url_origin.Resolve("/3-page/") /* expected_last_inner_url */, "/3-page/ from server, /3-page/script from server"); RunScriptAndObserveNavigation( "Back navigate to /server-page/", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, url_origin.Resolve("/server-page/") /* expected_last_comitted_url */, url_origin.Resolve("/server-page/") /* expected_last_inner_url */, "/server-page/ from server, /server-page/script from server"); RunScriptAndObserveNavigation( "Back navigate to /2-page/", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/2-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/2-page/") /* expected_last_inner_url */, @@ -923,7 +923,7 @@ RunScriptAndObserveNavigation( "Back navigate to /1-page/", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/1-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/") /* expected_last_inner_url */, @@ -931,7 +931,7 @@ RunScriptAndObserveNavigation( "Forward navigate to /2-page/", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/2-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/2-page/") /* expected_last_inner_url */, @@ -939,14 +939,14 @@ RunScriptAndObserveNavigation( "Forward navigate to /server-page/", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, url_origin.Resolve("/server-page/") /* expected_last_comitted_url */, url_origin.Resolve("/server-page/") /* expected_last_inner_url */, "/server-page/ from server, /server-page/script from server"); RunScriptAndObserveNavigation( "Forward navigate to /3-page/", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, url_origin.Resolve("/3-page/") /* expected_last_comitted_url */, url_origin.Resolve("/3-page/") /* expected_last_inner_url */, "/3-page/ from server, /3-page/script from server"); @@ -969,7 +969,7 @@ get_url_for_bundle.Run(url_origin.Resolve("/top-page/")), "Ready"); RunScriptAndObserveNavigation( "Navigate to /1-page/", web_contents, web_contents /* execution_target */, - "location.href = '/1-page/';", {NAVIGATION_TYPE_NEW_ENTRY}, + "location.href = '/1-page/';", {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/1-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/") /* expected_last_inner_url */, @@ -977,7 +977,7 @@ RunScriptAndObserveNavigation( "Navigate to /1-page/#hash1", web_contents, web_contents /* execution_target */, "location.href = '#hash1';", - {NAVIGATION_TYPE_NEW_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, get_url_for_bundle.Run(url_origin.Resolve( "/1-page/#hash1")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/#hash1") /* expected_last_inner_url */, @@ -985,14 +985,14 @@ RunScriptAndObserveNavigation( "Navigate to /1-page/#hash2", web_contents, web_contents /* execution_target */, "location.href = '#hash2';", - {NAVIGATION_TYPE_NEW_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, get_url_for_bundle.Run(url_origin.Resolve( "/1-page/#hash2")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/#hash2") /* expected_last_inner_url */, "/1-page/ from wbn, /1-page/script from wbn"); RunScriptAndObserveNavigation( "Navigate to /2-page/", web_contents, web_contents /* execution_target */, - "location.href = '/2-page/';", {NAVIGATION_TYPE_NEW_ENTRY}, + "location.href = '/2-page/';", {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/2-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/2-page/") /* expected_last_inner_url */, @@ -1000,7 +1000,7 @@ RunScriptAndObserveNavigation( "Back navigate to /1-page/#hash2", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run(url_origin.Resolve( "/1-page/#hash2")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/#hash2") /* expected_last_inner_url */, @@ -1008,7 +1008,7 @@ RunScriptAndObserveNavigation( "Back navigate to /1-page/#hash1", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run(url_origin.Resolve( "/1-page/#hash1")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/#hash1") /* expected_last_inner_url */, @@ -1016,7 +1016,7 @@ RunScriptAndObserveNavigation( "Back navigate to /1-page/", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/1-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/") /* expected_last_inner_url */, @@ -1024,7 +1024,7 @@ RunScriptAndObserveNavigation( "Forward navigate to /1-page/#hash1", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run(url_origin.Resolve( "/1-page/#hash1")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/#hash1") /* expected_last_inner_url */, @@ -1032,7 +1032,7 @@ RunScriptAndObserveNavigation( "Forward navigate to /1-page/#hash2", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run(url_origin.Resolve( "/1-page/#hash2")) /* expected_last_comitted_url */, url_origin.Resolve("/1-page/#hash2") /* expected_last_inner_url */, @@ -1040,7 +1040,7 @@ RunScriptAndObserveNavigation( "Forward navigate to /2-page/", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/2-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/2-page/") /* expected_last_inner_url */, @@ -1082,7 +1082,7 @@ "Navigate to /iframe-test-page/", web_contents, web_contents /* execution_target */, "location.href = '/iframe-test-page/';", - {NAVIGATION_TYPE_NEW_ENTRY, NAVIGATION_TYPE_AUTO_SUBFRAME}, + {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, NAVIGATION_TYPE_AUTO_SUBFRAME}, get_url_for_bundle.Run(url_origin.Resolve( "/iframe-test-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/iframe-test-page/") /* expected_last_inner_url */, @@ -1115,7 +1115,7 @@ RunScriptAndObserveNavigation( "Back navigate to /top-page/", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/top-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/top-page/") /* expected_last_inner_url */, @@ -1124,7 +1124,8 @@ RunScriptAndObserveNavigation( "Forward navigate to /iframe-test-page/", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY, NAVIGATION_TYPE_AUTO_SUBFRAME}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + NAVIGATION_TYPE_AUTO_SUBFRAME}, get_url_for_bundle.Run(url_origin.Resolve( "/iframe-test-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/iframe-test-page/") /* expected_last_inner_url */, @@ -1157,7 +1158,7 @@ "Navigate to /iframe-test-page/", web_contents, web_contents /* execution_target */, "location.href = '/iframe-test-page/';", - {NAVIGATION_TYPE_NEW_ENTRY, NAVIGATION_TYPE_AUTO_SUBFRAME}, + {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, NAVIGATION_TYPE_AUTO_SUBFRAME}, get_url_for_bundle.Run(url_origin.Resolve( "/iframe-test-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/iframe-test-page/") /* expected_last_inner_url */, @@ -1207,7 +1208,7 @@ "Navigate to /iframe-test-page/", web_contents, web_contents /* execution_target */, "location.href = '/iframe-test-page/';", - {NAVIGATION_TYPE_NEW_ENTRY, NAVIGATION_TYPE_AUTO_SUBFRAME}, + {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, NAVIGATION_TYPE_AUTO_SUBFRAME}, get_url_for_bundle.Run(url_origin.Resolve( "/iframe-test-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/iframe-test-page/") /* expected_last_inner_url */, @@ -1274,7 +1275,7 @@ "Navigate to /iframe-test-page/", web_contents, web_contents /* execution_target */, "location.href = '/iframe-test-page/';", - {NAVIGATION_TYPE_NEW_ENTRY, NAVIGATION_TYPE_AUTO_SUBFRAME}, + {NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, NAVIGATION_TYPE_AUTO_SUBFRAME}, get_url_for_bundle.Run(url_origin.Resolve( "/iframe-test-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/iframe-test-page/") /* expected_last_inner_url */, @@ -1363,7 +1364,7 @@ RunScriptAndObserveNavigation( "Back navigate to /top-page/", web_contents, web_contents /* execution_target */, "history.back();", - {NAVIGATION_TYPE_EXISTING_ENTRY}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY}, get_url_for_bundle.Run( url_origin.Resolve("/top-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/top-page/") /* expected_last_inner_url */, @@ -1372,7 +1373,8 @@ RunScriptAndObserveNavigation( "Forward navigate to /iframe-test-page/", web_contents, web_contents /* execution_target */, "history.forward();", - {NAVIGATION_TYPE_EXISTING_ENTRY, NAVIGATION_TYPE_AUTO_SUBFRAME}, + {NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, + NAVIGATION_TYPE_AUTO_SUBFRAME}, get_url_for_bundle.Run(url_origin.Resolve( "/iframe-test-page/")) /* expected_last_comitted_url */, url_origin.Resolve("/iframe-test-page/") /* expected_last_inner_url */,
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc index fbbb12f..9a6b5e6a 100644 --- a/content/browser/webauth/authenticator_impl_unittest.cc +++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -3734,7 +3734,8 @@ device::CredentialType::kPublicKey, std::vector<uint8_t>(kTestCredentialIdLength, 2), {device::FidoTransportProtocol::kUsbHumanInterfaceDevice}); - // Same ID as `cred_a` and `cred_b` but with different transports. + // Same ID as `cred_a` and `cred_b` but with different transports. Transport + // hints from descriptors with equal IDs should be merged. device::PublicKeyCredentialDescriptor cred_c( device::CredentialType::kPublicKey, std::vector<uint8_t>(kTestCredentialIdLength, 1), @@ -3762,19 +3763,12 @@ AuthenticatorStatus::SUCCESS); EXPECT_EQ(virtual_device_factory_->mutable_state()->allow_list_history.size(), 1u); - // Transport hints from descriptors with equal IDs should be merged. device::PublicKeyCredentialDescriptor cred_a_and_c( device::CredentialType::kPublicKey, - std::vector<uint8_t>(kTestCredentialIdLength, 1), - // The union of the empty transports in `cred_a` plus the non-empty set - // from `cred_c` should still be empty, since empty set is interpreted to - // mean "any available transport". - {}); + std::vector<uint8_t>(kTestCredentialIdLength, 1)); device::PublicKeyCredentialDescriptor cred_b_and_d( device::CredentialType::kPublicKey, - std::vector<uint8_t>(kTestCredentialIdLength, 2), - {device::FidoTransportProtocol::kUsbHumanInterfaceDevice, - device::FidoTransportProtocol::kBluetoothLowEnergy}); + std::vector<uint8_t>(kTestCredentialIdLength, 2)); EXPECT_THAT( virtual_device_factory_->mutable_state()->allow_list_history.at(0), testing::UnorderedElementsAre(cred_a_and_c, cred_b_and_d)); @@ -3798,7 +3792,8 @@ device::CredentialType::kPublicKey, std::vector<uint8_t>(kTestCredentialIdLength, 2), {device::FidoTransportProtocol::kUsbHumanInterfaceDevice}); - // Same ID as `cred_a` and `cred_b` but with different transports. + // Same ID as `cred_a` and `cred_b` but with different transports. Transport + // hints from descriptors with equal IDs should be merged. device::PublicKeyCredentialDescriptor cred_c( device::CredentialType::kPublicKey, std::vector<uint8_t>(kTestCredentialIdLength, 1), @@ -3824,19 +3819,12 @@ EXPECT_EQ( virtual_device_factory_->mutable_state()->exclude_list_history.size(), 1u); - // Transport hints from descriptors with equal IDs should be merged. device::PublicKeyCredentialDescriptor cred_a_and_c( device::CredentialType::kPublicKey, - std::vector<uint8_t>(kTestCredentialIdLength, 1), - // The union of the empty transports in `cred_a` plus the non-empty set - // from `cred_c` should still be empty, since empty set is interpreted to - // mean "any available transport". - {}); + std::vector<uint8_t>(kTestCredentialIdLength, 1)); device::PublicKeyCredentialDescriptor cred_b_and_d( device::CredentialType::kPublicKey, - std::vector<uint8_t>(kTestCredentialIdLength, 2), - {device::FidoTransportProtocol::kUsbHumanInterfaceDevice, - device::FidoTransportProtocol::kBluetoothLowEnergy}); + std::vector<uint8_t>(kTestCredentialIdLength, 2)); EXPECT_THAT( virtual_device_factory_->mutable_state()->exclude_list_history.at(0), testing::UnorderedElementsAre(cred_a_and_c, cred_b_and_d));
diff --git a/content/browser/webrtc/webrtc_internals_message_handler.h b/content/browser/webrtc/webrtc_internals_message_handler.h index a60fef8..6fe6718 100644 --- a/content/browser/webrtc/webrtc_internals_message_handler.h +++ b/content/browser/webrtc/webrtc_internals_message_handler.h
@@ -7,6 +7,7 @@ #include "base/memory/ref_counted.h" #include "content/browser/webrtc/webrtc_internals_ui_observer.h" +#include "content/common/content_export.h" #include "content/public/browser/web_ui_message_handler.h" namespace base {
diff --git a/content/browser/webui/content_web_ui_controller_factory.h b/content/browser/webui/content_web_ui_controller_factory.h index ab96e93..d86d3385 100644 --- a/content/browser/webui/content_web_ui_controller_factory.h +++ b/content/browser/webui/content_web_ui_controller_factory.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_WEBUI_CONTENT_WEB_UI_CONTROLLER_FACTORY_H_ #include "base/memory/singleton.h" +#include "content/common/content_export.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_controller_factory.h"
diff --git a/content/browser/webui/web_ui_controller_factory_registry.h b/content/browser/webui/web_ui_controller_factory_registry.h index c218284a..8e18ac2 100644 --- a/content/browser/webui/web_ui_controller_factory_registry.h +++ b/content/browser/webui/web_ui_controller_factory_registry.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_WEBUI_WEB_UI_CONTROLLER_FACTORY_REGISTRY_H_ #include "base/memory/singleton.h" +#include "content/common/content_export.h" #include "content/public/browser/web_ui_controller_factory.h" namespace content {
diff --git a/content/browser/webui/web_ui_impl.h b/content/browser/webui/web_ui_impl.h index 97d53ac5..b2b3ad2 100644 --- a/content/browser/webui/web_ui_impl.h +++ b/content/browser/webui/web_ui_impl.h
@@ -13,6 +13,7 @@ #include "base/compiler_specific.h" #include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" #include "content/common/web_ui.mojom.h" #include "content/public/browser/web_ui.h" #include "mojo/public/cpp/bindings/associated_receiver.h"
diff --git a/content/browser/worker_host/dedicated_worker_hosts_for_document.h b/content/browser/worker_host/dedicated_worker_hosts_for_document.h index 1b4fa62..92edc1e 100644 --- a/content/browser/worker_host/dedicated_worker_hosts_for_document.h +++ b/content/browser/worker_host/dedicated_worker_hosts_for_document.h
@@ -7,6 +7,7 @@ #include "base/containers/flat_set.h" #include "base/memory/safe_ref.h" +#include "content/common/content_export.h" #include "content/public/browser/document_user_data.h" #include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h"
diff --git a/content/browser/worker_host/dedicated_worker_service_impl.h b/content/browser/worker_host/dedicated_worker_service_impl.h index ef17b53..84df5d2 100644 --- a/content/browser/worker_host/dedicated_worker_service_impl.h +++ b/content/browser/worker_host/dedicated_worker_service_impl.h
@@ -7,6 +7,7 @@ #include "base/containers/flat_map.h" #include "base/observer_list.h" +#include "content/common/content_export.h" #include "content/public/browser/dedicated_worker_service.h" #include "url/gurl.h"
diff --git a/content/browser/worker_host/shared_worker_service_impl.h b/content/browser/worker_host/shared_worker_service_impl.h index 4de179a..f2416b9 100644 --- a/content/browser/worker_host/shared_worker_service_impl.h +++ b/content/browser/worker_host/shared_worker_service_impl.h
@@ -16,6 +16,7 @@ #include "base/observer_list.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/worker_host/shared_worker_host.h" +#include "content/common/content_export.h" #include "content/public/browser/global_routing_id.h" #include "content/public/browser/shared_worker_service.h" #include "mojo/public/cpp/bindings/pending_remote.h"
diff --git a/content/browser/worker_host/worker_script_fetcher.h b/content/browser/worker_host/worker_script_fetcher.h index e7358fb..14c5d8b 100644 --- a/content/browser/worker_host/worker_script_fetcher.h +++ b/content/browser/worker_host/worker_script_fetcher.h
@@ -7,6 +7,7 @@ #include "base/callback.h" #include "content/browser/navigation_subresource_loader_params.h" +#include "content/common/content_export.h" #include "content/public/browser/service_worker_client_info.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h"
diff --git a/content/browser/worker_host/worker_script_loader_factory.h b/content/browser/worker_host/worker_script_loader_factory.h index 2432f70..abb9cb4 100644 --- a/content/browser/worker_host/worker_script_loader_factory.h +++ b/content/browser/worker_host/worker_script_loader_factory.h
@@ -7,6 +7,7 @@ #include "base/memory/weak_ptr.h" #include "content/browser/navigation_subresource_loader_params.h" +#include "content/common/content_export.h" #include "content/public/browser/service_worker_client_info.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h"
diff --git a/content/common/child_process_host_impl.h b/content/common/child_process_host_impl.h index e4f8dd0..c4a6345 100644 --- a/content/common/child_process_host_impl.h +++ b/content/common/child_process_host_impl.h
@@ -16,6 +16,7 @@ #include "base/process/process.h" #include "build/build_config.h" #include "content/common/child_process.mojom.h" +#include "content/common/content_export.h" #include "content/public/common/child_process_host.h" #include "ipc/ipc_listener.h" #include "mojo/public/cpp/bindings/receiver.h"
diff --git a/content/common/content_param_traits.h b/content/common/content_param_traits.h index cf4ec5fa..8a060a3 100644 --- a/content/common/content_param_traits.h +++ b/content/common/content_param_traits.h
@@ -16,6 +16,7 @@ #include "base/memory/ref_counted.h" #include "cc/ipc/cc_param_traits_macros.h" +#include "content/common/content_export.h" #include "content/common/content_param_traits_macros.h" #include "ipc/ipc_mojo_param_traits.h" #include "ui/accessibility/ax_mode.h"
diff --git a/content/common/input/actions_parser.h b/content/common/input/actions_parser.h index d7a907e..bac53918 100644 --- a/content/common/input/actions_parser.h +++ b/content/common/input/actions_parser.h
@@ -10,6 +10,7 @@ #include <string> #include "base/values.h" +#include "content/common/content_export.h" #include "content/common/input/synthetic_pointer_action_list_params.h" namespace content {
diff --git a/content/common/input/input_injector_mojom_traits.h b/content/common/input/input_injector_mojom_traits.h index 80beb3e..f4dbb34 100644 --- a/content/common/input/input_injector_mojom_traits.h +++ b/content/common/input/input_injector_mojom_traits.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_COMMON_INPUT_INPUT_INJECTOR_MOJOM_TRAITS_H_ #define CONTENT_COMMON_INPUT_INPUT_INJECTOR_MOJOM_TRAITS_H_ +#include "content/common/content_export.h" #include "content/common/input/input_injector.mojom.h" #include "content/common/input/synthetic_pinch_gesture_params.h" #include "content/common/input/synthetic_pointer_action_list_params.h"
diff --git a/content/common/state_transitions.h b/content/common/state_transitions.h index b3bf0ff..25c16c4 100644 --- a/content/common/state_transitions.h +++ b/content/common/state_transitions.h
@@ -10,6 +10,7 @@ #include "base/check_op.h" #include "base/containers/contains.h" #include "base/no_destructor.h" +#include "content/common/content_export.h" namespace content {
diff --git a/content/common/user_agent.cc b/content/common/user_agent.cc index c5884656..2fd614f 100644 --- a/content/common/user_agent.cc +++ b/content/common/user_agent.cc
@@ -12,7 +12,6 @@ #include "base/strings/stringprintf.h" #include "base/system/sys_info.h" #include "build/build_config.h" -#include "build/chromeos_buildflags.h" #include "build/util/chromium_git_revision.h" #if defined(OS_MAC) @@ -163,8 +162,7 @@ std::string GetOSVersion(IncludeAndroidBuildNumber include_android_build_number, IncludeAndroidModel include_android_model) { std::string os_version; -#if defined(OS_WIN) || defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) || \ - BUILDFLAG(IS_CHROMEOS_LACROS) +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_CHROMEOS) int32_t os_major_version = 0; int32_t os_minor_version = 0; int32_t os_bugfix_version = 0;
diff --git a/content/common/zygote/zygote_handle_impl_linux.h b/content/common/zygote/zygote_handle_impl_linux.h index 6a53082..49cc5146c 100644 --- a/content/common/zygote/zygote_handle_impl_linux.h +++ b/content/common/zygote/zygote_handle_impl_linux.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_COMMON_ZYGOTE_ZYGOTE_HANDLE_IMPL_LINUX_H_ #define CONTENT_COMMON_ZYGOTE_ZYGOTE_HANDLE_IMPL_LINUX_H_ +#include "content/common/content_export.h" #include "content/public/common/zygote/zygote_handle.h" namespace content {
diff --git a/content/public/DEPS b/content/public/DEPS index 0e0a300..0b410fa 100644 --- a/content/public/DEPS +++ b/content/public/DEPS
@@ -5,10 +5,12 @@ "+services/network/public/mojom", "+services/service_manager/public", + # All code in content/public can use these headers. + "+content/public/common", + "+content/public/android/content_jni_headers", + # This file does not belong in content/public as it should not be # included directly by embedders of content/. It must however be # available to code in content/public. "+content/common/content_export.h", - "+content/public/common", - "+content/public/android/content_jni_headers", ]
diff --git a/content/public/browser/background_sync_context.h b/content/public/browser/background_sync_context.h index 67dcf3ab..07605f94 100644 --- a/content/public/browser/background_sync_context.h +++ b/content/public/browser/background_sync_context.h
@@ -7,6 +7,7 @@ #include "base/callback_forward.h" #include "build/build_config.h" +#include "content/common/content_export.h" #include "third_party/blink/public/mojom/background_sync/background_sync.mojom.h" #include "url/origin.h"
diff --git a/content/public/browser/client_hints.h b/content/public/browser/client_hints.h index 1bda108..7517325 100644 --- a/content/public/browser/client_hints.h +++ b/content/public/browser/client_hints.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_PUBLIC_BROWSER_CLIENT_HINTS_H_ #define CONTENT_PUBLIC_BROWSER_CLIENT_HINTS_H_ +#include "content/common/content_export.h" #include "content/public/browser/client_hints_controller_delegate.h" #include "net/http/http_request_headers.h" #include "services/network/public/mojom/parsed_headers.mojom-forward.h"
diff --git a/content/public/browser/mhtml_extra_parts.h b/content/public/browser/mhtml_extra_parts.h index 5ec8945..527331f44 100644 --- a/content/public/browser/mhtml_extra_parts.h +++ b/content/public/browser/mhtml_extra_parts.h
@@ -6,6 +6,7 @@ #define CONTENT_PUBLIC_BROWSER_MHTML_EXTRA_PARTS_H_ #include "base/supports_user_data.h" +#include "content/common/content_export.h" #include "content/public/browser/web_contents.h" namespace content {
diff --git a/content/public/browser/navigation_type.h b/content/public/browser/navigation_type.h index 8c1f362..0572c48 100644 --- a/content/public/browser/navigation_type.h +++ b/content/public/browser/navigation_type.h
@@ -17,14 +17,14 @@ // A new entry was navigated to in the main frame. This covers all cases where // the main frame navigated and a new navigation entry was created. This means // cases like navigations to a hash on the same document or history.pushState - // are NEW_ENTRY, except when it results in replacement (see comment for - // NAVIGATION_TYPE_EXISTING_ENTRY below). + // are MAIN_FRAME_NEW_ENTRY, except when it results in replacement (see + // comment for NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY below). // This type of navigation will create a new NavigationEntry, without sharing // any (frame-specific) session history entries with other NavigationEntries. // Navigation entries created by subframe navigations are NEW_SUBFRAME. // Note: This includes all main frames (e.g. fenced frames), not only the // navigation entries created by navigations in primary main frames. - NAVIGATION_TYPE_NEW_ENTRY, + NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, // Navigating the main frame to an existing navigation entry. This is the case // for: @@ -36,10 +36,10 @@ // same-document navigations on a document with a trivial session history // entry requirement (e.g. prerender). Note that for normal non-replacement // cases, same-document navigations on the main frame will be - // classified as NAVIGATION_TYPE_NEW_ENTRY. + // classified as NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY. // TODO(https://crbug.com/1226489): Classify same-document replacements (or - // at least location.replace()) as NAVIGATION_TYPE_NEW_ENTRY, like - // cross-document replacements and normal same-document navigations. + // at least location.replace()) as NAVIGATION_TYPE_MAIN_FRAME_NEW_ENTRY, + // like cross-document replacements and normal same-document navigations. // // This type of navigation will reuse the existing NavigationEntry but modify // most/all of the contents of the existing NavigationEntry. This means the @@ -50,7 +50,7 @@ // TODO(https://crbug.com/1226489): Do not reuse the session history entry // for the frame (and maybe the NavigationEntry itself) for same-document // location.replace(). - NAVIGATION_TYPE_EXISTING_ENTRY, + NAVIGATION_TYPE_MAIN_FRAME_EXISTING_ENTRY, // A new subframe was manually navigated by the user. We will create a new // NavigationEntry so they can go back to the previous subframe content
diff --git a/content/public/browser/provision_fetcher_impl.h b/content/public/browser/provision_fetcher_impl.h index 0b17be8e..c697689 100644 --- a/content/public/browser/provision_fetcher_impl.h +++ b/content/public/browser/provision_fetcher_impl.h
@@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" #include "content/public/browser/provision_fetcher_factory.h" #include "media/base/provision_fetcher.h" #include "media/mojo/mojom/provision_fetcher.mojom.h"
diff --git a/content/public/browser/site_instance.h b/content/public/browser/site_instance.h index 73a3f884..84d2c20 100644 --- a/content/public/browser/site_instance.h +++ b/content/public/browser/site_instance.h
@@ -188,6 +188,15 @@ // Write a representation of this object into a trace. virtual void WriteIntoTrace(perfetto::TracedValue context) = 0; + // Estimates the overhead in terms of process count due to OriginAgentCluster + // (OAC) SiteInstances in the BrowsingInstance related to this SiteInstance. + // The estimate is based on counting SiteInstances where OAC is on, and + // subtracting from it the count of SiteInstances that would exist without + // OAC. If we assume that we don't coalesce SiteInstances from different + // BrowsingInstances into a single RenderProcess, this roughly corresponds to + // the number of renderer processes engendered by OAC. + virtual int EstimateOriginAgentClusterOverheadForMetrics() = 0; + // Factory method to create a new SiteInstance. This will create a new // BrowsingInstance, so it should only be used when creating a new tab from // scratch (or similar circumstances).
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index b5c602b..bd1c84f 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -9,6 +9,7 @@ #define CONTENT_PUBLIC_COMMON_COMMON_PARAM_TRAITS_MACROS_H_ #include "build/build_config.h" +#include "content/common/content_export.h" #include "content/public/common/drop_data.h" #include "content/public/common/referrer.h" #include "content/public/common/webplugininfo_param_traits.h"
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 6e53659c..ff8ffd22 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -1199,8 +1199,7 @@ // On ChromeOS the service must run in the browser process, because parts of the // code depend on global objects that are only available in the Browser process. // See https://crbug.com/891961. -#if defined(OS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) || \ - BUILDFLAG(IS_CHROMEOS_LACROS) +#if defined(OS_ANDROID) || defined(OS_CHROMEOS) return VideoCaptureServiceConfiguration::kEnabledForBrowserProcess; #else #if defined(OS_WIN)
diff --git a/content/public/common/webplugininfo_param_traits.h b/content/public/common/webplugininfo_param_traits.h index 85ebcee..f9a116e 100644 --- a/content/public/common/webplugininfo_param_traits.h +++ b/content/public/common/webplugininfo_param_traits.h
@@ -4,6 +4,7 @@ // no-include-guard-because-multiply-included +#include "content/common/content_export.h" #include "content/public/common/webplugininfo.h" #include "ipc/ipc_message_macros.h"
diff --git a/content/public/gpu/content_gpu_client.h b/content/public/gpu/content_gpu_client.h index cb7774f..04274b7 100644 --- a/content/public/gpu/content_gpu_client.h +++ b/content/public/gpu/content_gpu_client.h
@@ -7,6 +7,7 @@ #include "base/metrics/field_trial.h" #include "base/task/single_thread_task_runner.h" +#include "content/common/content_export.h" #include "content/public/common/content_client.h" #include "mojo/public/cpp/bindings/binder_map.h"
diff --git a/content/public/renderer/content_renderer_client.h b/content/public/renderer/content_renderer_client.h index 0b09803..4352aad 100644 --- a/content/public/renderer/content_renderer_client.h +++ b/content/public/renderer/content_renderer_client.h
@@ -17,6 +17,7 @@ #include "base/memory/ref_counted.h" #include "base/task/thread_pool/thread_pool_instance.h" #include "build/build_config.h" +#include "content/common/content_export.h" #include "content/public/common/content_client.h" #include "media/base/audio_parameters.h" #include "media/base/supported_types.h"
diff --git a/content/public/renderer/video_encode_accelerator.cc b/content/public/renderer/video_encode_accelerator.cc index 1b5188d0..9d99c7e 100644 --- a/content/public/renderer/video_encode_accelerator.cc +++ b/content/public/renderer/video_encode_accelerator.cc
@@ -17,7 +17,7 @@ media::GpuVideoAcceleratorFactories* gpu_factories = RenderThreadImpl::current()->GetGpuFactories(); - if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) { + if (!gpu_factories || !gpu_factories->IsGpuVideoEncodeAcceleratorEnabled()) { std::move(callback).Run(nullptr, std::unique_ptr<media::VideoEncodeAccelerator>()); return; @@ -42,7 +42,7 @@ #else media::GpuVideoAcceleratorFactories* gpu_factories = RenderThreadImpl::current()->GetGpuFactories(); - if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) + if (!gpu_factories || !gpu_factories->IsGpuVideoEncodeAcceleratorEnabled()) return media::VideoEncodeAccelerator::SupportedProfiles(); return gpu_factories->GetVideoEncodeAcceleratorSupportedProfiles().value_or( media::VideoEncodeAccelerator::SupportedProfiles());
diff --git a/content/public/test/DEPS b/content/public/test/DEPS index 61ac36e..d601abe 100644 --- a/content/public/test/DEPS +++ b/content/public/test/DEPS
@@ -8,7 +8,14 @@ "+chromeos/lacros/lacros_test_helper.h", "+chromeos/startup/startup_switches.h", + # Tests can use all content/public headers. "+content/public", + + # This file does not belong in content/public as it should not be + # included directly by embedders of content/. It must however be + # available to code in content/public. + "+content/common/content_export.h", + "+components/discardable_memory/service", "+components/download/public/common", "+components/enterprise/common/download_item_reroute_info.h",
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index bebd44e4..5216c98 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -1905,6 +1905,13 @@ return rfh->frame_tree_node()->child_at(index)->current_frame_host(); } +bool HasOriginKeyedProcess(RenderFrameHost* frame) { + return static_cast<RenderFrameHostImpl*>(frame) + ->GetSiteInstance() + ->GetSiteInfo() + .requires_origin_keyed_process(); +} + std::vector<RenderFrameHost*> CollectAllRenderFrameHosts( RenderFrameHost* starting_rfh) { std::vector<RenderFrameHost*> visited_frames;
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index d881384..ffdbed5 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -894,6 +894,10 @@ // RenderFrameHost. Returns nullptr if such child frame does not exist. RenderFrameHost* ChildFrameAt(const ToRenderFrameHost& adapter, size_t index); +// Returns true if |frame| has origin-keyed process isolation due to the +// OriginAgentCluster header. +bool HasOriginKeyedProcess(RenderFrameHost* frame); + // Returns the frames visited by |RenderFrameHost::ForEachRenderFrameHost| in // the same order. std::vector<RenderFrameHost*> CollectAllRenderFrameHosts(
diff --git a/content/public/test/fake_local_frame.cc b/content/public/test/fake_local_frame.cc index 821ed5b..f22da3ff 100644 --- a/content/public/test/fake_local_frame.cc +++ b/content/public/test/fake_local_frame.cc
@@ -27,6 +27,10 @@ base::Unretained(this))); } +void FakeLocalFrame::FlushMessages() { + receiver_.FlushForTesting(); +} + void FakeLocalFrame::GetTextSurroundingSelection( uint32_t max_length, GetTextSurroundingSelectionCallback callback) {
diff --git a/content/public/test/fake_local_frame.h b/content/public/test/fake_local_frame.h index f4d06943..a3b4aa2 100644 --- a/content/public/test/fake_local_frame.h +++ b/content/public/test/fake_local_frame.h
@@ -34,6 +34,9 @@ void Init(blink::AssociatedInterfaceProvider* provider); + // Flushes mojo messages on `receiver_`. + void FlushMessages(); + // blink::mojom::LocalFrame: void GetTextSurroundingSelection( uint32_t max_length,
diff --git a/content/public/test/test_synchronous_compositor_android.h b/content/public/test/test_synchronous_compositor_android.h index 78962a1..bae8d568 100644 --- a/content/public/test/test_synchronous_compositor_android.h +++ b/content/public/test/test_synchronous_compositor_android.h
@@ -11,6 +11,7 @@ #include <vector> #include "components/viz/common/surfaces/frame_sink_id.h" +#include "content/common/content_export.h" #include "content/public/browser/android/synchronous_compositor.h" #include "content/public/browser/android/synchronous_compositor_client.h"
diff --git a/content/public/utility/content_utility_client.h b/content/public/utility/content_utility_client.h index d47a823..1f3ed83 100644 --- a/content/public/utility/content_utility_client.h +++ b/content/public/utility/content_utility_client.h
@@ -8,6 +8,7 @@ #include <map> #include <memory> +#include "content/common/content_export.h" #include "content/public/common/content_client.h" #include "mojo/public/cpp/bindings/binder_map.h" #include "mojo/public/cpp/bindings/generic_pending_receiver.h"
diff --git a/content/public/utility/utility_thread.h b/content/public/utility/utility_thread.h index 1850b440..47ebc06 100644 --- a/content/public/utility/utility_thread.h +++ b/content/public/utility/utility_thread.h
@@ -6,6 +6,7 @@ #define CONTENT_PUBLIC_UTILITY_UTILITY_THREAD_H_ #include "build/build_config.h" +#include "content/common/content_export.h" #include "content/public/child/child_thread.h" namespace content {
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc index 42451dd..434e59217 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -82,7 +82,8 @@ const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider, bool enable_video_gpu_memory_buffers, bool enable_media_stream_gpu_memory_buffers, - bool enable_video_accelerator, + bool enable_video_decode_accelerator, + bool enable_video_encode_accelerator, mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory_remote, mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> @@ -92,8 +93,9 @@ return base::WrapUnique(new GpuVideoAcceleratorFactoriesImpl( std::move(gpu_channel_host), main_thread_task_runner, task_runner, context_provider, enable_video_gpu_memory_buffers, - enable_media_stream_gpu_memory_buffers, enable_video_accelerator, - std::move(interface_factory_remote), std::move(vea_provider_remote))); + enable_media_stream_gpu_memory_buffers, enable_video_decode_accelerator, + enable_video_encode_accelerator, std::move(interface_factory_remote), + std::move(vea_provider_remote))); } GpuVideoAcceleratorFactoriesImpl::GpuVideoAcceleratorFactoriesImpl( @@ -103,7 +105,8 @@ const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider, bool enable_video_gpu_memory_buffers, bool enable_media_stream_gpu_memory_buffers, - bool enable_video_accelerator, + bool enable_video_decode_accelerator, + bool enable_video_encode_accelerator, mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory_remote, mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> @@ -115,7 +118,8 @@ enable_video_gpu_memory_buffers_(enable_video_gpu_memory_buffers), enable_media_stream_gpu_memory_buffers_( enable_media_stream_gpu_memory_buffers), - video_accelerator_enabled_(enable_video_accelerator), + video_decode_accelerator_enabled_(enable_video_decode_accelerator), + video_encode_accelerator_enabled_(enable_video_encode_accelerator), gpu_memory_buffer_manager_( RenderThreadImpl::current()->GetGpuMemoryBufferManager()) { DCHECK(main_thread_task_runner_); @@ -157,7 +161,7 @@ base::BindOnce(&GpuVideoAcceleratorFactoriesImpl::OnChannelTokenReady, base::Unretained(this))); - if (video_accelerator_enabled_) { + if (video_encode_accelerator_enabled_) { { // TODO(crbug.com/709631): This should be removed. base::AutoLock lock(supported_profiles_lock_); @@ -280,8 +284,11 @@ ContextProviderPhase::CONTEXT_PROVIDER_RELEASED); } -bool GpuVideoAcceleratorFactoriesImpl::IsGpuVideoAcceleratorEnabled() { - return video_accelerator_enabled_; +bool GpuVideoAcceleratorFactoriesImpl::IsGpuVideoDecodeAcceleratorEnabled() { + return video_decode_accelerator_enabled_; +} +bool GpuVideoAcceleratorFactoriesImpl::IsGpuVideoEncodeAcceleratorEnabled() { + return video_encode_accelerator_enabled_; } void GpuVideoAcceleratorFactoriesImpl::GetChannelToken( @@ -350,7 +357,7 @@ GpuVideoAcceleratorFactoriesImpl::CreateVideoDecoder( media::MediaLog* media_log, media::RequestOverlayInfoCB request_overlay_info_cb) { - DCHECK(video_accelerator_enabled_); + DCHECK(video_decode_accelerator_enabled_); DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(interface_factory_.is_bound()); @@ -371,7 +378,7 @@ std::unique_ptr<media::VideoEncodeAccelerator> GpuVideoAcceleratorFactoriesImpl::CreateVideoEncodeAccelerator() { - DCHECK(video_accelerator_enabled_); + DCHECK(video_encode_accelerator_enabled_); DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(vea_provider_.is_bound()); if (CheckContextLost())
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h index b89f278..6b02c4b8 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h
@@ -67,14 +67,16 @@ const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider, bool enable_video_gpu_memory_buffers, bool enable_media_stream_gpu_memory_buffers, - bool enable_video_accelerator, + bool enable_video_decode_accelerator, + bool enable_video_encode_accelerator, mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory_remote, mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> vea_provider_remote); // media::GpuVideoAcceleratorFactories implementation. - bool IsGpuVideoAcceleratorEnabled() override; + bool IsGpuVideoDecodeAcceleratorEnabled() override; + bool IsGpuVideoEncodeAcceleratorEnabled() override; void GetChannelToken( gpu::mojom::GpuChannel::GetChannelTokenCallback cb) override; int32_t GetCommandBufferRouteId() override; @@ -160,7 +162,8 @@ const scoped_refptr<viz::ContextProviderCommandBuffer>& context_provider, bool enable_gpu_memory_buffer_video_frames_for_video, bool enable_gpu_memory_buffer_video_frames_for_media_stream, - bool enable_video_accelerator, + bool enable_video_decode_accelerator, + bool enable_video_encode_accelerator, mojo::PendingRemote<media::mojom::InterfaceFactory> interface_factory_remote, mojo::PendingRemote<media::mojom::VideoEncodeAcceleratorProvider> @@ -209,7 +212,8 @@ const bool enable_video_gpu_memory_buffers_; const bool enable_media_stream_gpu_memory_buffers_; // Whether video acceleration encoding/decoding should be enabled. - const bool video_accelerator_enabled_; + const bool video_decode_accelerator_enabled_; + const bool video_encode_accelerator_enabled_; gfx::ColorSpace rendering_color_space_;
diff --git a/content/renderer/media/inspector_media_event_handler.h b/content/renderer/media/inspector_media_event_handler.h index 325e890..121398b 100644 --- a/content/renderer/media/inspector_media_event_handler.h +++ b/content/renderer/media/inspector_media_event_handler.h
@@ -7,6 +7,7 @@ #include <vector> +#include "content/common/content_export.h" #include "content/renderer/media/batching_media_log.h" #include "third_party/blink/public/web/web_media_inspector.h"
diff --git a/content/renderer/media/media_factory.cc b/content/renderer/media/media_factory.cc index efc42b5..2914818 100644 --- a/content/renderer/media/media_factory.cc +++ b/content/renderer/media/media_factory.cc
@@ -46,13 +46,11 @@ #include "media/renderers/default_renderer_factory.h" #include "media/video/gpu_video_accelerator_factories.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "services/device/public/mojom/battery_monitor.mojom.h" #include "services/service_manager/public/cpp/connect.h" #include "services/viz/public/cpp/gpu/context_provider_command_buffer.h" #include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/media/key_system_config_selector.h" -#include "third_party/blink/public/platform/media/power_status_helper.h" #include "third_party/blink/public/platform/media/remote_playback_client_wrapper_impl.h" #include "third_party/blink/public/platform/media/resource_fetch_context.h" #include "third_party/blink/public/platform/media/url_index.h" @@ -480,26 +478,6 @@ interface_broker_->GetInterface( metrics_provider.InitWithNewPipeAndPassReceiver()); - std::unique_ptr<blink::PowerStatusHelper> power_status_helper; - if (base::FeatureList::IsEnabled(media::kMediaPowerExperiment)) { - // The battery monitor is only available through the blink provider. - // TODO(liberato): Should we expose this via |remote_interfaces_|? - scoped_refptr<blink::ThreadSafeBrowserInterfaceBrokerProxy> - remote_interfaces = - blink::Platform::Current()->GetBrowserInterfaceBroker(); - auto battery_monitor_cb = base::BindRepeating( - [](scoped_refptr<blink::ThreadSafeBrowserInterfaceBrokerProxy> - remote_interfaces) { - mojo::PendingRemote<device::mojom::BatteryMonitor> battery_monitor; - remote_interfaces->GetInterface( - battery_monitor.InitWithNewPipeAndPassReceiver()); - return battery_monitor; - }, - remote_interfaces); - power_status_helper = std::make_unique<blink::PowerStatusHelper>( - std::move(battery_monitor_cb)); - } - scoped_refptr<base::SingleThreadTaskRunner> video_frame_compositor_task_runner; const auto surface_layer_mode = GetSurfaceLayerMode(MediaPlayerType::kNormal); @@ -543,8 +521,7 @@ render_frame_->GetRenderFrameMediaPlaybackOptions() .is_background_video_track_optimization_supported, GetContentClient()->renderer()->OverrideDemuxerForUrl(render_frame_, url, - media_task_runner), - std::move(power_status_helper)); + media_task_runner)); auto vfc = std::make_unique<blink::VideoFrameCompositor>( params->video_frame_compositor_task_runner(), std::move(submitter)); @@ -552,6 +529,7 @@ auto* media_player = new blink::WebMediaPlayerImpl( web_frame, client, encrypted_client, delegate, std::move(factory_selector), url_index_.get(), std::move(vfc), + blink::Platform::Current()->GetBrowserInterfaceBroker(), std::move(params)); return media_player;
diff --git a/content/renderer/media/render_media_event_handler.h b/content/renderer/media/render_media_event_handler.h index e92a6ac14..3077c62 100644 --- a/content/renderer/media/render_media_event_handler.h +++ b/content/renderer/media/render_media_event_handler.h
@@ -7,6 +7,7 @@ #include <vector> +#include "content/common/content_export.h" #include "content/common/media/media_log_records.mojom.h" #include "content/renderer/media/batching_media_log.h" #include "mojo/public/cpp/bindings/remote.h"
diff --git a/content/renderer/navigation_state.h b/content/renderer/navigation_state.h index 5794a52a..f1661d94 100644 --- a/content/renderer/navigation_state.h +++ b/content/renderer/navigation_state.h
@@ -7,6 +7,7 @@ #include <memory> +#include "content/common/content_export.h" #include "content/common/frame.mojom.h" #include "content/renderer/navigation_client.h" #include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h"
diff --git a/content/renderer/pepper/renderer_ppapi_host_impl.h b/content/renderer/pepper/renderer_ppapi_host_impl.h index 0a8f5ed..b88583e 100644 --- a/content/renderer/pepper/renderer_ppapi_host_impl.h +++ b/content/renderer/pepper/renderer_ppapi_host_impl.h
@@ -7,6 +7,7 @@ #include <memory> +#include "content/common/content_export.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "content/renderer/pepper/content_renderer_pepper_host_factory.h" #include "ppapi/host/ppapi_host.h"
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index ed716709..038b9c0 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -31,6 +31,7 @@ #include "build/build_config.h" #include "cc/input/browser_controls_state.h" #include "content/common/buildflags.h" +#include "content/common/content_export.h" #include "content/common/download/mhtml_file_writer.mojom.h" #include "content/common/frame.mojom.h" #include "content/common/navigation_client.mojom.h"
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 73b8a8e..45fc702 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -1060,7 +1060,7 @@ viz::command_buffer_metrics::ContextType::MEDIA, kGpuStreamIdMedia, kGpuStreamPriorityMedia); - const bool enable_video_accelerator = + const bool enable_video_decode_accelerator = #if defined(OS_LINUX) base::FeatureList::IsEnabled(media::kVaapiVideoDecodeLinux) && @@ -1070,6 +1070,18 @@ (gpu_channel_host->gpu_feature_info() .status_values[gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] == gpu::kGpuFeatureStatusEnabled); + + const bool enable_video_encode_accelerator = + +#if defined(OS_LINUX) + base::FeatureList::IsEnabled(media::kVaapiVideoEncodeLinux) && +#else + !cmd_line->HasSwitch(switches::kDisableAcceleratedVideoEncode) && +#endif // defined(OS_LINUX) + (gpu_channel_host->gpu_feature_info() + .status_values[gpu::GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE] == + gpu::kGpuFeatureStatusEnabled); + const bool enable_gpu_memory_buffers = !is_gpu_compositing_disabled_ && #if !defined(OS_ANDROID) @@ -1102,8 +1114,8 @@ std::move(gpu_channel_host), base::ThreadTaskRunnerHandle::Get(), GetMediaThreadTaskRunner(), std::move(media_context_provider), enable_video_gpu_memory_buffers, enable_media_stream_gpu_memory_buffers, - enable_video_accelerator, std::move(interface_factory), - std::move(vea_provider))); + enable_video_decode_accelerator, enable_video_encode_accelerator, + std::move(interface_factory), std::move(vea_provider))); gpu_factories_.back()->SetRenderingColorSpace(rendering_color_space_); return gpu_factories_.back().get(); }
diff --git a/content/shell/browser/shell_permission_manager.cc b/content/shell/browser/shell_permission_manager.cc index 188423a..88788ed3 100644 --- a/content/shell/browser/shell_permission_manager.cc +++ b/content/shell/browser/shell_permission_manager.cc
@@ -38,6 +38,9 @@ // Storage Access API web platform tests require permission to be granted by // default. case PermissionType::STORAGE_ACCESS_GRANT: + + // WebNFC browser tests require permission to be granted by default. + case PermissionType::NFC: return true; case PermissionType::MIDI_SYSEX: @@ -50,7 +53,6 @@ case PermissionType::CLIPBOARD_SANITIZED_WRITE: case PermissionType::NUM: case PermissionType::WAKE_LOCK_SYSTEM: - case PermissionType::NFC: case PermissionType::VR: case PermissionType::AR: case PermissionType::CAMERA_PAN_TILT_ZOOM:
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 72a1d604..3348164d 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1625,6 +1625,7 @@ } sources += [ "../browser/accessibility/android_granularity_movement_browsertest.cc", + "../browser/android/nfc_host_browsertest.cc", "../browser/android/render_widget_host_connector_browsertest.cc", "../browser/android/render_widget_host_connector_browsertest.h", "../browser/android/synchronous_compositor_browsertest.cc", @@ -1944,6 +1945,7 @@ "../browser/browsing_data/browsing_data_remover_impl_unittest.cc", "../browser/browsing_data/clear_site_data_handler_unittest.cc", "../browser/browsing_data/same_site_data_remover_impl_unittest.cc", + "../browser/buckets/bucket_manager_host_unittest.cc", "../browser/byte_stream_unittest.cc", "../browser/cache_storage/cache_storage_blob_to_disk_cache_unittest.cc", "../browser/cache_storage/cache_storage_cache_unittest.cc",
diff --git a/content/test/gpu/flake_suppressor/__init__.py b/content/test/gpu/flake_suppressor/__init__.py index 5300841..b3cd8a3 100644 --- a/content/test/gpu/flake_suppressor/__init__.py +++ b/content/test/gpu/flake_suppressor/__init__.py
@@ -8,6 +8,7 @@ from gpu_tests import path_util path_util.SetupTypPath() +path_util.SetupTelemetryPaths() CHROMIUM_SRC_DIR = os.path.realpath( os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))
diff --git a/content/test/gpu/flake_suppressor/expectations.py b/content/test/gpu/flake_suppressor/expectations.py index ae14029..bc959c6 100644 --- a/content/test/gpu/flake_suppressor/expectations.py +++ b/content/test/gpu/flake_suppressor/expectations.py
@@ -4,8 +4,10 @@ """Module for interacting with expectation files.""" import base64 +import collections import os import posixpath +import re import six @@ -15,6 +17,7 @@ import urllib.request import flake_suppressor +from flake_suppressor import tag_utils from typ import expectations_parser @@ -34,8 +37,10 @@ GITILES_URL = 'https://chromium.googlesource.com/chromium/src/+/refs/heads/main' TEXT_FORMAT_ARG = '?format=TEXT' +TAG_GROUP_REGEX = re.compile(r'# tags: \[([^\]]*)\]', re.MULTILINE | re.DOTALL) -def IterateThroughResultsForUser(result_map, group_by_tags): + +def IterateThroughResultsForUser(result_map, group_by_tags, include_all_tags): """Iterates over |result_map| for the user to provide input. For each unique result, user will be able to decide whether to ignore it (do @@ -50,6 +55,8 @@ by tags or not. If True, expectations will be added after an existing expectation whose tags are the largest subset of the produced tags. If False, new expectations will be appended to the end of the file. + include_all_tags: A boolean denoting whether all tags should be used for + expectations or only the most specific ones. """ typ_tag_ordered_result_map = _ReorderMapByTypTags(result_map) for suite, test_map in result_map.items(): @@ -81,12 +88,12 @@ continue ModifyFileForResult(suite, test, typ_tags, bug, expected_result, - group_by_tags) + group_by_tags, include_all_tags) def IterateThroughResultsWithThresholds(result_map, group_by_tags, result_counts, ignore_threshold, - flaky_threshold): + flaky_threshold, include_all_tags): """Iterates over |result_map| and generates expectations based off thresholds. Args: @@ -102,6 +109,8 @@ flaky_threshold: A float containing the fraction of failed tests under which failures will be suppressed with RetryOnFailure and above which will be suppressed with Failure. + include_all_tags: A boolean denoting whether all tags should be used for + expectations or only the most specific ones. """ assert isinstance(ignore_threshold, float) assert isinstance(flaky_threshold, float) @@ -118,7 +127,7 @@ else: expected_result = 'Failure' ModifyFileForResult(suite, test, typ_tags, '', expected_result, - group_by_tags) + group_by_tags, include_all_tags) def FindFailuresInSameTest(result_map, target_suite, target_test, @@ -239,7 +248,7 @@ def ModifyFileForResult(suite, test, typ_tags, bug, expected_result, - group_by_tags): + group_by_tags, include_all_tags): """Adds an expectation to the appropriate expectation file. Args: @@ -253,8 +262,16 @@ by tags or not. If True, expectations will be added after an existing expectation whose tags are the largest subset of the produced tags. If False, new expectations will be appended to the end of the file. + include_all_tags: A boolean denoting whether all tags should be used for + expectations or only the most specific ones. """ expectation_file = GetExpectationFileForSuite(suite, typ_tags) + if not include_all_tags: + # Remove temporarily un-ignored tags, namely webgl-version-x tags, since + # those were necessary to find the correct file. However, we do not want + # to actually include them in the file since they are unused/ignored. + typ_tags = tag_utils.RemoveTemporarilyKeptIgnoredTags(typ_tags) + typ_tags = FilterToMostSpecificTypTags(typ_tags, expectation_file) bug = '%s ' % bug if bug else bug def AppendExpectationToEnd(): @@ -269,12 +286,17 @@ if insertion_line == -1: AppendExpectationToEnd() else: + # If we've already filtered tags, then use those instead of the "best + # matching" ones. + tags_to_use = best_matching_tags + if not include_all_tags: + tags_to_use = typ_tags # enumerate starts at 0 but line numbers start at 1. insertion_line -= 1 - best_matching_tags = list(best_matching_tags) - best_matching_tags.sort() - expectation_line = '%s[ %s ] %s [ %s ]\n' % ( - bug, ' '.join(best_matching_tags), test, expected_result) + tags_to_use = list(tags_to_use) + tags_to_use.sort() + expectation_line = '%s[ %s ] %s [ %s ]\n' % (bug, ' '.join(tags_to_use), + test, expected_result) with open(expectation_file) as infile: input_contents = infile.read() output_contents = '' @@ -288,6 +310,61 @@ AppendExpectationToEnd() +def FilterToMostSpecificTypTags(typ_tags, expectation_file): + """Filters |typ_tags| to the most specific set. + + Assumes that the tags in |expectation_file| are ordered from least specific + to most specific within each tag group. + + Args: + typ_tags: A list of strings containing the typ tags the test produced. + expectation_file: A string containing a filepath pointing to the + expectation file to filter tags with. + + Returns: + A list containing the contents of |typ_tags| with only the most specific + tag from each tag group remaining. + """ + with open(expectation_file) as infile: + contents = infile.read() + + tag_groups = [] + for match in TAG_GROUP_REGEX.findall(contents): + tag_groups.append(match.strip().replace('#', '').split()) + + num_matches = 0 + tags_in_same_group = collections.defaultdict(list) + for tag in typ_tags: + for index, tag_group in enumerate(tag_groups): + if tag in tag_group: + tags_in_same_group[index].append(tag) + num_matches += 1 + break + if num_matches != len(typ_tags): + all_tags = set() + for group in tag_groups: + all_tags |= set(group) + raise RuntimeError('Found tags not in expectation file: %s' % + ' '.join(set(typ_tags) - all_tags)) + + filtered_tags = [] + for index, tags in tags_in_same_group.items(): + if len(tags) == 1: + filtered_tags.append(tags[0]) + else: + tag_group = tag_groups[index] + best_index = -1 + for t in tags: + i = tag_group.index(t) + if i > best_index: + best_index = i + filtered_tags.append(tag_group[best_index]) + + # Sort to keep order consistent with what we were given. + filtered_tags.sort() + return filtered_tags + + def GetExpectationFileForSuite(suite, typ_tags): """Finds the correct expectation file for the given suite.
diff --git a/content/test/gpu/flake_suppressor/expectations_unittest.py b/content/test/gpu/flake_suppressor/expectations_unittest.py index c861457..08d5ed1c 100755 --- a/content/test/gpu/flake_suppressor/expectations_unittest.py +++ b/content/test/gpu/flake_suppressor/expectations_unittest.py
@@ -6,6 +6,7 @@ import base64 import os import sys +import tempfile import unittest import six @@ -78,7 +79,7 @@ def testIterateThroughResultsForUserIgnoreNoGroupByTags(self): """Tests that everything appears to function with ignore and no group.""" self._input_mock.return_value = (None, None) - expectations.IterateThroughResultsForUser(self.result_map, False) + expectations.IterateThroughResultsForUser(self.result_map, False, True) expected_contents = validate_tag_consistency.TAG_HEADER + """\ [ win ] some_test [ Failure ] [ mac ] some_test [ Failure ] @@ -90,7 +91,7 @@ def testIterateThroughResultsForUserIgnoreGroupByTags(self): """Tests that everything appears to function with ignore and grouping.""" self._input_mock.return_value = (None, None) - expectations.IterateThroughResultsForUser(self.result_map, True) + expectations.IterateThroughResultsForUser(self.result_map, True, True) expected_contents = validate_tag_consistency.TAG_HEADER + """\ [ win ] some_test [ Failure ] [ mac ] some_test [ Failure ] @@ -102,7 +103,7 @@ def testIterateThroughResultsForUserRetryNoGroupByTags(self): """Tests that everything appears to function with retry and no group.""" self._input_mock.return_value = ('RetryOnFailure', '') - expectations.IterateThroughResultsForUser(self.result_map, False) + expectations.IterateThroughResultsForUser(self.result_map, False, True) expected_contents = validate_tag_consistency.TAG_HEADER + """\ [ win ] some_test [ Failure ] [ mac ] some_test [ Failure ] @@ -117,7 +118,7 @@ def testIterateThroughResultsForUserRetryGroupByTags(self): """Tests that everything appears to function with retry and grouping.""" self._input_mock.return_value = ('RetryOnFailure', 'crbug.com/1') - expectations.IterateThroughResultsForUser(self.result_map, True) + expectations.IterateThroughResultsForUser(self.result_map, True, True) expected_contents = validate_tag_consistency.TAG_HEADER + """\ [ win ] some_test [ Failure ] crbug.com/1 [ win ] foo_test [ RetryOnFailure ] @@ -132,7 +133,7 @@ def testIterateThroughResultsForUserFailNoGroupByTags(self): """Tests that everything appears to function with failure and no group.""" self._input_mock.return_value = ('Failure', 'crbug.com/1') - expectations.IterateThroughResultsForUser(self.result_map, False) + expectations.IterateThroughResultsForUser(self.result_map, False, True) expected_contents = validate_tag_consistency.TAG_HEADER + """\ [ win ] some_test [ Failure ] [ mac ] some_test [ Failure ] @@ -147,7 +148,7 @@ def testIterateThroughResultsForUserFailGroupByTags(self): """Tests that everything appears to function with failure and grouping.""" self._input_mock.return_value = ('Failure', '') - expectations.IterateThroughResultsForUser(self.result_map, True) + expectations.IterateThroughResultsForUser(self.result_map, True, True) expected_contents = validate_tag_consistency.TAG_HEADER + """\ [ win ] some_test [ Failure ] [ win ] foo_test [ Failure ] @@ -159,6 +160,32 @@ with open(self.expectation_file) as infile: self.assertEqual(infile.read(), expected_contents) + def testIterateThroughResultsForUserNoIncludeAllTags(self): + """Tests that everything appears to function without including all tags""" + self.result_map = { + 'pixel_integration_test': { + 'foo_test': { + tuple(['win', 'win10']): ['a'], + tuple(['mac']): ['b'], + }, + 'bar_test': { + tuple(['win']): ['c'], + }, + }, + } + self._input_mock.return_value = ('RetryOnFailure', '') + expectations.IterateThroughResultsForUser(self.result_map, False, False) + expected_contents = validate_tag_consistency.TAG_HEADER + """\ +[ win ] some_test [ Failure ] +[ mac ] some_test [ Failure ] +[ android ] some_test [ Failure ] +[ win10 ] foo_test [ RetryOnFailure ] +[ mac ] foo_test [ RetryOnFailure ] +[ win ] bar_test [ RetryOnFailure ] +""" + with open(self.expectation_file) as infile: + self.assertEqual(infile.read(), expected_contents) + @unittest.skipIf(sys.version_info[0] != 3, 'Python 3-only') class IterateThroughResultsWithThresholdsUnittest( @@ -205,7 +232,8 @@ } } expectations.IterateThroughResultsWithThresholds(self.result_map, True, - result_counts, 0.02, 0.5) + result_counts, 0.02, 0.5, + True) expected_contents = validate_tag_consistency.TAG_HEADER + """\ [ win ] some_test [ Failure ] [ win ] bar_test [ RetryOnFailure ] @@ -231,7 +259,8 @@ } } expectations.IterateThroughResultsWithThresholds(self.result_map, False, - result_counts, 0.02, 0.5) + result_counts, 0.02, 0.5, + True) expected_contents = validate_tag_consistency.TAG_HEADER + """\ [ win ] some_test [ Failure ] [ mac ] some_test [ Failure ] @@ -242,6 +271,45 @@ with open(self.expectation_file) as infile: self.assertEqual(infile.read(), expected_contents) + def testNoIncludeAllTags(self): + """Tests that threshold-based expectations work when filtering tags.""" + self.result_map = { + 'pixel_integration_test': { + 'foo_test': { + tuple(['win', 'win10']): ['a'], + tuple(['mac']): ['b'], + }, + 'bar_test': { + tuple(['win', 'win10']): ['c'], + }, + }, + } + + result_counts = { + tuple(['win', 'win10']): { + # We expect this to be ignored since it has a 1% flake rate. + 'foo_test': 100, + # We expect this to be RetryOnFailure since it has a 25% flake rate. + 'bar_test': 4, + }, + tuple(['mac']): { + # We expect this to be Failure since it has a 50% flake rate. + 'foo_test': 2 + } + } + expectations.IterateThroughResultsWithThresholds(self.result_map, False, + result_counts, 0.02, 0.5, + False) + expected_contents = validate_tag_consistency.TAG_HEADER + """\ +[ win ] some_test [ Failure ] +[ mac ] some_test [ Failure ] +[ android ] some_test [ Failure ] +[ mac ] foo_test [ Failure ] +[ win10 ] bar_test [ RetryOnFailure ] +""" + with open(self.expectation_file) as infile: + self.assertEqual(infile.read(), expected_contents) + @unittest.skipIf(sys.version_info[0] != 3, 'Python 3-only') class FindFailuresInSameConditionUnittest(unittest.TestCase): @@ -312,7 +380,7 @@ with open(self.expectation_file, 'w') as outfile: outfile.write(expectation_file_contents) expectations.ModifyFileForResult(None, 'some_test', ['win', 'win10'], '', - 'Failure', False) + 'Failure', False, True) expected_contents = validate_tag_consistency.TAG_HEADER + """\ [ win ] some_test [ Failure ] @@ -330,7 +398,7 @@ with open(self.expectation_file, 'w') as outfile: outfile.write(expectation_file_contents) expectations.ModifyFileForResult(None, 'some_test', ['win', 'win10'], '', - 'Failure', True) + 'Failure', True, True) expected_contents = validate_tag_consistency.TAG_HEADER + """\ [ mac ] some_test [ Failure ] [ win win10 ] some_test [ Failure ] @@ -348,7 +416,7 @@ with open(self.expectation_file, 'w') as outfile: outfile.write(expectation_file_contents) expectations.ModifyFileForResult(None, 'foo_test', ['win', 'win10'], '', - 'Failure', True) + 'Failure', True, True) expected_contents = validate_tag_consistency.TAG_HEADER + """\ [ win ] some_test [ Failure ] [ win ] foo_test [ Failure ] @@ -360,6 +428,97 @@ @unittest.skipIf(sys.version_info[0] != 3, 'Python 3-only') +class FilterToMostSpecificTagTypeUnittest(fake_filesystem_unittest.TestCase): + def setUp(self): + self.setUpPyfakefs() + with tempfile.NamedTemporaryFile(delete=False) as tf: + self.expectation_file = tf.name + + def testBasic(self): + """Tests that only the most specific tags are kept.""" + expectation_file_contents = """\ +# tags: [ tag1_least_specific tag1_middle_specific tag1_most_specific ] +# tags: [ tag2_least_specific tag2_middle_specific tag2_most_specific ]""" + with open(self.expectation_file, 'w') as outfile: + outfile.write(expectation_file_contents) + + tags = [ + 'tag1_least_specific', 'tag1_most_specific', 'tag2_middle_specific', + 'tag2_least_specific' + ] + filtered_tags = expectations.FilterToMostSpecificTypTags( + tags, self.expectation_file) + self.assertEqual(filtered_tags, + ['tag1_most_specific', 'tag2_middle_specific']) + + def testSingleTags(self): + """Tests that functionality works as expected with single tags.""" + expectation_file_contents = """\ +# tags: [ tag1_most_specific ] +# tags: [ tag2_most_specific ]""" + with open(self.expectation_file, 'w') as outfile: + outfile.write(expectation_file_contents) + + tags = ['tag1_most_specific', 'tag2_most_specific'] + filtered_tags = expectations.FilterToMostSpecificTypTags( + tags, self.expectation_file) + self.assertEqual(filtered_tags, tags) + + def testUnusedTags(self): + """Tests that functionality works as expected with extra/unused tags.""" + expectation_file_contents = """\ +# tags: [ tag1_least_specific tag1_middle_specific tag1_most_specific ] +# tags: [ tag2_least_specific tag2_middle_specific tag2_most_specific ] +# tags: [ some_unused_tag ]""" + with open(self.expectation_file, 'w') as outfile: + outfile.write(expectation_file_contents) + + tags = [ + 'tag1_least_specific', 'tag1_most_specific', 'tag2_middle_specific', + 'tag2_least_specific' + ] + filtered_tags = expectations.FilterToMostSpecificTypTags( + tags, self.expectation_file) + self.assertEqual(filtered_tags, + ['tag1_most_specific', 'tag2_middle_specific']) + + def testMultiline(self): + """Tests that functionality works when tags cover multiple lines.""" + expectation_file_contents = """\ +# tags: [ tag1_least_specific +# tag1_middle_specific +# tag1_most_specific ] +# tags: [ tag2_least_specific +# tag2_middle_specific tag2_most_specific ]""" + with open(self.expectation_file, 'w') as outfile: + outfile.write(expectation_file_contents) + + tags = [ + 'tag1_least_specific', 'tag1_middle_specific', 'tag1_most_specific', + 'tag2_middle_specific', 'tag2_least_specific' + ] + filtered_tags = expectations.FilterToMostSpecificTypTags( + tags, self.expectation_file) + self.assertEqual(filtered_tags, + ['tag1_most_specific', 'tag2_middle_specific']) + + def testMissingTags(self): + """Tests that a file not having all tags is an error.""" + expectation_file_contents = """\ +# tags: [ tag1_least_specific tag1_middle_specific ] +# tags: [ tag2_least_specific tag2_middle_specific tag2_most_specific ]""" + with open(self.expectation_file, 'w') as outfile: + outfile.write(expectation_file_contents) + + tags = [ + 'tag1_least_specific', 'tag1_most_specific', 'tag2_middle_specific', + 'tag2_least_specific' + ] + with self.assertRaises(RuntimeError): + expectations.FilterToMostSpecificTypTags(tags, self.expectation_file) + + +@unittest.skipIf(sys.version_info[0] != 3, 'Python 3-only') class GetExpectationFileForSuiteUnittest(unittest.TestCase): def testRegularExpectationFile(self): """Tests that a regular expectation file is found properly."""
diff --git a/content/test/gpu/flake_suppressor/queries.py b/content/test/gpu/flake_suppressor/queries.py index baef642..5bdfcd7 100644 --- a/content/test/gpu/flake_suppressor/queries.py +++ b/content/test/gpu/flake_suppressor/queries.py
@@ -9,6 +9,7 @@ import subprocess from flake_suppressor import results as results_module +from flake_suppressor import tag_utils from unexpected_passes_common import queries as upc_queries @@ -132,12 +133,13 @@ json_results = json.loads(completed_process.stdout) - result_counts = collections.defaultdict(dict) + # A default dict of default dicts of ints. + result_counts = collections.defaultdict(lambda: collections.defaultdict(int)) for r in json_results: - typ_tags = tuple(r['typ_tags']) + typ_tags = tuple(tag_utils.RemoveMostIgnoredTags(r['typ_tags'])) test_name = r['test_name'] _, test_name = results_module.GetTestSuiteAndNameFromResultDbName(test_name) count = int(r['result_count']) - result_counts[typ_tags][test_name] = count + result_counts[typ_tags][test_name] += count return result_counts
diff --git a/content/test/gpu/flake_suppressor/queries_unittest.py b/content/test/gpu/flake_suppressor/queries_unittest.py index 2b5584f23..8050955 100755 --- a/content/test/gpu/flake_suppressor/queries_unittest.py +++ b/content/test/gpu/flake_suppressor/queries_unittest.py
@@ -53,6 +53,39 @@ self.assertEqual(result_counts, expected_result_counts) self._subprocess_mock.assert_called_once() + def testIgnoredTags(self): + """Tests that ignored tags are removed and their counts merged.""" + query_result = [ + { + 'typ_tags': ['win', 'win-laptop'], + 'test_name': 'garbage.suite.garbage.windows', + 'result_count': '100', + }, + { + 'typ_tags': ['win'], + 'test_name': 'garbage.suite.garbage.windows', + 'result_count': '50', + }, + { + 'typ_tags': ['mac', 'exact'], + 'test_name': 'garbage.suite.garbage.mac', + 'result_count': '200', + }, + ] + fake_process = uu.FakeProcess(stdout=json.dumps(query_result)) + self._subprocess_mock.return_value = fake_process + result_counts = queries.GetResultCounts(1, 'project') + expected_result_counts = { + tuple(['win']): { + 'windows': 150, + }, + tuple(['mac']): { + 'mac': 200, + }, + } + self.assertEqual(result_counts, expected_result_counts) + self._subprocess_mock.assert_called_once() + if __name__ == '__main__': unittest.main(verbosity=2)
diff --git a/content/test/gpu/flake_suppressor/results.py b/content/test/gpu/flake_suppressor/results.py index c22aa74b..fbd01cdb 100644 --- a/content/test/gpu/flake_suppressor/results.py +++ b/content/test/gpu/flake_suppressor/results.py
@@ -8,6 +8,7 @@ from flake_suppressor import data_types from flake_suppressor import expectations +from flake_suppressor import tag_utils from typ import expectations_parser @@ -55,9 +56,7 @@ for r in results: suite, test_name = GetTestSuiteAndNameFromResultDbName(r['name']) build_id = r['id'].split('-')[-1] - typ_tags = r['typ_tags'] - typ_tags.sort() - typ_tags = tuple(typ_tags) + typ_tags = tuple(tag_utils.RemoveMostIgnoredTags(r['typ_tags'])) object_results.append( data_types.Result(suite, test_name, typ_tags, build_id)) return object_results
diff --git a/content/test/gpu/flake_suppressor/results_unittest.py b/content/test/gpu/flake_suppressor/results_unittest.py index ad0a5b1..9756ded6 100755 --- a/content/test/gpu/flake_suppressor/results_unittest.py +++ b/content/test/gpu/flake_suppressor/results_unittest.py
@@ -49,7 +49,9 @@ 'conformance/textures/misc/video-rotation.html'), 'id': 'build-1111', - 'typ_tags': ['win', 'nvidia'], + # The win-laptop tag is ignored, and thus should be removed in the + # output. + 'typ_tags': ['win', 'nvidia', 'win-laptop'], }, { 'name': ('gpu_tests.webgl_conformance_integration_test.' @@ -182,7 +184,9 @@ 'conformance/textures/misc/video-rotation.html'), 'id': 'build-1111', - 'typ_tags': ['win', 'nvidia'], + # The win-laptop tag is ignored, and thus should be removed in the + # output. + 'typ_tags': ['win', 'nvidia', 'win-laptop'], }, { 'name': ('gpu_tests.webgl_conformance_integration_test.'
diff --git a/content/test/gpu/flake_suppressor/tag_utils.py b/content/test/gpu/flake_suppressor/tag_utils.py new file mode 100644 index 0000000..7f91be3f --- /dev/null +++ b/content/test/gpu/flake_suppressor/tag_utils.py
@@ -0,0 +1,54 @@ +# Copyright 2021 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Module for tag-related helper functions.""" + +from gpu_tests import gpu_integration_test + +IGNORED_TAGS_TO_TEMPORARILY_KEEP = set([ + 'webgl-version-1', + 'webgl-version-2', +]) + + +def RemoveMostIgnoredTags(tags): + """Removes ignored tags from |tags| except temporarily kept ones. + + The temporarily kept ones can later be removed by + RemoveTemporarilyKeptIgnoredTags(). + + Some tags are kept around temporarily because they contain useful information + for other parts of the script, but are not present in expectation files. + + Args: + tags: An iterable of strings containing tags + + Returns: + A list of strings containing the contents of |tags| with ignored tags + removed except for the ones in IGNORED_TAGS_TO_TEMPORARILY_KEEP. + """ + ignored_tags = set(gpu_integration_test.GpuIntegrationTest.IgnoredTags()) + tags = set(tags) + ignored_tags_to_keep = tags & IGNORED_TAGS_TO_TEMPORARILY_KEEP + tags -= ignored_tags + tags |= ignored_tags_to_keep + tags = list(tags) + tags.sort() + return tags + + +def RemoveTemporarilyKeptIgnoredTags(tags): + """Removes ignored tags that were temporarily kept. + + Args: + tags: An iterable of strings containing tags that at one point were passed + through RemoveMostIgnoredTags() + + Returns: + A list of strings containing the contents of |tags| with the contents of + IGNORED_TAGS_TO_TEMPORARILY_KEEP removed. Thus, the return value should not + have any remaining ignored tags. + """ + tags = list(set(tags) - IGNORED_TAGS_TO_TEMPORARILY_KEEP) + tags.sort() + return tags
diff --git a/content/test/gpu/flake_suppressor/tag_utils_unittest.py b/content/test/gpu/flake_suppressor/tag_utils_unittest.py new file mode 100755 index 0000000..24c468b --- /dev/null +++ b/content/test/gpu/flake_suppressor/tag_utils_unittest.py
@@ -0,0 +1,29 @@ +#!/usr/bin/env vpython3 +# 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. + +import unittest + +from flake_suppressor import tag_utils + + +class RemoveMostIgnoredTagsUnittest(unittest.TestCase): + def testBasic(self): + tags = ['win', 'win-laptop', 'webgl-version-1'] + filtered_tags = tag_utils.RemoveMostIgnoredTags(tags) + self.assertEqual(filtered_tags, ['webgl-version-1', 'win']) + + +class RemoveTemporarilyKeptIgnoredTagsUnittest(unittest.TestCase): + def testBasic(self): + # win-laptop shouldn't technically be here since it would have been removed + # by RemoveMostIgnoredTags(), but since this is *only* supposed to remove + # temporarily kept ignored tags, include it to test that. + tags = ['win', 'win-laptop', 'webgl-version-1', 'amd'] + filtered_tags = tag_utils.RemoveTemporarilyKeptIgnoredTags(tags) + self.assertEqual(filtered_tags, ['amd', 'win', 'win-laptop']) + + +if __name__ == '__main__': + unittest.main(verbosity=2) \ No newline at end of file
diff --git a/content/test/gpu/gpu_tests/gpu_integration_test.py b/content/test/gpu/gpu_tests/gpu_integration_test.py index e22b53b8..c50a7f6 100644 --- a/content/test/gpu/gpu_tests/gpu_integration_test.py +++ b/content/test/gpu/gpu_tests/gpu_integration_test.py
@@ -64,11 +64,14 @@ # on assumptions about retries, etc. if possible. _flaky_test_tries = collections.Counter() + # Keeps track of the first test that is run on a shard for a flakiness + # workaround. See crbug.com/1079244. + _first_run_test = None + def __init__(self, *args, **kwargs): super(GpuIntegrationTest, self).__init__(*args, **kwargs) if self.artifacts is None: self.set_artifacts(None) - self._first_run_test = None def set_artifacts(self, artifacts): # Instead of using the default logging artifact implementation, use the @@ -318,9 +321,9 @@ # conformance tests in the first test run on a shard. This should not be # kept in long-term. See crbug.com/1079244. if self._ShouldForceRetryOnFailureFirstTest(): - if self._first_run_test is None: - self._first_run_test = test_name - if self._first_run_test == test_name: + if GpuIntegrationTest._first_run_test is None: + GpuIntegrationTest._first_run_test = test_name + if GpuIntegrationTest._first_run_test == test_name: logging.warning('Forcing RetryOnFailure in test %s', test_name) should_retry_on_failure = True try:
diff --git a/content/test/gpu/suppress_flakes.py b/content/test/gpu/suppress_flakes.py index 562c7d1..12d5b1a 100755 --- a/content/test/gpu/suppress_flakes.py +++ b/content/test/gpu/suppress_flakes.py
@@ -69,6 +69,15 @@ 'will be marked as RetryOnFailure when ' '--no-prompt-for-user-input is used. Above this, ' 'failures will be marked as Failure.')) + parser.add_argument('--include-all-tags', + action='store_true', + default=False, + help=('Use all tags generated by a configuration when ' + 'creating an expectation rather than attempting ' + 'to only use the most specific one. This should ' + 'only need to be passed if the tags in the ' + 'expectation files are not ordered from least ' + 'specific to most specific.')) args = parser.parse_args() if not args.prompt_for_user_input: @@ -95,14 +104,13 @@ if args.prompt_for_user_input: input('\nBeginning of user input section - press any key to continue') expectations.IterateThroughResultsForUser(aggregated_results, - args.group_by_tags) + args.group_by_tags, + args.include_all_tags) else: result_counts = queries.GetResultCounts(args.sample_period, args.project) - expectations.IterateThroughResultsWithThresholds(aggregated_results, - args.group_by_tags, - result_counts, - args.ignore_threshold, - args.flaky_threshold) + expectations.IterateThroughResultsWithThresholds( + aggregated_results, args.group_by_tags, result_counts, + args.ignore_threshold, args.flaky_threshold, args.include_all_tags) print('\nGenerated expectations will need to have bugs manually added.') print('\nGenerated expectations likely contain conflicting tags that need to ' 'be removed.')
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index feb7d22..6805ba3 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -87,6 +87,12 @@ TestRenderFrameHost::~TestRenderFrameHost() = default; +void TestRenderFrameHost::FlushLocalFrameMessages() { + // Force creation of `local_frame_`. + GetAssociatedLocalFrame(); + local_frame_.FlushForTesting(); +} + TestRenderViewHost* TestRenderFrameHost::GetRenderViewHost() { return static_cast<TestRenderViewHost*>( RenderFrameHostImpl::GetRenderViewHost()); @@ -194,7 +200,8 @@ void TestRenderFrameHost::SimulateBeforeUnloadCompleted(bool proceed) { base::TimeTicks now = base::TimeTicks::Now(); ProcessBeforeUnloadCompleted( - proceed, false /* treat_as_final_completion_callback */, now, now); + proceed, /* treat_as_final_completion_callback= */ false, now, now, + /*for_legacy=*/false); } void TestRenderFrameHost::SimulateUnloadACK() {
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h index f59869c..711af70 100644 --- a/content/test/test_render_frame_host.h +++ b/content/test/test_render_frame_host.h
@@ -66,6 +66,9 @@ ~TestRenderFrameHost() override; + // Flushes mojo messages on `local_frame_`. + void FlushLocalFrameMessages(); + // RenderFrameHostImpl overrides (same values, but in Test*/Mock* types) TestRenderViewHost* GetRenderViewHost() override; MockRenderProcessHost* GetProcess() override;
diff --git a/content/web_test/browser/web_test_control_host.cc b/content/web_test/browser/web_test_control_host.cc index 660de00..65369ec 100644 --- a/content/web_test/browser/web_test_control_host.cc +++ b/content/web_test/browser/web_test_control_host.cc
@@ -250,7 +250,6 @@ prefs->dom_paste_enabled = true; prefs->javascript_can_access_clipboard = true; prefs->xslt_enabled = true; - prefs->application_cache_enabled = true; prefs->tabs_to_links = false; prefs->hyperlink_auditing_enabled = false; prefs->allow_running_insecure_content = false;
diff --git a/content/web_test/renderer/test_runner.cc b/content/web_test/renderer/test_runner.cc index 5bc213a..76a8497b 100644 --- a/content/web_test/renderer/test_runner.cc +++ b/content/web_test/renderer/test_runner.cc
@@ -487,7 +487,7 @@ // because WPT reftests never access this object. if (is_wpt_test && is_main_test_window && !web_frame->Parent() && !web_frame->Opener()) { - web_frame->ExecuteScript(blink::WebString( + web_frame->ExecuteScript(blink::WebScriptSource(blink::WebString( R"(if (!window.testRunner._wpt_reftest_setup) { window.testRunner._wpt_reftest_setup = true; @@ -516,7 +516,7 @@ document.fonts.ready.then(() => window.testRunner.notifyDone()); } }); - })")); + })"))); } } @@ -1104,7 +1104,7 @@ if (invalid_ || world_id <= 0 || world_id >= (1 << 29)) return {}; - blink::WebScriptSource source = blink::WebString::FromUTF8(script); + blink::WebScriptSource source(blink::WebString::FromUTF8(script)); return GetWebFrame()->ExecuteScriptInIsolatedWorldAndReturnValue( world_id, source, blink::BackForwardCacheAware::kAllow); } @@ -1115,7 +1115,7 @@ if (invalid_ || world_id <= 0 || world_id >= (1 << 29)) return; - blink::WebScriptSource source = blink::WebString::FromUTF8(script); + blink::WebScriptSource source(blink::WebString::FromUTF8(script)); GetWebFrame()->ExecuteScriptInIsolatedWorld( world_id, source, blink::BackForwardCacheAware::kAllow); }
diff --git a/device/fido/ctap_request_unittest.cc b/device/fido/ctap_request_unittest.cc index 6c8ddee..83fc8a9 100644 --- a/device/fido/ctap_request_unittest.cc +++ b/device/fido/ctap_request_unittest.cc
@@ -2,13 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/containers/contains.h" #include "components/cbor/reader.h" #include "device/fido/ctap_get_assertion_request.h" #include "device/fido/ctap_make_credential_request.h" #include "device/fido/fido_constants.h" #include "device/fido/fido_parsing_utils.h" #include "device/fido/fido_test_data.h" +#include "device/fido/fido_transport_protocol.h" #include "device/fido/mock_fido_device.h" +#include "device/fido/public_key_credential_descriptor.h" #include "device/fido/virtual_ctap2_device.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -72,4 +75,14 @@ test_data::kTestComplexCtapGetAssertionRequest)); } +// Regression test for https://crbug.com/1270757. +TEST(CTAPRequestTest, PublicKeyCredentialDescriptorAsCBOR_1270757) { + PublicKeyCredentialDescriptor descriptor( + CredentialType::kPublicKey, {{1, 2, 3}}, + {FidoTransportProtocol::kUsbHumanInterfaceDevice}); + cbor::Value value = AsCBOR(descriptor); + const cbor::Value::MapValue& map = value.GetMap(); + EXPECT_FALSE(base::Contains(map, cbor::Value("transports"))); +} + } // namespace device
diff --git a/device/fido/public_key_credential_descriptor.cc b/device/fido/public_key_credential_descriptor.cc index c1e22db..c9dedd8 100644 --- a/device/fido/public_key_credential_descriptor.cc +++ b/device/fido/public_key_credential_descriptor.cc
@@ -14,7 +14,6 @@ // Keys for storing credential descriptor information in CBOR map. constexpr char kCredentialIdKey[] = "id"; constexpr char kCredentialTypeKey[] = "type"; -constexpr char kTransportsKey[] = "transports"; } // namespace @@ -35,29 +34,8 @@ if (id == map.end() || !id->second.is_bytestring()) return absl::nullopt; - auto transports_it = map.find(cbor::Value(kTransportsKey)); - if (transports_it == map.end()) - return PublicKeyCredentialDescriptor(CredentialType::kPublicKey, - id->second.GetBytestring()); - - if (!transports_it->second.is_array()) - return absl::nullopt; - - base::flat_set<FidoTransportProtocol> transports; - for (const cbor::Value& transport_name : transports_it->second.GetArray()) { - if (!transport_name.is_string()) { - return absl::nullopt; - } - absl::optional<FidoTransportProtocol> transport = - ConvertToFidoTransportProtocol(transport_name.GetString()); - if (!transport) { - continue; - } - transports.insert(*transport); - } return PublicKeyCredentialDescriptor(CredentialType::kPublicKey, - id->second.GetBytestring(), - std::move(transports)); + id->second.GetBytestring()); } PublicKeyCredentialDescriptor::PublicKeyCredentialDescriptor() = default; @@ -100,14 +78,9 @@ cbor_descriptor_map[cbor::Value(kCredentialIdKey)] = cbor::Value(desc.id()); cbor_descriptor_map[cbor::Value(kCredentialTypeKey)] = cbor::Value(CredentialTypeToString(desc.credential_type())); - std::vector<cbor::Value> transports; - for (FidoTransportProtocol transport : desc.transports()) { - transports.emplace_back(cbor::Value(ToString(transport))); - } - if (!transports.empty()) { - cbor_descriptor_map[cbor::Value(kTransportsKey)] = - cbor::Value(std::move(transports)); - } + // Transports are omitted from CBOR serialization. They aren't useful for + // security keys to process. Some existing devices even refuse to parse them + // (see https://crbug.com/1270757). return cbor::Value(std::move(cbor_descriptor_map)); }
diff --git a/device/fido/public_key_credential_descriptor.h b/device/fido/public_key_credential_descriptor.h index 85ad4646..63489ab 100644 --- a/device/fido/public_key_credential_descriptor.h +++ b/device/fido/public_key_credential_descriptor.h
@@ -63,6 +63,7 @@ base::flat_set<FidoTransportProtocol> transports_; }; +COMPONENT_EXPORT(DEVICE_FIDO) cbor::Value AsCBOR(const PublicKeyCredentialDescriptor&); } // namespace device
diff --git a/extensions/browser/api/execute_code_function.cc b/extensions/browser/api/execute_code_function.cc index 970ffd4..96ec7ffe 100644 --- a/extensions/browser/api/execute_code_function.cc +++ b/extensions/browser/api/execute_code_function.cc
@@ -131,9 +131,12 @@ bool wants_result = has_callback(); std::vector<mojom::JSSourcePtr> sources; sources.push_back(mojom::JSSource::New(code_string, script_url_)); + // tabs.executeScript does not support waiting for promises (only + // scripting.executeScript does). + constexpr bool kWaitForPromises = false; injection = mojom::CodeInjection::NewJs(mojom::JSInjection::New( std::move(sources), mojom::ExecutionWorld::kIsolated, wants_result, - user_gesture())); + user_gesture(), kWaitForPromises)); } executor->ExecuteScript(
diff --git a/extensions/browser/api/messaging/message_service.cc b/extensions/browser/api/messaging/message_service.cc index 8a9749f..771595a 100644 --- a/extensions/browser/api/messaging/message_service.cc +++ b/extensions/browser/api/messaging/message_service.cc
@@ -124,7 +124,7 @@ return false; static const bool is_extension_message_supported = base::FeatureParam<bool>(&features::kBackForwardCache, - "extension_message_supported", false) + "extension_message_supported", true) .Get(); return is_extension_message_supported; }
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index 55166a73..63b6a11 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -74,12 +74,12 @@ #include "extensions/common/api/web_request.h" #include "extensions/common/constants.h" #include "extensions/common/error_utils.h" -#include "extensions/common/event_filtering_info.h" #include "extensions/common/extension.h" #include "extensions/common/extension_features.h" #include "extensions/common/features/feature.h" #include "extensions/common/features/feature_provider.h" #include "extensions/common/identifiability_metrics.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/common/permissions/permissions_data.h" #include "extensions/common/url_pattern.h" #include "extensions/strings/grit/extensions_strings.h" @@ -316,7 +316,8 @@ EventRouter* event_router = EventRouter::Get(browser_context); - EventFilteringInfo event_filtering_info; + mojom::EventFilteringInfoPtr event_filtering_info = + mojom::EventFilteringInfo::New(); events::HistogramValue histogram_value = events::UNKNOWN; std::string event_name; @@ -324,7 +325,8 @@ // process. We use a filter here so that only event listeners for a particular // <webview> will fire. if (is_web_view_guest) { - event_filtering_info.instance_id = web_view_instance_id; + event_filtering_info->has_instance_id = true; + event_filtering_info->instance_id = web_view_instance_id; histogram_value = events::WEB_VIEW_INTERNAL_ON_MESSAGE; event_name = webview::kEventMessage; } else { @@ -335,7 +337,7 @@ auto event = std::make_unique<Event>( histogram_value, event_name, std::move(*event_args).TakeList(), browser_context, GURL(), EventRouter::USER_GESTURE_UNKNOWN, - event_filtering_info); + std::move(event_filtering_info)); event_router->DispatchEventToExtension(extension_id, std::move(event)); } @@ -1625,7 +1627,7 @@ listener->histogram_value, listener->id.sub_event_name, listener->id.render_process_id, listener->id.worker_thread_id, listener->id.service_worker_version_id, std::move(args_filtered), - EventFilteringInfo()); + mojom::EventFilteringInfo::New()); } }
diff --git a/extensions/browser/event_listener_map.cc b/extensions/browser/event_listener_map.cc index 52967c5..f939873 100644 --- a/extensions/browser/event_listener_map.cc +++ b/extensions/browser/event_listener_map.cc
@@ -318,9 +318,8 @@ std::set<const EventListener*> interested_listeners; if (IsFilteredEvent(event)) { // Look up the interested listeners via the EventFilter. - std::set<MatcherID> ids = - event_filter_.MatchEvent(event.event_name, event.filter_info, - MSG_ROUTING_NONE); + std::set<MatcherID> ids = event_filter_.MatchEvent( + event.event_name, *event.filter_info, MSG_ROUTING_NONE); for (const MatcherID& id : ids) { EventListener* listener = listeners_by_matcher_id_[id]; CHECK(listener);
diff --git a/extensions/browser/event_listener_map_unittest.cc b/extensions/browser/event_listener_map_unittest.cc index 4090a55..2e5ae63 100644 --- a/extensions/browser/event_listener_map_unittest.cc +++ b/extensions/browser/event_listener_map_unittest.cc
@@ -13,6 +13,7 @@ #include "content/public/test/test_browser_context.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extensions_test.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -94,11 +95,11 @@ std::unique_ptr<Event> CreateEvent(const std::string& event_name, const GURL& url) { - EventFilteringInfo info; - info.url = url; - return std::make_unique<Event>(events::FOR_TEST, event_name, - std::vector<base::Value>(), nullptr, GURL(), - EventRouter::USER_GESTURE_UNKNOWN, info); + mojom::EventFilteringInfoPtr info = mojom::EventFilteringInfo::New(); + info->url = url; + return std::make_unique<Event>( + events::FOR_TEST, event_name, std::vector<base::Value>(), nullptr, + GURL(), EventRouter::USER_GESTURE_UNKNOWN, std::move(info)); } std::unique_ptr<EventListener> CreateLazyListener( @@ -205,7 +206,7 @@ } std::unique_ptr<Event> event(CreateNamedEvent(kEvent1Name)); - event->filter_info.url = GURL("http://www.google.com"); + event->filter_info->url = GURL("http://www.google.com"); std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); ASSERT_EQ(4u, targets.size()); } @@ -263,7 +264,7 @@ CreateHostSuffixFilter("google.com"))); std::unique_ptr<Event> event(CreateNamedEvent(kEvent1Name)); - event->filter_info.url = GURL("http://www.google.com"); + event->filter_info->url = GURL("http://www.google.com"); std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); ASSERT_EQ(2u, targets.size()); } @@ -279,7 +280,7 @@ listeners_->RemoveListenersForProcess(process_.get()); std::unique_ptr<Event> event(CreateNamedEvent(kEvent1Name)); - event->filter_info.url = GURL("http://www.google.com"); + event->filter_info->url = GURL("http://www.google.com"); ASSERT_EQ(1u, listeners_->GetEventListeners(*event).size()); } @@ -311,7 +312,7 @@ listeners_->RemoveListener(listener.get()); std::unique_ptr<Event> event(CreateNamedEvent(kEvent1Name)); - event->filter_info.url = GURL("http://www.google.com"); + event->filter_info->url = GURL("http://www.google.com"); ASSERT_EQ(1u, listeners_->GetEventListeners(*event).size()); } @@ -345,7 +346,7 @@ listeners_->RemoveListener(listener.get()); std::unique_ptr<Event> event(CreateNamedEvent(kEvent1Name)); - event->filter_info.url = GURL("http://www.google.com"); + event->filter_info->url = GURL("http://www.google.com"); std::set<const EventListener*> targets(listeners_->GetEventListeners(*event)); ASSERT_EQ(0u, targets.size()); } @@ -371,13 +372,13 @@ listeners_->RemoveListenersForExtension(kExt1Id); std::unique_ptr<Event> event1(CreateNamedEvent(kEvent1Name)); - event1->filter_info.url = GURL("http://www.google.com"); + event1->filter_info->url = GURL("http://www.google.com"); std::set<const EventListener*> targets( listeners_->GetEventListeners(*event1)); ASSERT_EQ(0u, targets.size()); std::unique_ptr<Event> event2(CreateNamedEvent(kEvent2Name)); - event2->filter_info.url = GURL("http://www.google.com"); + event2->filter_info->url = GURL("http://www.google.com"); targets = listeners_->GetEventListeners(*event2); ASSERT_EQ(0u, targets.size()); }
diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc index 3beca3a..21e7a0c 100644 --- a/extensions/browser/event_router.cc +++ b/extensions/browser/event_router.cc
@@ -33,6 +33,7 @@ #include "extensions/browser/process_manager.h" #include "extensions/browser/process_map.h" #include "extensions/common/constants.h" +#include "extensions/common/event_filtering_info_type_converters.h" #include "extensions/common/extension.h" #include "extensions/common/extension_api.h" #include "extensions/common/extension_messages.h" @@ -41,6 +42,7 @@ #include "extensions/common/features/feature_provider.h" #include "extensions/common/manifest_handlers/background_info.h" #include "extensions/common/manifest_handlers/incognito_info.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/common/permissions/permissions_data.h" using base::DictionaryValue; @@ -157,7 +159,7 @@ const std::string& event_name, ListValue* event_args, UserGestureState user_gesture, - const EventFilteringInfo& info) { + mojom::EventFilteringInfoPtr info) { NotifyEventDispatched(browser_context, extension_id, event_name, *event_args); mojom::DispatchEventParams params; params.worker_thread_id = worker_thread_id; @@ -165,7 +167,7 @@ params.event_name = event_name; params.event_id = event_id; params.is_user_gesture = user_gesture == USER_GESTURE_ENABLED; - params.filtering_info = info; + params.filtering_info = info->To<EventFilteringInfo>(); ipc_sender->Send(new ExtensionMsg_DispatchEvent(params, *event_args)); } @@ -192,7 +194,7 @@ int worker_thread_id, int64_t service_worker_version_id, std::unique_ptr<ListValue> event_args, - const EventFilteringInfo& info) { + mojom::EventFilteringInfoPtr info) { DCHECK_CURRENTLY_ON(BrowserThread::UI); int event_id = g_extension_event_id.GetNext(); @@ -202,7 +204,8 @@ DispatchExtensionMessage(ipc_sender, worker_thread_id, browser_context, extension_id, event_id, event_name, event_args.get(), - UserGestureState::USER_GESTURE_UNKNOWN, info); + UserGestureState::USER_GESTURE_UNKNOWN, + std::move(info)); } // static. @@ -954,7 +957,7 @@ DispatchExtensionMessage(process, worker_thread_id, listener_context, extension_id, event_id, event->event_name, event->event_args.get(), event->user_gesture, - event->filter_info); + event->filter_info.Clone()); for (TestObserver& observer : test_observers_) observer.OnDidDispatchEventToProcess(*event); @@ -1231,7 +1234,7 @@ restrict_to_browser_context, GURL(), EventRouter::USER_GESTURE_UNKNOWN, - EventFilteringInfo()) {} + mojom::EventFilteringInfo::New()) {} Event::Event(events::HistogramValue histogram_value, const std::string& event_name, @@ -1239,14 +1242,14 @@ content::BrowserContext* restrict_to_browser_context, const GURL& event_url, EventRouter::UserGestureState user_gesture, - const EventFilteringInfo& info) + mojom::EventFilteringInfoPtr info) : histogram_value(histogram_value), event_name(event_name), event_args(std::make_unique<base::ListValue>(std::move(event_args_tmp))), restrict_to_browser_context(restrict_to_browser_context), event_url(event_url), user_gesture(user_gesture), - filter_info(info) { + filter_info(std::move(info)) { DCHECK(event_args); DCHECK_NE(events::UNKNOWN, histogram_value) << "events::UNKNOWN cannot be used as a histogram value.\n" @@ -1259,9 +1262,10 @@ Event::~Event() = default; std::unique_ptr<Event> Event::DeepCopy() const { - auto copy = std::make_unique<Event>( - histogram_value, event_name, event_args->Clone().TakeList(), - restrict_to_browser_context, event_url, user_gesture, filter_info); + auto copy = std::make_unique<Event>(histogram_value, event_name, + event_args->Clone().TakeList(), + restrict_to_browser_context, event_url, + user_gesture, filter_info.Clone()); copy->will_dispatch_callback = will_dispatch_callback; return copy; }
diff --git a/extensions/browser/event_router.h b/extensions/browser/event_router.h index 74f8da5..bd526e90 100644 --- a/extensions/browser/event_router.h +++ b/extensions/browser/event_router.h
@@ -28,8 +28,8 @@ #include "extensions/browser/extension_registry_observer.h" #include "extensions/browser/lazy_context_task_queue.h" #include "extensions/common/constants.h" -#include "extensions/common/event_filtering_info.h" #include "extensions/common/features/feature.h" +#include "extensions/common/mojom/event_dispatcher.mojom-forward.h" #include "extensions/common/mojom/event_router.mojom.h" #include "ipc/ipc_sender.h" #include "mojo/public/cpp/bindings/associated_receiver_set.h" @@ -126,7 +126,7 @@ int worker_thread_id, int64_t service_worker_version_id, std::unique_ptr<base::ListValue> event_args, - const EventFilteringInfo& info); + mojom::EventFilteringInfoPtr info); // Returns false when the event is scoped to a context and the listening // extension does not have access to events from that context. @@ -363,7 +363,7 @@ const std::string& event_name, base::ListValue* event_args, UserGestureState user_gesture, - const extensions::EventFilteringInfo& info); + extensions::mojom::EventFilteringInfoPtr info); // Adds an extension as an event listener for |event_name|. // @@ -535,7 +535,7 @@ EventRouter::UserGestureState user_gesture; // Extra information used to filter which events are sent to the listener. - EventFilteringInfo filter_info; + mojom::EventFilteringInfoPtr filter_info; // If specified, this is called before dispatching an event to each // extension. The third argument is a mutable reference to event_args, @@ -567,7 +567,7 @@ content::BrowserContext* restrict_to_browser_context, const GURL& event_url, EventRouter::UserGestureState user_gesture, - const EventFilteringInfo& info); + mojom::EventFilteringInfoPtr info); ~Event();
diff --git a/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc b/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc index 5fd952eb..9a894d5 100644 --- a/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc +++ b/extensions/browser/guest_view/extensions_guest_view_manager_delegate.cc
@@ -28,6 +28,7 @@ #include "extensions/common/constants.h" #include "extensions/common/features/feature.h" #include "extensions/common/features/feature_provider.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/common/mojom/view_type.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-forward.h" @@ -55,8 +56,9 @@ std::unique_ptr<base::DictionaryValue> args, GuestViewBase* guest, int instance_id) { - EventFilteringInfo info; - info.instance_id = instance_id; + mojom::EventFilteringInfoPtr info = mojom::EventFilteringInfo::New(); + info->has_instance_id = true; + info->instance_id = instance_id; std::unique_ptr<base::ListValue> event_args(new base::ListValue()); event_args->Append(std::move(args)); @@ -78,7 +80,7 @@ guest->owner_host(), histogram_value, event_name, content::ChildProcessHost::kInvalidUniqueID, extensions::kMainThreadId, blink::mojom::kInvalidServiceWorkerVersionId, std::move(event_args), - info); + std::move(info)); } bool ExtensionsGuestViewManagerDelegate::IsGuestAvailableToContext(
diff --git a/extensions/common/BUILD.gn b/extensions/common/BUILD.gn index 7116e5b..3efbc39 100644 --- a/extensions/common/BUILD.gn +++ b/extensions/common/BUILD.gn
@@ -219,6 +219,8 @@ "event_filter.h", "event_filtering_info.cc", "event_filtering_info.h", + "event_filtering_info_type_converters.cc", + "event_filtering_info_type_converters.h", "event_matcher.cc", "event_matcher.h", "extension.cc",
diff --git a/extensions/common/OWNERS b/extensions/common/OWNERS index 7327a7b..407e8f1 100644 --- a/extensions/common/OWNERS +++ b/extensions/common/OWNERS
@@ -10,4 +10,5 @@ per-file *.typemap=file://ipc/SECURITY_OWNERS per-file *_struct_traits*.*=set noparent per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS - +per-file *_type_converter*.*=set noparent +per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
diff --git a/extensions/common/event_filter.cc b/extensions/common/event_filter.cc index 65f9d6f..789eadc2 100644 --- a/extensions/common/event_filter.cc +++ b/extensions/common/event_filter.cc
@@ -10,6 +10,7 @@ #include "base/logging.h" #include "base/notreached.h" #include "components/url_matcher/url_matcher_factory.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "ipc/ipc_message.h" using url_matcher::URLMatcher; @@ -135,7 +136,7 @@ std::set<EventFilter::MatcherID> EventFilter::MatchEvent( const std::string& event_name, - const EventFilteringInfo& event_info, + const mojom::EventFilteringInfo& event_info, int routing_id) const { std::set<MatcherID> matchers;
diff --git a/extensions/common/event_filter.h b/extensions/common/event_filter.h index 0e24860e..7d2c7bd2 100644 --- a/extensions/common/event_filter.h +++ b/extensions/common/event_filter.h
@@ -12,8 +12,8 @@ #include <vector> #include "components/url_matcher/url_matcher.h" -#include "extensions/common/event_filtering_info.h" #include "extensions/common/event_matcher.h" +#include "extensions/common/mojom/event_dispatcher.mojom-forward.h" namespace extensions { @@ -50,7 +50,7 @@ // event matchers that matched the event. // TODO(koz): Add a std::string* parameter for retrieving error messages. std::set<MatcherID> MatchEvent(const std::string& event_name, - const EventFilteringInfo& event_info, + const mojom::EventFilteringInfo& event_info, int routing_id) const; int GetMatcherCountForEventForTesting(const std::string& event_name) const;
diff --git a/extensions/common/event_filter_unittest.cc b/extensions/common/event_filter_unittest.cc index f0c21302..ace1797 100644 --- a/extensions/common/event_filter_unittest.cc +++ b/extensions/common/event_filter_unittest.cc
@@ -9,8 +9,8 @@ #include <utility> #include "base/values.h" -#include "extensions/common/event_filtering_info.h" #include "extensions/common/event_matcher.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "ipc/ipc_message.h" #include "testing/gtest/include/gtest/gtest.h" @@ -63,17 +63,16 @@ } EventFilter event_filter_; - EventFilteringInfo empty_event_; - EventFilteringInfo google_event_; - EventFilteringInfo yahoo_event_; - EventFilteringInfo random_url_event_; - EventFilteringInfo empty_url_event_; + mojom::EventFilteringInfo empty_event_; + mojom::EventFilteringInfo google_event_; + mojom::EventFilteringInfo yahoo_event_; + mojom::EventFilteringInfo random_url_event_; + mojom::EventFilteringInfo empty_url_event_; }; TEST_F(EventFilterUnittest, NoMatchersMatchIfEmpty) { - std::set<int> matches = event_filter_.MatchEvent("some-event", - empty_event_, - MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("some-event", empty_event_, MSG_ROUTING_NONE); ASSERT_EQ(0u, matches.size()); } @@ -84,55 +83,53 @@ TEST_F(EventFilterUnittest, DontMatchAgainstMatchersForDifferentEvents) { event_filter_.AddEventMatcher("event1", AllURLs()); - std::set<int> matches = event_filter_.MatchEvent("event2", - empty_event_, - MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event2", empty_event_, MSG_ROUTING_NONE); ASSERT_EQ(0u, matches.size()); } TEST_F(EventFilterUnittest, DoMatchAgainstMatchersForSameEvent) { int id = event_filter_.AddEventMatcher("event1", AllURLs()); - std::set<int> matches = event_filter_.MatchEvent("event1", - google_event_, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", google_event_, MSG_ROUTING_NONE); ASSERT_EQ(1u, matches.size()); ASSERT_EQ(1u, matches.count(id)); } TEST_F(EventFilterUnittest, DontMatchUnlessMatcherMatches) { - EventFilteringInfo info; + mojom::EventFilteringInfo info; info.url = GURL("http://www.yahoo.com"); event_filter_.AddEventMatcher("event1", HostSuffixMatcher("google.com")); - std::set<int> matches = event_filter_.MatchEvent( - "event1", info, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", info, MSG_ROUTING_NONE); ASSERT_TRUE(matches.empty()); } TEST_F(EventFilterUnittest, RemovingAnEventMatcherStopsItMatching) { int id = event_filter_.AddEventMatcher("event1", AllURLs()); event_filter_.RemoveEventMatcher(id); - std::set<int> matches = event_filter_.MatchEvent("event1", - empty_event_, - MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", empty_event_, MSG_ROUTING_NONE); ASSERT_TRUE(matches.empty()); } TEST_F(EventFilterUnittest, MultipleEventMatches) { int id1 = event_filter_.AddEventMatcher("event1", AllURLs()); int id2 = event_filter_.AddEventMatcher("event1", AllURLs()); - std::set<int> matches = event_filter_.MatchEvent("event1", - google_event_, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", google_event_, MSG_ROUTING_NONE); ASSERT_EQ(2u, matches.size()); ASSERT_EQ(1u, matches.count(id1)); ASSERT_EQ(1u, matches.count(id2)); } TEST_F(EventFilterUnittest, TestURLMatching) { - EventFilteringInfo info; + mojom::EventFilteringInfo info; info.url = GURL("http://www.google.com"); int id = event_filter_.AddEventMatcher("event1", HostSuffixMatcher("google.com")); - std::set<int> matches = event_filter_.MatchEvent( - "event1", info, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", info, MSG_ROUTING_NONE); ASSERT_EQ(1u, matches.size()); ASSERT_EQ(1u, matches.count(id)); } @@ -147,20 +144,20 @@ int id = event_filter_.AddEventMatcher("event1", std::move(matcher)); { - std::set<int> matches = event_filter_.MatchEvent("event1", - google_event_, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", google_event_, MSG_ROUTING_NONE); ASSERT_EQ(1u, matches.size()); ASSERT_EQ(1u, matches.count(id)); } { - std::set<int> matches = event_filter_.MatchEvent("event1", - yahoo_event_, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", yahoo_event_, MSG_ROUTING_NONE); ASSERT_EQ(1u, matches.size()); ASSERT_EQ(1u, matches.count(id)); } { - std::set<int> matches = event_filter_.MatchEvent("event1", - random_url_event_, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", random_url_event_, MSG_ROUTING_NONE); ASSERT_EQ(0u, matches.size()); } } @@ -171,8 +168,8 @@ event_filter_.RemoveEventMatcher(id1); { - std::set<int> matches = event_filter_.MatchEvent("event1", - google_event_, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", google_event_, MSG_ROUTING_NONE); ASSERT_EQ(1u, matches.size()); ASSERT_EQ(1u, matches.count(id2)); } @@ -183,8 +180,8 @@ event_filter_.AddEventMatcher("event2", AllURLs()); { - std::set<int> matches = event_filter_.MatchEvent("event1", - google_event_, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", google_event_, MSG_ROUTING_NONE); ASSERT_EQ(1u, matches.size()); ASSERT_EQ(1u, matches.count(id1)); } @@ -228,8 +225,8 @@ std::unique_ptr<EventMatcher> matcher( MatcherFromURLFilterList(std::make_unique<ListValue>())); int id = event_filter_.AddEventMatcher("event1", std::move(matcher)); - std::set<int> matches = event_filter_.MatchEvent("event1", - google_event_, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", google_event_, MSG_ROUTING_NONE); ASSERT_EQ(1u, matches.size()); ASSERT_EQ(1u, matches.count(id)); } @@ -246,8 +243,8 @@ TEST_F(EventFilterUnittest, EmptyURLsShouldBeMatchedByEmptyURLFilters) { int id = event_filter_.AddEventMatcher("event1", AllURLs()); - std::set<int> matches = event_filter_.MatchEvent( - "event1", empty_url_event_, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", empty_url_event_, MSG_ROUTING_NONE); ASSERT_EQ(1u, matches.size()); ASSERT_EQ(1u, matches.count(id)); } @@ -257,8 +254,8 @@ std::unique_ptr<EventMatcher> matcher(MatcherFromURLFilterList( ValueAsList(std::unique_ptr<Value>(new DictionaryValue())))); int id = event_filter_.AddEventMatcher("event1", std::move(matcher)); - std::set<int> matches = event_filter_.MatchEvent( - "event1", empty_url_event_, MSG_ROUTING_NONE); + std::set<int> matches = + event_filter_.MatchEvent("event1", empty_url_event_, MSG_ROUTING_NONE); ASSERT_EQ(1u, matches.size()); ASSERT_EQ(1u, matches.count(id)); }
diff --git a/extensions/common/event_filtering_info_type_converters.cc b/extensions/common/event_filtering_info_type_converters.cc new file mode 100644 index 0000000..c6df0a0 --- /dev/null +++ b/extensions/common/event_filtering_info_type_converters.cc
@@ -0,0 +1,45 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "extensions/common/event_filtering_info_type_converters.h" + +namespace mojo { + +// static +extensions::mojom::EventFilteringInfoPtr +TypeConverter<extensions::mojom::EventFilteringInfoPtr, + extensions::EventFilteringInfo>:: + Convert(const extensions::EventFilteringInfo& input) { + extensions::mojom::EventFilteringInfoPtr output = + extensions::mojom::EventFilteringInfo::New(); + output->url = input.url; + output->service_type = input.service_type; + output->has_instance_id = input.instance_id.has_value(); + if (output->has_instance_id) + output->instance_id = input.instance_id.value(); + output->window_type = input.window_type; + output->has_window_exposed_by_default = + input.window_exposed_by_default.has_value(); + if (output->has_window_exposed_by_default) + output->window_exposed_by_default = input.window_exposed_by_default.value(); + return output; +} + +// static +extensions::EventFilteringInfo +TypeConverter<extensions::EventFilteringInfo, + extensions::mojom::EventFilteringInfo>:: + Convert(const extensions::mojom::EventFilteringInfo& input) { + extensions::EventFilteringInfo output; + output.url = input.url; + output.service_type = input.service_type; + if (input.has_instance_id) + output.instance_id = input.instance_id; + output.window_type = input.window_type; + if (input.has_window_exposed_by_default) + output.window_exposed_by_default = input.window_exposed_by_default; + return output; +} + +} // namespace mojo \ No newline at end of file
diff --git a/extensions/common/event_filtering_info_type_converters.h b/extensions/common/event_filtering_info_type_converters.h new file mode 100644 index 0000000..5617457 --- /dev/null +++ b/extensions/common/event_filtering_info_type_converters.h
@@ -0,0 +1,31 @@ +// 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 EXTENSIONS_COMMON_EVENT_FILTERING_INFO_TYPE_CONVERTERS_H_ +#define EXTENSIONS_COMMON_EVENT_FILTERING_INFO_TYPE_CONVERTERS_H_ + +#include "extensions/common/event_filtering_info.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" +#include "mojo/public/cpp/bindings/type_converter.h" + +namespace mojo { +// TODO(crbug.com/1222550): Remove these converters once +// extensions::EventFilteringInfo is removed. +template <> +struct TypeConverter<extensions::mojom::EventFilteringInfoPtr, + extensions::EventFilteringInfo> { + static extensions::mojom::EventFilteringInfoPtr Convert( + const extensions::EventFilteringInfo& input); +}; + +template <> +struct TypeConverter<extensions::EventFilteringInfo, + extensions::mojom::EventFilteringInfo> { + static extensions::EventFilteringInfo Convert( + const extensions::mojom::EventFilteringInfo& input); +}; + +} // namespace mojo + +#endif // EXTENSIONS_COMMON_EVENT_FILTERING_INFO_TYPE_CONVERTERS_H_ \ No newline at end of file
diff --git a/extensions/common/event_matcher.cc b/extensions/common/event_matcher.cc index 6a84bca..6021fbd 100644 --- a/extensions/common/event_matcher.cc +++ b/extensions/common/event_matcher.cc
@@ -7,7 +7,7 @@ #include <utility> #include "base/callback.h" -#include "extensions/common/event_filtering_info.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" namespace { const char kUrlFiltersKey[] = "url"; @@ -26,9 +26,9 @@ } bool EventMatcher::MatchNonURLCriteria( - const EventFilteringInfo& event_info) const { - if (event_info.instance_id) { - return *event_info.instance_id == GetInstanceID(); + const mojom::EventFilteringInfo& event_info) const { + if (event_info.has_instance_id) { + return event_info.instance_id == GetInstanceID(); } if (event_info.window_type) { @@ -43,12 +43,12 @@ return false; } - if (event_info.window_exposed_by_default) { + if (event_info.has_window_exposed_by_default) { // An event with a |window_exposed_by_default| set is only // relevant to the listener if no window type filter is set. if (HasWindowTypes()) return false; - return *event_info.window_exposed_by_default; + return event_info.window_exposed_by_default; } const std::string& service_type_filter = GetServiceTypeFilter();
diff --git a/extensions/common/event_matcher.h b/extensions/common/event_matcher.h index 958b0d5..e5224db3 100644 --- a/extensions/common/event_matcher.h +++ b/extensions/common/event_matcher.h
@@ -8,10 +8,9 @@ #include <memory> #include "base/values.h" +#include "extensions/common/mojom/event_dispatcher.mojom-forward.h" namespace extensions { -struct EventFilteringInfo; - extern const char kEventFilterServiceTypeKey[]; // Matches EventFilteringInfos against a set of criteria. This is intended to @@ -29,7 +28,7 @@ // Returns true if |event_info| satisfies this matcher's criteria, not taking // into consideration any URL criteria. - bool MatchNonURLCriteria(const EventFilteringInfo& event_info) const; + bool MatchNonURLCriteria(const mojom::EventFilteringInfo& event_info) const; int GetURLFilterCount() const; bool GetURLFilter(int i, base::DictionaryValue** url_filter_out);
diff --git a/extensions/common/extension.cc b/extensions/common/extension.cc index 0e7ef99..505df2f 100644 --- a/extensions/common/extension.cc +++ b/extensions/common/extension.cc
@@ -253,6 +253,12 @@ return nullptr; } + if ((flags & FROM_BOOKMARK) != 0) { + // Extension-based bookmark apps are no longer supported. + // They have been replaced by web apps. + return nullptr; + } + std::unique_ptr<extensions::Manifest> manifest; if (flags & FOR_LOGIN_SCREEN) { manifest = Manifest::CreateManifestForLoginScreen(
diff --git a/extensions/common/extension.h b/extensions/common/extension.h index f992cfb..60ffc75f 100644 --- a/extensions/common/extension.h +++ b/extensions/common/extension.h
@@ -317,7 +317,7 @@ } int creation_flags() const { return creation_flags_; } bool from_webstore() const { return (creation_flags_ & FROM_WEBSTORE) != 0; } - bool from_bookmark() const { return (creation_flags_ & FROM_BOOKMARK) != 0; } + bool from_bookmark() const { return false; } bool may_be_untrusted() const { return (creation_flags_ & MAY_BE_UNTRUSTED) != 0; }
diff --git a/extensions/common/extension_l10n_util.cc b/extensions/common/extension_l10n_util.cc index 59d2d3a..df34a5ab 100644 --- a/extensions/common/extension_l10n_util.cc +++ b/extensions/common/extension_l10n_util.cc
@@ -17,6 +17,7 @@ #include "base/json/json_string_value_serializer.h" #include "base/logging.h" #include "base/no_destructor.h" +#include "base/strings/strcat.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -234,27 +235,29 @@ if (!LocalizeManifestValue(keys::kDescription, messages, manifest, error)) return false; + // Returns the key for the "default_title" entry in the given + // `action_key`'s manifest entry. + auto get_title_key = [](const char* action_key) { + return base::StrCat({action_key, ".", keys::kActionDefaultTitle}); + }; + // Initialize browser_action.default_title - std::string key(keys::kBrowserAction); - key.append("."); - key.append(keys::kActionDefaultTitle); - if (!LocalizeManifestValue(key, messages, manifest, error)) + if (!LocalizeManifestValue(get_title_key(keys::kBrowserAction), messages, + manifest, error)) { return false; + } // Initialize page_action.default_title - key.assign(keys::kPageAction); - key.append("."); - key.append(keys::kActionDefaultTitle); - if (!LocalizeManifestValue(key, messages, manifest, error)) + if (!LocalizeManifestValue(get_title_key(keys::kPageAction), messages, + manifest, error)) { return false; + } // Initialize action.default_title - // TODO(devlin): These could easily use something like base::StrCat(). - key.assign(keys::kAction); - key.append("."); - key.append(keys::kActionDefaultTitle); - if (!LocalizeManifestValue(key, messages, manifest, error)) + if (!LocalizeManifestValue(get_title_key(keys::kAction), messages, manifest, + error)) { return false; + } // Initialize omnibox.keyword. if (!LocalizeManifestValue(keys::kOmniboxKeyword, messages, manifest, error)) @@ -262,7 +265,6 @@ base::ListValue* file_handlers = NULL; if (manifest->GetList(keys::kFileBrowserHandlers, &file_handlers)) { - key.assign(keys::kFileBrowserHandlers); for (size_t i = 0; i < file_handlers->GetList().size(); i++) { base::DictionaryValue* handler = NULL; if (!file_handlers->GetDictionary(i, &handler)) { @@ -305,8 +307,8 @@ for (base::DictionaryValue::Iterator iter(*commands_handler); !iter.IsAtEnd(); iter.Advance()) { - key.assign( - base::StringPrintf("commands.%s.description", iter.key().c_str())); + std::string key = + base::StringPrintf("commands.%s.description", iter.key().c_str()); if (!LocalizeManifestValue(key, messages, manifest, error)) return false; } @@ -319,8 +321,8 @@ for (base::DictionaryValue::Iterator iter(*search_provider); !iter.IsAtEnd(); iter.Advance()) { - key.assign(base::StringPrintf( - "%s.%s", keys::kOverrideSearchProvider, iter.key().c_str())); + std::string key = base::StrCat( + {keys::kOverrideSearchProvider, ".", iter.key().c_str()}); bool success = (key == keys::kSettingsOverrideAlternateUrls) ? LocalizeManifestListValue(key, messages, manifest, error)
diff --git a/extensions/common/mojom/code_injection.mojom b/extensions/common/mojom/code_injection.mojom index 2f319a44..b2c0d3ba1 100644 --- a/extensions/common/mojom/code_injection.mojom +++ b/extensions/common/mojom/code_injection.mojom
@@ -42,6 +42,10 @@ // Whether the code to be executed should be associated with a user gesture. bool user_gesture; + + // If true and a script evaluates to a promise, causes the injection to + // wait for the promise to resolve and pass back the result. + bool wait_for_promise; }; // A struct representing a collection of CSS code to insert in the renderer.
diff --git a/extensions/renderer/bindings/DEPS b/extensions/renderer/bindings/DEPS index cec3540..0d84132 100644 --- a/extensions/renderer/bindings/DEPS +++ b/extensions/renderer/bindings/DEPS
@@ -10,8 +10,9 @@ # necessary for filtered listeners and do not themselves include any # extensions system knowledge. "+extensions/common/event_filter.h", - "+extensions/common/event_filtering_info.h", "+extensions/common/event_matcher.h", + "+extensions/common/mojom/event_dispatcher.mojom.h", + "+extensions/common/mojom/event_dispatcher.mojom-forward.h", "+extensions/common/value_counter.h", ]
diff --git a/extensions/renderer/bindings/api_binding_bridge.cc b/extensions/renderer/bindings/api_binding_bridge.cc index 47a36f0..52c8b61 100644 --- a/extensions/renderer/bindings/api_binding_bridge.cc +++ b/extensions/renderer/bindings/api_binding_bridge.cc
@@ -89,10 +89,6 @@ if (!result.IsJust() || !result.FromJust()) return; - // TODO(devlin): The binding.js version of these hooks also has a 'schema' - // property. I wonder if we can factor that out? If not, we'll need to add it - // here. - result = hook_object->SetPrototype(context, v8::Null(isolate)); if (!result.IsJust() || !result.FromJust()) return;
diff --git a/extensions/renderer/bindings/api_bindings_system.cc b/extensions/renderer/bindings/api_bindings_system.cc index eb41b67f..bdbb5c7 100644 --- a/extensions/renderer/bindings/api_bindings_system.cc +++ b/extensions/renderer/bindings/api_bindings_system.cc
@@ -4,8 +4,11 @@ #include "extensions/renderer/bindings/api_bindings_system.h" +#include <utility> + #include "base/bind.h" #include "base/values.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/bindings/api_binding_hooks.h" #include "extensions/renderer/bindings/api_binding_util.h" #include "extensions/renderer/bindings/api_response_validator.h" @@ -119,11 +122,13 @@ request_handler_.CompleteRequest(request_id, response, error); } -void APIBindingsSystem::FireEventInContext(const std::string& event_name, - v8::Local<v8::Context> context, - const base::ListValue& response, - const EventFilteringInfo* filter) { - event_handler_.FireEventInContext(event_name, context, response, filter); +void APIBindingsSystem::FireEventInContext( + const std::string& event_name, + v8::Local<v8::Context> context, + const base::ListValue& response, + mojom::EventFilteringInfoPtr filter) { + event_handler_.FireEventInContext(event_name, context, response, + std::move(filter)); } APIBindingHooks* APIBindingsSystem::GetHooksForAPI(
diff --git a/extensions/renderer/bindings/api_bindings_system.h b/extensions/renderer/bindings/api_bindings_system.h index e3c615b..c43935e0 100644 --- a/extensions/renderer/bindings/api_bindings_system.h +++ b/extensions/renderer/bindings/api_bindings_system.h
@@ -10,6 +10,7 @@ #include <string> #include "base/callback.h" +#include "extensions/common/mojom/event_dispatcher.mojom-forward.h" #include "extensions/renderer/bindings/api_binding.h" #include "extensions/renderer/bindings/api_binding_types.h" #include "extensions/renderer/bindings/api_event_handler.h" @@ -78,7 +79,7 @@ void FireEventInContext(const std::string& event_name, v8::Local<v8::Context> context, const base::ListValue& response, - const EventFilteringInfo* filter); + mojom::EventFilteringInfoPtr filter); // Returns the APIBindingHooks object for the given api to allow for // registering custom hooks. These must be registered *before* the
diff --git a/extensions/renderer/bindings/api_bindings_system_unittest.cc b/extensions/renderer/bindings/api_bindings_system_unittest.cc index 08f8fd4e..cd6aed3 100644 --- a/extensions/renderer/bindings/api_bindings_system_unittest.cc +++ b/extensions/renderer/bindings/api_bindings_system_unittest.cc
@@ -10,7 +10,7 @@ #include "base/cxx17_backports.h" #include "base/strings/stringprintf.h" #include "base/values.h" -#include "extensions/common/event_filtering_info.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/bindings/api_binding.h" #include "extensions/renderer/bindings/api_binding_hooks.h" #include "extensions/renderer/bindings/api_binding_hooks_test_delegate.h"
diff --git a/extensions/renderer/bindings/api_event_handler.cc b/extensions/renderer/bindings/api_event_handler.cc index bb387b2a..b316948 100644 --- a/extensions/renderer/bindings/api_event_handler.cc +++ b/extensions/renderer/bindings/api_event_handler.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <map> #include <memory> +#include <utility> #include <vector> #include "base/bind.h" @@ -17,6 +18,7 @@ #include "base/supports_user_data.h" #include "base/values.h" #include "content/public/renderer/v8_value_converter.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/bindings/event_emitter.h" #include "extensions/renderer/bindings/get_per_context_data.h" #include "extensions/renderer/bindings/js_runner.h" @@ -212,7 +214,7 @@ void APIEventHandler::FireEventInContext(const std::string& event_name, v8::Local<v8::Context> context, const base::ListValue& args, - const EventFilteringInfo* filter) { + mojom::EventFilteringInfoPtr filter) { // Don't bother converting arguments if there are no listeners. // NOTE(devlin): This causes a double data and EventEmitter lookup, since // the v8 version below also checks for listeners. This should be very cheap, @@ -231,7 +233,7 @@ for (const auto& arg : args.GetList()) v8_args.push_back(converter->ToV8Value(&arg, context)); - FireEventInContext(event_name, context, &v8_args, filter, + FireEventInContext(event_name, context, &v8_args, std::move(filter), JSRunner::ResultCallback()); } @@ -239,7 +241,7 @@ const std::string& event_name, v8::Local<v8::Context> context, std::vector<v8::Local<v8::Value>>* arguments, - const EventFilteringInfo* filter, + mojom::EventFilteringInfoPtr filter, JSRunner::ResultCallback callback) { APIEventPerContextData* data = APIEventPerContextData::GetFrom(context, kDontCreateIfMissing); @@ -256,7 +258,7 @@ auto massager_iter = data->massagers.find(event_name); if (massager_iter == data->massagers.end()) { - emitter->Fire(context, arguments, filter, std::move(callback)); + emitter->Fire(context, arguments, std::move(filter), std::move(callback)); } else { DCHECK(!callback) << "Can't use an event callback with argument massagers.";
diff --git a/extensions/renderer/bindings/api_event_handler.h b/extensions/renderer/bindings/api_event_handler.h index 0c146232..9b79ca0 100644 --- a/extensions/renderer/bindings/api_event_handler.h +++ b/extensions/renderer/bindings/api_event_handler.h
@@ -8,6 +8,7 @@ #include <string> #include "base/callback.h" +#include "extensions/common/mojom/event_dispatcher.mojom-forward.h" #include "extensions/renderer/bindings/api_binding_types.h" #include "extensions/renderer/bindings/api_event_listeners.h" #include "extensions/renderer/bindings/event_emitter.h" @@ -20,7 +21,6 @@ namespace extensions { class ExceptionHandler; -struct EventFilteringInfo; // The object to handle API events. This includes vending v8::Objects for the // event; handling adding, removing, and querying listeners; and firing events @@ -72,11 +72,11 @@ void FireEventInContext(const std::string& event_name, v8::Local<v8::Context> context, const base::ListValue& arguments, - const EventFilteringInfo* filter); + mojom::EventFilteringInfoPtr filter); void FireEventInContext(const std::string& event_name, v8::Local<v8::Context> context, std::vector<v8::Local<v8::Value>>* arguments, - const EventFilteringInfo* filter, + mojom::EventFilteringInfoPtr filter, JSRunner::ResultCallback callback); // Registers a |function| to serve as an "argument massager" for the given
diff --git a/extensions/renderer/bindings/api_event_handler_unittest.cc b/extensions/renderer/bindings/api_event_handler_unittest.cc index 2b40f2b..576f02a 100644 --- a/extensions/renderer/bindings/api_event_handler_unittest.cc +++ b/extensions/renderer/bindings/api_event_handler_unittest.cc
@@ -11,7 +11,7 @@ #include "base/test/bind.h" #include "base/test/mock_callback.h" #include "base/values.h" -#include "extensions/common/event_filtering_info.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/bindings/api_binding_test.h" #include "extensions/renderer/bindings/api_binding_test_util.h" #include "extensions/renderer/bindings/exception_handler.h" @@ -26,11 +26,6 @@ namespace { -const char kAddListenerFunction[] = - "(function(event, listener) { event.addListener(listener); })"; -const char kRemoveListenerFunction[] = - "(function(event, listener) { event.removeListener(listener); })"; - using MockEventChangeHandler = ::testing::StrictMock< base::MockCallback<APIEventListeners::ListenersUpdated>>; @@ -38,10 +33,16 @@ return "context"; } -// TODO(devlin): Use these handy functions more places. +// Note: Not function-local to RemoveListener() because it's used in one place +// that needs to circumvent RunFunction(). +constexpr char kRemoveListenerFunction[] = + "(function(event, listener) { event.removeListener(listener); })"; + void AddListener(v8::Local<v8::Context> context, v8::Local<v8::Function> listener, v8::Local<v8::Object> event) { + constexpr char kAddListenerFunction[] = + "(function(event, listener) { event.addListener(listener); })"; v8::Local<v8::Function> add_listener = FunctionFromString(context, kAddListenerFunction); v8::Local<v8::Value> argv[] = {event, listener}; @@ -113,20 +114,11 @@ FunctionFromString(context, kListenerFunction); ASSERT_FALSE(listener_function.IsEmpty()); - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - - { - v8::Local<v8::Value> argv[] = {event, listener_function}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } + AddListener(context, listener_function, event); // There should only be one listener on the event. EXPECT_EQ(1u, handler()->GetNumEventListenersForTesting(kEventName, context)); - { - v8::Local<v8::Value> argv[] = {event, listener_function}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } + AddListener(context, listener_function, event); // Trying to add the same listener again should be a no-op. EXPECT_EQ(1u, handler()->GetNumEventListenersForTesting(kEventName, context)); @@ -171,12 +163,7 @@ EXPECT_TRUE(has_listeners); } - v8::Local<v8::Function> remove_listener_function = - FunctionFromString(context, kRemoveListenerFunction); - { - v8::Local<v8::Value> argv[] = {event, listener_function}; - RunFunction(remove_listener_function, context, base::size(argv), argv); - } + RemoveListener(context, listener_function, event); EXPECT_EQ(0u, handler()->GetNumEventListenersForTesting(kEventName, context)); { @@ -229,22 +216,9 @@ ASSERT_FALSE(alpha_listener2.IsEmpty()); ASSERT_FALSE(beta_listener.IsEmpty()); - { - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - { - v8::Local<v8::Value> argv[] = {alpha_event, alpha_listener1}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } - { - v8::Local<v8::Value> argv[] = {alpha_event, alpha_listener2}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } - { - v8::Local<v8::Value> argv[] = {beta_event, beta_listener}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } - } + AddListener(context, alpha_listener1, alpha_event); + AddListener(context, alpha_listener2, alpha_event); + AddListener(context, beta_listener, beta_event); EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kAlphaName, context)); EXPECT_EQ(1u, handler()->GetNumEventListenersForTesting(kBetaName, context)); @@ -302,12 +276,7 @@ FunctionFromString(context, kListenerFunction); ASSERT_FALSE(listener_function.IsEmpty()); - { - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - v8::Local<v8::Value> argv[] = {event, listener_function}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } + AddListener(context, listener_function, event); const char kArguments[] = "['foo',1,{'prop1':'bar'}]"; std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); @@ -345,23 +314,13 @@ ASSERT_FALSE(event_b.IsEmpty()); // Add two separate listeners to the event, one in each context. - { - v8::Local<v8::Function> add_listener_a = - FunctionFromString(context_a, kAddListenerFunction); - v8::Local<v8::Value> argv[] = {event_a, listener_a}; - RunFunction(add_listener_a, context_a, base::size(argv), argv); - } + AddListener(context_a, listener_a, event_a); EXPECT_EQ(1u, handler()->GetNumEventListenersForTesting(kEventName, context_a)); EXPECT_EQ(0u, handler()->GetNumEventListenersForTesting(kEventName, context_b)); - { - v8::Local<v8::Function> add_listener_b = - FunctionFromString(context_b, kAddListenerFunction); - v8::Local<v8::Value> argv[] = {event_b, listener_b}; - RunFunction(add_listener_b, context_b, base::size(argv), argv); - } + AddListener(context_b, listener_b, event_b); EXPECT_EQ(1u, handler()->GetNumEventListenersForTesting(kEventName, context_a)); EXPECT_EQ(1u, @@ -466,13 +425,7 @@ v8::Local<v8::Function> listener = FunctionFromString(context, kListenerFunction); - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - - { - v8::Local<v8::Value> argv[] = {event, listener}; - RunFunctionOnGlobal(add_listener_function, context, base::size(argv), argv); - } + AddListener(context, listener, event); v8::Local<v8::Function> fire_event_function = FunctionFromString( @@ -524,13 +477,8 @@ for (size_t i = 0; i < kNumListeners; ++i) listeners.push_back(FunctionFromString(context, kListenerFunction)); - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - - for (const auto& listener : listeners) { - v8::Local<v8::Value> argv[] = {event, listener}; - RunFunctionOnGlobal(add_listener_function, context, base::size(argv), argv); - } + for (const auto& listener : listeners) + AddListener(context, listener, event); // Fire the event. All listeners should be removed (and we shouldn't crash). EXPECT_EQ(kNumListeners, @@ -576,14 +524,10 @@ " this.eventArgs = Array.from(arguments);\n" "});"; - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - for (int i = 0; i < 2; ++i) { v8::Local<v8::Function> listener = FunctionFromString(context, kListenerFunction); - v8::Local<v8::Value> argv[] = {event, listener}; - RunFunctionOnGlobal(add_listener_function, context, base::size(argv), argv); + AddListener(context, listener, event); } EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kEventName, context)); @@ -632,8 +576,6 @@ // Add a listener to the first event. The APIEventHandler should notify // since it's a change in state (no listeners -> listeners). - v8::Local<v8::Function> add_listener = - FunctionFromString(context_a, kAddListenerFunction); v8::Local<v8::Function> listener1 = FunctionFromString(context_a, "(function() {})"); { @@ -643,8 +585,7 @@ kFirstUnfilteredListenerForContextOwnerAdded, nullptr, true, context_a)) .Times(1); - v8::Local<v8::Value> argv[] = {event1_a, listener1}; - RunFunction(add_listener, context_a, base::size(argv), argv); + AddListener(context_a, listener1, event1_a); ::testing::Mock::VerifyAndClearExpectations(&change_handler); } EXPECT_EQ(1u, @@ -654,21 +595,13 @@ // the event already had listeners. v8::Local<v8::Function> listener2 = FunctionFromString(context_a, "(function() {})"); - { - v8::Local<v8::Value> argv[] = {event1_a, listener2}; - RunFunction(add_listener, context_a, base::size(argv), argv); - } + AddListener(context_a, listener2, event1_a); EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kEventName1, context_a)); // Remove the first listener of the event. Again, since the event has // listeners, we shouldn't be notified. - v8::Local<v8::Function> remove_listener = - FunctionFromString(context_a, kRemoveListenerFunction); - { - v8::Local<v8::Value> argv[] = {event1_a, listener1}; - RunFunction(remove_listener, context_a, base::size(argv), argv); - } + RemoveListener(context_a, listener1, event1_a); EXPECT_EQ(1u, handler()->GetNumEventListenersForTesting(kEventName1, context_a)); @@ -682,8 +615,7 @@ kLastUnfilteredListenerForContextOwnerRemoved, nullptr, true, context_a)) .Times(1); - v8::Local<v8::Value> argv[] = {event1_a, listener2}; - RunFunction(remove_listener, context_a, base::size(argv), argv); + RemoveListener(context_a, listener2, event1_a); ::testing::Mock::VerifyAndClearExpectations(&change_handler); } EXPECT_EQ(0u, @@ -700,8 +632,7 @@ kFirstUnfilteredListenerForContextOwnerAdded, nullptr, true, context_a)) .Times(1); - v8::Local<v8::Value> argv[] = {event2_a, listener3}; - RunFunction(add_listener, context_a, base::size(argv), argv); + AddListener(context_a, listener3, event2_a); ::testing::Mock::VerifyAndClearExpectations(&change_handler); } EXPECT_EQ(1u, @@ -716,12 +647,9 @@ .Times(1); // And add a listener to an event in a different context to make sure the // associated context is correct. - v8::Local<v8::Function> add_listener_b = - FunctionFromString(context_b, kAddListenerFunction); v8::Local<v8::Function> listener = FunctionFromString(context_b, "(function() {})"); - v8::Local<v8::Value> argv[] = {event1_b, listener}; - RunFunction(add_listener_b, context_b, base::size(argv), argv); + AddListener(context_b, listener, event1_b); ::testing::Mock::VerifyAndClearExpectations(&change_handler); } EXPECT_EQ(1u, @@ -774,12 +702,7 @@ FunctionFromString(context, kListenerFunction); ASSERT_FALSE(listener_function.IsEmpty()); - { - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - v8::Local<v8::Value> argv[] = {event, listener_function}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } + AddListener(context, listener_function, event); const char kArguments[] = "['first','second']"; std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); @@ -820,12 +743,7 @@ FunctionFromString(context, kListenerFunction); ASSERT_FALSE(listener_function.IsEmpty()); - { - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - v8::Local<v8::Value> argv[] = {event, listener_function}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } + AddListener(context, listener_function, event); const char kArguments[] = "['first','second']"; std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); @@ -877,10 +795,7 @@ FunctionFromString(context, kListenerFunction); ASSERT_FALSE(listener_function.IsEmpty()); - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - v8::Local<v8::Value> argv[] = {event, listener_function}; - RunFunction(add_listener_function, context, base::size(argv), argv); + AddListener(context, listener_function, event); handler()->FireEventInContext(kEventName, context, base::ListValue(), nullptr); @@ -918,13 +833,7 @@ v8::Local<v8::Function> listener_function = FunctionFromString(context, kListenerFunction); ASSERT_FALSE(listener_function.IsEmpty()); - - { - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - v8::Local<v8::Value> argv[] = {event, listener_function}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } + AddListener(context, listener_function, event); handler()->FireEventInContext(kEventName, context, base::ListValue(), nullptr); @@ -951,15 +860,11 @@ v8::Local<v8::Object> event = handler.CreateAnonymousEventInstance(context); ASSERT_FALSE(event.IsEmpty()); - const char kLocalAddListenerFunction[] = - "(function(event) {\n" - " event.addListener(function() {\n" - " this.eventArgs = Array.from(arguments);\n" - " });\n" - "})"; - v8::Local<v8::Value> add_listener_argv[] = {event}; - RunFunction(FunctionFromString(context, kLocalAddListenerFunction), context, - base::size(add_listener_argv), add_listener_argv); + constexpr char kListenerFunction[] = + R"((function() { this.eventArgs = Array.from(arguments); }))"; + v8::Local<v8::Function> listener = + FunctionFromString(context, kListenerFunction); + AddListener(context, listener, event); // Test dispatching to the listeners. const char kDispatchEventFunction[] = @@ -1027,18 +932,9 @@ kEventName, false, true, binding::kNoListenerMax, false, context); const char kListener[] = - "(function() {\n" - " this.eventArgs = Array.from(arguments);\n" - "});"; + R"((function() { this.eventArgs = Array.from(arguments); }))"; v8::Local<v8::Function> listener = FunctionFromString(context, kListener); - - { - const char kAddListener[] = - "(function(event, listener) { event.addListener(listener); })"; - v8::Local<v8::Value> args[] = {event, listener}; - RunFunction(FunctionFromString(context, kAddListener), context, - base::size(args), args); - } + AddListener(context, listener, event); EXPECT_EQ(1u, handler.GetNumEventListenersForTesting(kEventName, context)); @@ -1048,13 +944,7 @@ EXPECT_EQ("[1,\"foo\"]", GetStringPropertyFromObject(context->Global(), context, "eventArgs")); - { - const char kRemoveListener[] = - "(function(event, listener) { event.removeListener(listener); })"; - v8::Local<v8::Value> args[] = {event, listener}; - RunFunction(FunctionFromString(context, kRemoveListener), context, - base::size(args), args); - } + RemoveListener(context, listener, event); EXPECT_EQ(0u, handler.GetNumEventListenersForTesting(kEventName, context)); } @@ -1078,8 +968,6 @@ binding::kNoListenerMax, true, context); ASSERT_FALSE(lazy_listeners_not_supported.IsEmpty()); - v8::Local<v8::Function> add_listener = - FunctionFromString(context, kAddListenerFunction); v8::Local<v8::Function> listener = FunctionFromString(context, "(function() {})"); { @@ -1089,8 +977,7 @@ kFirstUnfilteredListenerForContextOwnerAdded, nullptr, true, context)) .Times(1); - v8::Local<v8::Value> argv[] = {lazy_listeners_supported, listener}; - RunFunction(add_listener, context, base::size(argv), argv); + AddListener(context, listener, lazy_listeners_supported); ::testing::Mock::VerifyAndClearExpectations(&change_handler); } @@ -1101,13 +988,10 @@ kFirstUnfilteredListenerForContextOwnerAdded, nullptr, false, context)) .Times(1); - v8::Local<v8::Value> argv[] = {lazy_listeners_not_supported, listener}; - RunFunction(add_listener, context, base::size(argv), argv); + AddListener(context, listener, lazy_listeners_not_supported); ::testing::Mock::VerifyAndClearExpectations(&change_handler); } - v8::Local<v8::Function> remove_listener = - FunctionFromString(context, kRemoveListenerFunction); { EXPECT_CALL(change_handler, Run(kLazyListenersSupported, @@ -1115,8 +999,7 @@ kLastUnfilteredListenerForContextOwnerRemoved, nullptr, true, context)) .Times(1); - v8::Local<v8::Value> argv[] = {lazy_listeners_supported, listener}; - RunFunction(remove_listener, context, base::size(argv), argv); + RemoveListener(context, listener, lazy_listeners_supported); ::testing::Mock::VerifyAndClearExpectations(&change_handler); } @@ -1127,8 +1010,7 @@ kLastUnfilteredListenerForContextOwnerRemoved, nullptr, false, context)) .Times(1); - v8::Local<v8::Value> argv[] = {lazy_listeners_not_supported, listener}; - RunFunction(remove_listener, context, base::size(argv), argv); + RemoveListener(context, listener, lazy_listeners_not_supported); ::testing::Mock::VerifyAndClearExpectations(&change_handler); } @@ -1148,12 +1030,7 @@ v8::Local<v8::Function> listener = FunctionFromString(context, kListenerFunction); - { - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - v8::Local<v8::Value> argv[] = {event, listener}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } + AddListener(context, listener, event); { // Suspend script and fire an event. The listener should *not* be notified @@ -1201,12 +1078,7 @@ v8::Local<v8::Function> listener = FunctionFromString(context, kListenerFunction); - { - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - v8::Local<v8::Value> argv[] = {event, listener}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } + AddListener(context, listener, event); TestJSRunner::AllowErrors allow_errors; { @@ -1251,18 +1123,8 @@ FunctionFromString(context, kListenerFunction2); // Add two event listeners. - { - v8::Local<v8::Function> add_listener_function = - FunctionFromString(context, kAddListenerFunction); - { - v8::Local<v8::Value> argv[] = {event, listener1}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } - { - v8::Local<v8::Value> argv[] = {event, listener2}; - RunFunction(add_listener_function, context, base::size(argv), argv); - } - } + AddListener(context, listener1, event); + AddListener(context, listener2, event); EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kEventName, context)); {
diff --git a/extensions/renderer/bindings/api_event_listeners.cc b/extensions/renderer/bindings/api_event_listeners.cc index 6f41e0b96..9bb3b3b 100644 --- a/extensions/renderer/bindings/api_event_listeners.cc +++ b/extensions/renderer/bindings/api_event_listeners.cc
@@ -8,8 +8,8 @@ #include <memory> #include "content/public/renderer/v8_value_converter.h" -#include "extensions/common/event_filtering_info.h" #include "extensions/common/event_matcher.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/bindings/listener_tracker.h" #include "gin/converter.h" @@ -160,7 +160,7 @@ } std::vector<v8::Local<v8::Function>> UnfilteredEventListeners::GetListeners( - const EventFilteringInfo* filter, + mojom::EventFilteringInfoPtr filter, v8::Local<v8::Context> context) { std::vector<v8::Local<v8::Function>> listeners; listeners.reserve(listeners_.size()); @@ -310,10 +310,12 @@ } std::vector<v8::Local<v8::Function>> FilteredEventListeners::GetListeners( - const EventFilteringInfo* filter, + mojom::EventFilteringInfoPtr filter, v8::Local<v8::Context> context) { std::set<int> ids = listener_tracker_->GetMatchingFilteredListeners( - event_name_, filter ? *filter : EventFilteringInfo(), kIgnoreRoutingId); + event_name_, + filter ? std::move(filter) : mojom::EventFilteringInfo::New(), + kIgnoreRoutingId); std::vector<v8::Local<v8::Function>> listeners; listeners.reserve(ids.size());
diff --git a/extensions/renderer/bindings/api_event_listeners.h b/extensions/renderer/bindings/api_event_listeners.h index 44c894b..5a784a2 100644 --- a/extensions/renderer/bindings/api_event_listeners.h +++ b/extensions/renderer/bindings/api_event_listeners.h
@@ -9,6 +9,7 @@ #include <vector> #include "base/callback.h" +#include "extensions/common/mojom/event_dispatcher.mojom-forward.h" #include "extensions/renderer/bindings/api_binding_types.h" #include "v8/include/v8.h" @@ -18,7 +19,6 @@ namespace extensions { class ListenerTracker; -struct EventFilteringInfo; // A base class to hold listeners for a given event. This allows for adding, // removing, and querying listeners in the list, and calling a callback when @@ -75,7 +75,7 @@ // Returns the listeners that should be notified for the given |filter|. virtual std::vector<v8::Local<v8::Function>> GetListeners( - const EventFilteringInfo* filter, + mojom::EventFilteringInfoPtr filter, v8::Local<v8::Context> context) = 0; // Invalidates the list. @@ -110,7 +110,7 @@ bool HasListener(v8::Local<v8::Function> listener) override; size_t GetNumListeners() override; std::vector<v8::Local<v8::Function>> GetListeners( - const EventFilteringInfo* filter, + mojom::EventFilteringInfoPtr filter, v8::Local<v8::Context> context) override; void Invalidate(v8::Local<v8::Context> context) override; @@ -185,7 +185,7 @@ bool HasListener(v8::Local<v8::Function> listener) override; size_t GetNumListeners() override; std::vector<v8::Local<v8::Function>> GetListeners( - const EventFilteringInfo* filter, + mojom::EventFilteringInfoPtr filter, v8::Local<v8::Context> context) override; void Invalidate(v8::Local<v8::Context> context) override;
diff --git a/extensions/renderer/bindings/api_event_listeners_unittest.cc b/extensions/renderer/bindings/api_event_listeners_unittest.cc index 7aa37a3fb..583364db 100644 --- a/extensions/renderer/bindings/api_event_listeners_unittest.cc +++ b/extensions/renderer/bindings/api_event_listeners_unittest.cc
@@ -4,11 +4,14 @@ #include "extensions/renderer/bindings/api_event_listeners.h" +#include <utility> + #include "base/bind.h" #include "base/callback_helpers.h" #include "base/test/mock_callback.h" #include "base/values.h" #include "extensions/common/event_filter.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/bindings/api_binding_test.h" #include "extensions/renderer/bindings/api_binding_test_util.h" #include "extensions/renderer/bindings/api_binding_types.h" @@ -160,9 +163,10 @@ std::string error; v8::Local<v8::Object> filter; EXPECT_TRUE(listeners.AddListener(function, filter, context, &error)); - EventFilteringInfo filtering_info; - filtering_info.url = GURL("http://example.com/foo"); - EXPECT_THAT(listeners.GetListeners(&filtering_info, context), + mojom::EventFilteringInfoPtr filtering_info = + mojom::EventFilteringInfo::New(); + filtering_info->url = GURL("http://example.com/foo"); + EXPECT_THAT(listeners.GetListeners(std::move(filtering_info), context), testing::UnorderedElementsAre(function)); } @@ -268,9 +272,9 @@ // Since function_a has no filter, associating a specific url should still // return function_a. - EventFilteringInfo filtering_info_match; + mojom::EventFilteringInfo filtering_info_match; filtering_info_match.url = GURL("http://example.com/foo"); - EXPECT_THAT(listeners.GetListeners(&filtering_info_match, context), + EXPECT_THAT(listeners.GetListeners(filtering_info_match.Clone(), context), testing::UnorderedElementsAre(function_a)); // Trying to add function_a again should have no effect. @@ -318,12 +322,12 @@ EXPECT_THAT(listeners.GetListeners(nullptr, context), testing::UnorderedElementsAre(function_a)); // function_b should be included for matching urls... - EXPECT_THAT(listeners.GetListeners(&filtering_info_match, context), + EXPECT_THAT(listeners.GetListeners(filtering_info_match.Clone(), context), testing::UnorderedElementsAre(function_a, function_b)); // ... but not urls that don't match. - EventFilteringInfo filtering_info_no_match; + mojom::EventFilteringInfo filtering_info_no_match; filtering_info_no_match.url = GURL("http://example.com/bar"); - EXPECT_THAT(listeners.GetListeners(&filtering_info_no_match, context), + EXPECT_THAT(listeners.GetListeners(filtering_info_no_match.Clone(), context), testing::UnorderedElementsAre(function_a)); // Remove function_a. Since filtered listeners notify whenever there's a @@ -343,10 +347,10 @@ // function_b should be the only listener remaining, so we shouldn't find // any listeners for events without matching filters. EXPECT_TRUE(listeners.GetListeners(nullptr, context).empty()); - EXPECT_THAT(listeners.GetListeners(&filtering_info_match, context), + EXPECT_THAT(listeners.GetListeners(filtering_info_match.Clone(), context), testing::UnorderedElementsAre(function_b)); EXPECT_TRUE( - listeners.GetListeners(&filtering_info_no_match, context).empty()); + listeners.GetListeners(filtering_info_no_match.Clone(), context).empty()); // Remove function_b. No listeners should remain. EXPECT_CALL(handler, Run(kEvent, @@ -358,7 +362,8 @@ EXPECT_FALSE(listeners.HasListener(function_b)); EXPECT_EQ(0u, listeners.GetNumListeners()); EXPECT_TRUE(listeners.GetListeners(nullptr, context).empty()); - EXPECT_TRUE(listeners.GetListeners(&filtering_info_match, context).empty()); + EXPECT_TRUE( + listeners.GetListeners(filtering_info_match.Clone(), context).empty()); EXPECT_EQ( 0, tracker.event_filter_for_testing()->GetMatcherCountForEventForTesting( kEvent)); @@ -404,10 +409,11 @@ 3, tracker.event_filter_for_testing()->GetMatcherCountForEventForTesting( kEvent)); - EventFilteringInfo filtering_info_match; - filtering_info_match.url = GURL("http://example.com/foo"); + mojom::EventFilteringInfoPtr filtering_info_match = + mojom::EventFilteringInfo::New(); + filtering_info_match->url = GURL("http://example.com/foo"); EXPECT_THAT( - listeners.GetListeners(&filtering_info_match, context), + listeners.GetListeners(std::move(filtering_info_match), context), testing::UnorderedElementsAre(function_a, function_b, function_c)); listeners.RemoveListener(function_c, context);
diff --git a/extensions/renderer/bindings/event_emitter.cc b/extensions/renderer/bindings/event_emitter.cc index 099e691..75d99c1 100644 --- a/extensions/renderer/bindings/event_emitter.cc +++ b/extensions/renderer/bindings/event_emitter.cc
@@ -5,7 +5,9 @@ #include "extensions/renderer/bindings/event_emitter.h" #include <algorithm> +#include <utility> +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/bindings/api_binding_util.h" #include "extensions/renderer/bindings/api_event_listeners.h" #include "extensions/renderer/bindings/exception_handler.h" @@ -55,17 +57,17 @@ void EventEmitter::Fire(v8::Local<v8::Context> context, std::vector<v8::Local<v8::Value>>* args, - const EventFilteringInfo* filter, + mojom::EventFilteringInfoPtr filter, JSRunner::ResultCallback callback) { - DispatchAsync(context, args, filter, std::move(callback)); + DispatchAsync(context, args, std::move(filter), std::move(callback)); } v8::Local<v8::Value> EventEmitter::FireSync( v8::Local<v8::Context> context, std::vector<v8::Local<v8::Value>>* args, - const EventFilteringInfo* filter) { + mojom::EventFilteringInfoPtr filter) { DCHECK(context == context->GetIsolate()->GetCurrentContext()); - return DispatchSync(context, args, filter); + return DispatchSync(context, args, std::move(filter)); } void EventEmitter::Invalidate(v8::Local<v8::Context> context) { @@ -155,10 +157,10 @@ v8::Local<v8::Value> EventEmitter::DispatchSync( v8::Local<v8::Context> context, std::vector<v8::Local<v8::Value>>* args, - const EventFilteringInfo* filter) { + mojom::EventFilteringInfoPtr filter) { // Note that |listeners_| can be modified during handling. std::vector<v8::Local<v8::Function>> listeners = - listeners_->GetListeners(filter, context); + listeners_->GetListeners(std::move(filter), context); JSRunner* js_runner = JSRunner::Get(context); v8::Isolate* isolate = context->GetIsolate(); @@ -221,7 +223,7 @@ void EventEmitter::DispatchAsync(v8::Local<v8::Context> context, std::vector<v8::Local<v8::Value>>* args, - const EventFilteringInfo* filter, + mojom::EventFilteringInfoPtr filter, JSRunner::ResultCallback callback) { v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope handle_scope(isolate); @@ -243,7 +245,7 @@ int filter_id = kInvalidFilterId; if (filter) { filter_id = next_filter_id_++; - pending_filters_.emplace(filter_id, *filter); + pending_filters_[filter_id] = std::move(filter); } v8::Local<v8::Array> args_array = v8::Array::New(isolate, args->size()); @@ -290,7 +292,7 @@ data->Get(context, gin::StringToSymbol(isolate, kFilterKey)) .ToLocalChecked(); int filter_id = filter_id_value.As<v8::Int32>()->Value(); - absl::optional<EventFilteringInfo> filter; + mojom::EventFilteringInfoPtr filter; if (filter_id != kInvalidFilterId) { auto filter_iter = emitter->pending_filters_.find(filter_id); DCHECK(filter_iter != emitter->pending_filters_.end()); @@ -311,8 +313,8 @@ // We know that dispatching synchronously should be safe because this function // was triggered by JS execution. - info.GetReturnValue().Set(emitter->DispatchSync( - context, &arguments, filter ? &filter.value() : nullptr)); + info.GetReturnValue().Set( + emitter->DispatchSync(context, &arguments, std::move(filter))); } } // namespace extensions
diff --git a/extensions/renderer/bindings/event_emitter.h b/extensions/renderer/bindings/event_emitter.h index 1c1742a..ee65780a 100644 --- a/extensions/renderer/bindings/event_emitter.h +++ b/extensions/renderer/bindings/event_emitter.h
@@ -8,7 +8,7 @@ #include <map> #include <vector> -#include "extensions/common/event_filtering_info.h" +#include "extensions/common/mojom/event_dispatcher.mojom-forward.h" #include "extensions/renderer/bindings/js_runner.h" #include "gin/wrappable.h" #include "v8/include/v8.h" @@ -47,7 +47,7 @@ // invalidated after this! void Fire(v8::Local<v8::Context> context, std::vector<v8::Local<v8::Value>>* args, - const EventFilteringInfo* filter, + mojom::EventFilteringInfoPtr filter, JSRunner::ResultCallback callback); // Fires the event to any listeners synchronously, and returns the result. @@ -57,7 +57,7 @@ // invalidated after this! v8::Local<v8::Value> FireSync(v8::Local<v8::Context> context, std::vector<v8::Local<v8::Value>>* args, - const EventFilteringInfo* filter); + mojom::EventFilteringInfoPtr filter); // Removes all listeners and marks this object as invalid so that no more // are added. @@ -78,12 +78,12 @@ // Dispatches an event synchronously to listeners, returning the result. v8::Local<v8::Value> DispatchSync(v8::Local<v8::Context> context, std::vector<v8::Local<v8::Value>>* args, - const EventFilteringInfo* filter); + mojom::EventFilteringInfoPtr filter); // Dispatches an event asynchronously to listeners. void DispatchAsync(v8::Local<v8::Context> context, std::vector<v8::Local<v8::Value>>* args, - const EventFilteringInfo* filter, + mojom::EventFilteringInfoPtr filter, JSRunner::ResultCallback callback); static void DispatchAsyncHelper( const v8::FunctionCallbackInfo<v8::Value>& info); @@ -106,7 +106,7 @@ static constexpr int kInvalidFilterId = -1; // The map of EventFilteringInfos for events that are pending dispatch (since // JS is suspended). - std::map<int, EventFilteringInfo> pending_filters_; + std::map<int, mojom::EventFilteringInfoPtr> pending_filters_; }; } // namespace extensions
diff --git a/extensions/renderer/bindings/event_emitter_unittest.cc b/extensions/renderer/bindings/event_emitter_unittest.cc index 6374834..e7cfa365 100644 --- a/extensions/renderer/bindings/event_emitter_unittest.cc +++ b/extensions/renderer/bindings/event_emitter_unittest.cc
@@ -8,6 +8,7 @@ #include "base/callback_helpers.h" #include "base/cxx17_backports.h" #include "base/values.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/bindings/api_binding_test.h" #include "extensions/renderer/bindings/api_binding_test_util.h" #include "extensions/renderer/bindings/api_event_listeners.h"
diff --git a/extensions/renderer/bindings/listener_tracker.cc b/extensions/renderer/bindings/listener_tracker.cc index 9a18b8ed..197afff 100644 --- a/extensions/renderer/bindings/listener_tracker.cc +++ b/extensions/renderer/bindings/listener_tracker.cc
@@ -4,7 +4,9 @@ #include "extensions/renderer/bindings/listener_tracker.h" +#include "base/check.h" #include "base/values.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/common/value_counter.h" namespace extensions { @@ -80,9 +82,10 @@ std::set<int> ListenerTracker::GetMatchingFilteredListeners( const std::string& event_name, - const EventFilteringInfo& filter, + mojom::EventFilteringInfoPtr filter, int routing_id) { - return event_filter_.MatchEvent(event_name, filter, routing_id); + DCHECK(!filter.is_null()); + return event_filter_.MatchEvent(event_name, *filter, routing_id); } } // namespace extensions
diff --git a/extensions/renderer/bindings/listener_tracker.h b/extensions/renderer/bindings/listener_tracker.h index 0d34750..f6b2384 100644 --- a/extensions/renderer/bindings/listener_tracker.h +++ b/extensions/renderer/bindings/listener_tracker.h
@@ -11,6 +11,7 @@ #include <utility> #include "extensions/common/event_filter.h" +#include "extensions/common/mojom/event_dispatcher.mojom-forward.h" namespace base { class DictionaryValue; @@ -19,7 +20,6 @@ namespace extensions { class EventFilter; class ValueCounter; -struct EventFilteringInfo; // A class to track all event listeners across multiple v8::Contexts. Each // context has a "context owner", which may be the same across multiple @@ -84,9 +84,10 @@ // Returns a set of filter IDs to that correspond to the given |event_name|, // |filter|, and |routing_id|. - std::set<int> GetMatchingFilteredListeners(const std::string& event_name, - const EventFilteringInfo& filter, - int routing_id); + std::set<int> GetMatchingFilteredListeners( + const std::string& event_name, + mojom::EventFilteringInfoPtr filter, + int routing_id); EventFilter* event_filter_for_testing() { return &event_filter_; }
diff --git a/extensions/renderer/bindings/listener_tracker_unittest.cc b/extensions/renderer/bindings/listener_tracker_unittest.cc index af2fb43..9801791 100644 --- a/extensions/renderer/bindings/listener_tracker_unittest.cc +++ b/extensions/renderer/bindings/listener_tracker_unittest.cc
@@ -5,8 +5,10 @@ #include "extensions/renderer/bindings/listener_tracker.h" #include <memory> +#include <utility> #include "base/values.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/bindings/api_binding_test_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -194,10 +196,11 @@ kOwner2, kEvent1, filter3->CreateDeepCopy(), kRoutingId); EXPECT_NE(-1, filter_id3); - EventFilteringInfo filtering_info; - filtering_info.url = GURL("https://example.com/foo"); - std::set<int> matching_filters = - tracker.GetMatchingFilteredListeners(kEvent1, filtering_info, kRoutingId); + mojom::EventFilteringInfoPtr filtering_info = + mojom::EventFilteringInfo::New(); + filtering_info->url = GURL("https://example.com/foo"); + std::set<int> matching_filters = tracker.GetMatchingFilteredListeners( + kEvent1, std::move(filtering_info), kRoutingId); EXPECT_THAT(matching_filters, testing::UnorderedElementsAre(filter_id1, filter_id3)); }
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 2bf9579..25bb8bb9 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -33,6 +33,7 @@ #include "extensions/common/api/messaging/message.h" #include "extensions/common/constants.h" #include "extensions/common/cors_util.h" +#include "extensions/common/event_filtering_info_type_converters.h" #include "extensions/common/extension.h" #include "extensions/common/extension_api.h" #include "extensions/common/extension_features.h" @@ -760,16 +761,17 @@ // |frame_helper| and |render_frame| might be dead by now. } -void Dispatcher::DispatchEvent(const std::string& extension_id, - const std::string& event_name, - const base::ListValue& event_args, - const EventFilteringInfo* filtering_info) const { +void Dispatcher::DispatchEvent( + const std::string& extension_id, + const std::string& event_name, + const base::ListValue& event_args, + mojom::EventFilteringInfoPtr filtering_info) const { script_context_set_->ForEach( extension_id, nullptr, base::BindRepeating( &NativeExtensionBindingsSystem::DispatchEventInContext, base::Unretained(bindings_system_.get()), event_name, &event_args, - filtering_info)); + base::OwnedRef(std::move(filtering_info)))); } void Dispatcher::InvokeModuleSystemMethod(content::RenderFrame* render_frame, @@ -1307,7 +1309,7 @@ } DispatchEvent(params.extension_id, params.event_name, event_args, - ¶ms.filtering_info); + mojom::EventFilteringInfo::From(params.filtering_info)); if (background_frame) { // Tell the browser process when an event has been dispatched with a lazy
diff --git a/extensions/renderer/dispatcher.h b/extensions/renderer/dispatcher.h index bcc54c9..35246a6 100644 --- a/extensions/renderer/dispatcher.h +++ b/extensions/renderer/dispatcher.h
@@ -67,7 +67,6 @@ class ScriptContextSetIterable; class ScriptInjectionManager; class WorkerScriptContextSet; -struct EventFilteringInfo; struct Message; struct PortId; @@ -170,7 +169,7 @@ void DispatchEvent(const std::string& extension_id, const std::string& event_name, const base::ListValue& event_args, - const EventFilteringInfo* filtering_info) const; + mojom::EventFilteringInfoPtr filtering_info) const; // Shared implementation of the various MessageInvoke IPCs. void InvokeModuleSystemMethod(content::RenderFrame* render_frame,
diff --git a/extensions/renderer/gin_port.cc b/extensions/renderer/gin_port.cc index bf9aa0a..29c4b0d3 100644 --- a/extensions/renderer/gin_port.cc +++ b/extensions/renderer/gin_port.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "extensions/common/api/messaging/message.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/bindings/api_binding_util.h" #include "extensions/renderer/bindings/api_event_handler.h" #include "extensions/renderer/bindings/event_emitter.h"
diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc index 112a7e4..153eda32 100644 --- a/extensions/renderer/native_extension_bindings_system.cc +++ b/extensions/renderer/native_extension_bindings_system.cc
@@ -4,6 +4,8 @@ #include "extensions/renderer/native_extension_bindings_system.h" +#include <utility> + #include "base/bind.h" #include "base/callback.h" #include "base/command_line.h" @@ -13,7 +15,6 @@ #include "components/crx_file/id_util.h" #include "content/public/common/content_switches.h" #include "extensions/common/constants.h" -#include "extensions/common/event_filtering_info.h" #include "extensions/common/extension_api.h" #include "extensions/common/extension_messages.h" #include "extensions/common/features/feature.h" @@ -21,6 +22,7 @@ #include "extensions/common/manifest_constants.h" #include "extensions/common/manifest_handlers/content_capabilities_handler.h" #include "extensions/common/manifest_handlers/externally_connectable.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/common/mojom/frame.mojom.h" #include "extensions/renderer/api_activity_logger.h" #include "extensions/renderer/bindings/api_binding_bridge.h" @@ -571,12 +573,12 @@ void NativeExtensionBindingsSystem::DispatchEventInContext( const std::string& event_name, const base::ListValue* event_args, - const EventFilteringInfo* filtering_info, + const mojom::EventFilteringInfoPtr& filtering_info, ScriptContext* context) { v8::HandleScope handle_scope(context->isolate()); v8::Context::Scope context_scope(context->v8_context()); api_system_.FireEventInContext(event_name, context->v8_context(), *event_args, - filtering_info); + filtering_info.Clone()); } bool NativeExtensionBindingsSystem::HasEventListenerInContext(
diff --git a/extensions/renderer/native_extension_bindings_system.h b/extensions/renderer/native_extension_bindings_system.h index 0b4503b..c7b68b4 100644 --- a/extensions/renderer/native_extension_bindings_system.h +++ b/extensions/renderer/native_extension_bindings_system.h
@@ -9,6 +9,7 @@ #include <string> #include "base/memory/weak_ptr.h" +#include "extensions/common/mojom/event_dispatcher.mojom-forward.h" #include "extensions/renderer/bindings/api_binding_types.h" #include "extensions/renderer/bindings/api_bindings_system.h" #include "extensions/renderer/bindings/event_emitter.h" @@ -56,10 +57,11 @@ // Dispatches an event with the given |name|, |event_args|, and // |filtering_info| in the given |context|. - void DispatchEventInContext(const std::string& event_name, - const base::ListValue* event_args, - const EventFilteringInfo* filtering_info, - ScriptContext* context); + void DispatchEventInContext( + const std::string& event_name, + const base::ListValue* event_args, + const mojom::EventFilteringInfoPtr& filtering_info, + ScriptContext* context); // Returns true if there is a listener for the given |event_name| in the // associated |context|.
diff --git a/extensions/renderer/one_time_message_handler.cc b/extensions/renderer/one_time_message_handler.cc index 0ca96b3..bb7d145 100644 --- a/extensions/renderer/one_time_message_handler.cc +++ b/extensions/renderer/one_time_message_handler.cc
@@ -13,6 +13,7 @@ #include "content/public/renderer/render_frame.h" #include "extensions/common/api/messaging/message.h" #include "extensions/common/api/messaging/port_id.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/bindings/api_binding_types.h" #include "extensions/renderer/bindings/api_binding_util.h" #include "extensions/renderer/bindings/api_bindings_system.h"
diff --git a/extensions/renderer/programmatic_script_injector.cc b/extensions/renderer/programmatic_script_injector.cc index 172f764..1fda46da 100644 --- a/extensions/renderer/programmatic_script_injector.cc +++ b/extensions/renderer/programmatic_script_injector.cc
@@ -65,6 +65,11 @@ return params_->injection->get_js()->wants_result; } +bool ProgrammaticScriptInjector::ShouldWaitForPromise() const { + DCHECK(params_->injection->is_js()); + return params_->injection->get_js()->wait_for_promise; +} + bool ProgrammaticScriptInjector::ShouldInjectJs( mojom::RunLocation run_location, const std::set<std::string>& executing_scripts) const {
diff --git a/extensions/renderer/programmatic_script_injector.h b/extensions/renderer/programmatic_script_injector.h index 1683e670..761c8b62 100644 --- a/extensions/renderer/programmatic_script_injector.h +++ b/extensions/renderer/programmatic_script_injector.h
@@ -39,6 +39,7 @@ mojom::CSSOrigin GetCssOrigin() const override; mojom::CSSInjection::Operation GetCSSInjectionOperation() const override; bool ExpectsResults() const override; + bool ShouldWaitForPromise() const override; bool ShouldInjectJs( mojom::RunLocation run_location, const std::set<std::string>& executing_scripts) const override;
diff --git a/extensions/renderer/script_injection.cc b/extensions/renderer/script_injection.cc index c5cf8176..12ab3e2 100644 --- a/extensions/renderer/script_injection.cc +++ b/extensions/renderer/script_injection.cc
@@ -360,10 +360,13 @@ } else { DCHECK_EQ(mojom::ExecutionWorld::kMain, execution_world); } + auto promise_behavior = + injector_->ShouldWaitForPromise() + ? blink::WebLocalFrame::PromiseBehavior::kAwait + : blink::WebLocalFrame::PromiseBehavior::kDontWait; render_frame_->GetWebFrame()->RequestExecuteScript( world_id, sources, is_user_gesture, execution_option, callback.release(), - blink::BackForwardCacheAware::kPossiblyDisallow, - blink::WebLocalFrame::PromiseBehavior::kDontWait); + blink::BackForwardCacheAware::kPossiblyDisallow, promise_behavior); } void ScriptInjection::OnJsInjectionCompleted(
diff --git a/extensions/renderer/script_injector.h b/extensions/renderer/script_injector.h index e90be5b8..e7c6d85 100644 --- a/extensions/renderer/script_injector.h +++ b/extensions/renderer/script_injector.h
@@ -66,6 +66,9 @@ // Returns true if the script expects results. virtual bool ExpectsResults() const = 0; + // Whether to wait for a promise result to resolve. + virtual bool ShouldWaitForPromise() const = 0; + // Returns true if the script should inject JS source at the given // |run_location|. virtual bool ShouldInjectJs(
diff --git a/extensions/renderer/storage_area_unittest.cc b/extensions/renderer/storage_area_unittest.cc index 1b05feb5..9cae268 100644 --- a/extensions/renderer/storage_area_unittest.cc +++ b/extensions/renderer/storage_area_unittest.cc
@@ -10,6 +10,7 @@ #include "components/version_info/channel.h" #include "extensions/common/extension_builder.h" #include "extensions/common/features/feature_channel.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/common/mojom/frame.mojom.h" #include "extensions/renderer/bindings/api_binding_test_util.h" #include "extensions/renderer/bindings/api_binding_util.h"
diff --git a/extensions/renderer/user_script_injector.cc b/extensions/renderer/user_script_injector.cc index 3c013c6..6a8b6d8 100644 --- a/extensions/renderer/user_script_injector.cc +++ b/extensions/renderer/user_script_injector.cc
@@ -150,6 +150,10 @@ return false; } +bool UserScriptInjector::ShouldWaitForPromise() const { + return false; +} + mojom::CSSOrigin UserScriptInjector::GetCssOrigin() const { return mojom::CSSOrigin::kAuthor; }
diff --git a/extensions/renderer/user_script_injector.h b/extensions/renderer/user_script_injector.h index 379d52c3..5509e5b7 100644 --- a/extensions/renderer/user_script_injector.h +++ b/extensions/renderer/user_script_injector.h
@@ -50,6 +50,7 @@ mojom::CSSOrigin GetCssOrigin() const override; mojom::CSSInjection::Operation GetCSSInjectionOperation() const override; bool ExpectsResults() const override; + bool ShouldWaitForPromise() const override; bool ShouldInjectJs( mojom::RunLocation run_location, const std::set<std::string>& executing_scripts) const override;
diff --git a/extensions/renderer/worker_thread_dispatcher.cc b/extensions/renderer/worker_thread_dispatcher.cc index 739a1c5..3486329 100644 --- a/extensions/renderer/worker_thread_dispatcher.cc +++ b/extensions/renderer/worker_thread_dispatcher.cc
@@ -16,8 +16,10 @@ #include "content/public/renderer/render_thread.h" #include "content/public/renderer/worker_thread.h" #include "extensions/common/constants.h" +#include "extensions/common/event_filtering_info_type_converters.h" #include "extensions/common/extension_features.h" #include "extensions/common/extension_messages.h" +#include "extensions/common/mojom/event_dispatcher.mojom.h" #include "extensions/renderer/dispatcher.h" #include "extensions/renderer/extension_interaction_provider.h" #include "extensions/renderer/extensions_renderer_client.h" @@ -367,8 +369,10 @@ ExtensionInteractionProvider::Scope::ForWorker( script_context->v8_context()); } + mojom::EventFilteringInfoPtr filtering_info = + mojom::EventFilteringInfo::From(params.filtering_info); data->bindings_system()->DispatchEventInContext( - params.event_name, &event_args, ¶ms.filtering_info, data->context()); + params.event_name, &event_args, filtering_info, data->context()); const int worker_thread_id = content::WorkerThread::GetCurrentId(); Send(new ExtensionHostMsg_EventAckWorker(data->context()->GetExtensionID(), data->service_worker_version_id(),
diff --git a/gpu/config/gpu_blocklist.cc b/gpu/config/gpu_blocklist.cc index 31683b6..3b219862 100644 --- a/gpu/config/gpu_blocklist.cc +++ b/gpu/config/gpu_blocklist.cc
@@ -31,6 +31,8 @@ GPU_FEATURE_TYPE_ACCELERATED_WEBGL); list->AddSupportedFeature("accelerated_video_decode", GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE); + list->AddSupportedFeature("accelerated_video_encode", + GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE); list->AddSupportedFeature("gpu_rasterization", GPU_FEATURE_TYPE_GPU_RASTERIZATION); list->AddSupportedFeature("accelerated_webgl2",
diff --git a/gpu/config/gpu_blocklist_unittest.cc b/gpu/config/gpu_blocklist_unittest.cc index 0be1f0f..5c325ee 100644 --- a/gpu/config/gpu_blocklist_unittest.cc +++ b/gpu/config/gpu_blocklist_unittest.cc
@@ -90,6 +90,9 @@ GPU_BLOCKLIST_FEATURE_TEST(AcceleratedVideoDecode, GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE) +GPU_BLOCKLIST_FEATURE_TEST(AcceleratedVideoEncode, + GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE) + GPU_BLOCKLIST_FEATURE_TEST(GpuRasterization, GPU_FEATURE_TYPE_GPU_RASTERIZATION) GPU_BLOCKLIST_FEATURE_TEST(OOPRasterization, GPU_FEATURE_TYPE_OOP_RASTERIZATION)
diff --git a/gpu/config/gpu_feature_type.h b/gpu/config/gpu_feature_type.h index f9b4566..a68a550 100644 --- a/gpu/config/gpu_feature_type.h +++ b/gpu/config/gpu_feature_type.h
@@ -14,6 +14,7 @@ GPU_FEATURE_TYPE_ACCELERATED_2D_CANVAS = 0, GPU_FEATURE_TYPE_ACCELERATED_WEBGL, GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE, + GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE, GPU_FEATURE_TYPE_GPU_RASTERIZATION, GPU_FEATURE_TYPE_ACCELERATED_WEBGL2, GPU_FEATURE_TYPE_OOP_RASTERIZATION,
diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc index 7326e1b..a365ef63 100644 --- a/gpu/config/gpu_util.cc +++ b/gpu/config/gpu_util.cc
@@ -296,6 +296,19 @@ return kGpuFeatureStatusEnabled; } +GpuFeatureStatus GetAcceleratedVideoEncodeFeatureStatus( + const std::set<int>& blocklisted_features, + bool use_swift_shader) { + if (use_swift_shader) { + // This is for testing only. Chrome should exercise the GPU accelerated + // path on top of SwiftShader driver. + return kGpuFeatureStatusEnabled; + } + if (blocklisted_features.count(GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE)) + return kGpuFeatureStatusBlocklisted; + return kGpuFeatureStatusEnabled; +} + GpuFeatureStatus GetGLFeatureStatus(const std::set<int>& blocklisted_features, bool use_swift_shader) { if (use_swift_shader) { @@ -426,6 +439,8 @@ kGpuFeatureStatusSoftware; gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] = kGpuFeatureStatusDisabled; + gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE] = + kGpuFeatureStatusDisabled; gpu_feature_info.status_values[GPU_FEATURE_TYPE_GPU_RASTERIZATION] = kGpuFeatureStatusDisabled; gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_WEBGL2] = @@ -458,6 +473,8 @@ kGpuFeatureStatusDisabled; gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] = kGpuFeatureStatusDisabled; + gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE] = + kGpuFeatureStatusDisabled; gpu_feature_info.status_values[GPU_FEATURE_TYPE_GPU_RASTERIZATION] = kGpuFeatureStatusDisabled; gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_WEBGL2] = @@ -490,6 +507,8 @@ kGpuFeatureStatusSoftware; gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] = kGpuFeatureStatusDisabled; + gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE] = + kGpuFeatureStatusDisabled; gpu_feature_info.status_values[GPU_FEATURE_TYPE_GPU_RASTERIZATION] = kGpuFeatureStatusDisabled; gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_WEBGL2] = @@ -579,6 +598,9 @@ gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_VIDEO_DECODE] = GetAcceleratedVideoDecodeFeatureStatus(blocklisted_features, use_swift_shader); + gpu_feature_info.status_values[GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE] = + GetAcceleratedVideoEncodeFeatureStatus(blocklisted_features, + use_swift_shader); gpu_feature_info.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] = GetOopRasterizationFeatureStatus(blocklisted_features, *command_line, gpu_preferences, gpu_info);
diff --git a/gpu/ipc/service/gpu_init.cc b/gpu/ipc/service/gpu_init.cc index fa23e58..4c628d7 100644 --- a/gpu/ipc/service/gpu_init.cc +++ b/gpu/ipc/service/gpu_init.cc
@@ -606,6 +606,12 @@ gpu_preferences_.disable_accelerated_video_decode = true; } + if (kGpuFeatureStatusEnabled != + gpu_feature_info_ + .status_values[GPU_FEATURE_TYPE_ACCELERATED_VIDEO_ENCODE]) { + gpu_preferences_.disable_accelerated_video_encode = true; + } + base::TimeDelta initialize_one_off_time = base::TimeTicks::Now() - before_initialize_one_off; UMA_HISTOGRAM_MEDIUM_TIMES("GPU.InitializeOneOffMediumTime",
diff --git a/infra/config/chops-weetbix.cfg b/infra/config/chops-weetbix.cfg index 65dd633..a6c1cea 100644 --- a/infra/config/chops-weetbix.cfg +++ b/infra/config/chops-weetbix.cfg
@@ -44,3 +44,51 @@ } priority_hysteresis_percent: 50 } + +realms { + name: "ci" + test_variant_analysis { + update_test_variant_task { + update_test_variant_task_interval { + seconds: 3600 # 1 hour + } + test_variant_status_update_duration { + seconds: 86400 # 24 hours + } + } + bq_exports { + table { + cloud_project: "chrome-flakiness" + dataset: "weetbix" + table: "ci_flaky_test_variants" + } + predicate { + status: FLAKY + } + } + } +} + +realms { + name: "try" + test_variant_analysis { + update_test_variant_task { + update_test_variant_task_interval { + seconds: 3600 # 1 hour + } + test_variant_status_update_duration { + seconds: 86400 # 24 hours + } + } + bq_exports { + table { + cloud_project: "chrome-flakiness" + dataset: "weetbix" + table: "try_flaky_test_variants" + } + predicate { + status: FLAKY + } + } + } +}
diff --git a/infra/config/generated/luci/chops-weetbix.cfg b/infra/config/generated/luci/chops-weetbix.cfg index 65dd633..a6c1cea 100644 --- a/infra/config/generated/luci/chops-weetbix.cfg +++ b/infra/config/generated/luci/chops-weetbix.cfg
@@ -44,3 +44,51 @@ } priority_hysteresis_percent: 50 } + +realms { + name: "ci" + test_variant_analysis { + update_test_variant_task { + update_test_variant_task_interval { + seconds: 3600 # 1 hour + } + test_variant_status_update_duration { + seconds: 86400 # 24 hours + } + } + bq_exports { + table { + cloud_project: "chrome-flakiness" + dataset: "weetbix" + table: "ci_flaky_test_variants" + } + predicate { + status: FLAKY + } + } + } +} + +realms { + name: "try" + test_variant_analysis { + update_test_variant_task { + update_test_variant_task_interval { + seconds: 3600 # 1 hour + } + test_variant_status_update_duration { + seconds: 86400 # 24 hours + } + } + bq_exports { + table { + cloud_project: "chrome-flakiness" + dataset: "weetbix" + table: "try_flaky_test_variants" + } + predicate { + status: FLAKY + } + } + } +}
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index 9ad9693b..7b791ce 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -66018,6 +66018,10 @@ value: 100 } experiments { + key: "luci.recipes.use_python3" + value: 100 + } + experiments { key: "luci.use_realms" value: 100 }
diff --git a/infra/config/recipes.star b/infra/config/recipes.star index 6c6bc80..2f8222b 100644 --- a/infra/config/recipes.star +++ b/infra/config/recipes.star
@@ -7,7 +7,7 @@ _RECIPE_NAME_PREFIX = "recipe:" def _recipe_for_package(cipd_package): - def recipe(*, name, cipd_version = None, recipe = None, bootstrappable = False): + def recipe(*, name, cipd_version = None, recipe = None, use_python3 = False, bootstrappable = False): """Declare a recipe for the given package. A wrapper around luci.recipe with a fixed cipd_package and some @@ -47,6 +47,7 @@ cipd_version = cipd_version, recipe = recipe, use_bbagent = True, + use_python3 = use_python3, ) if bootstrappable: @@ -206,6 +207,7 @@ build_recipe( name = "recipe:tricium_clang_tidy_wrapper", + use_python3 = True, ) build_recipe(
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index 48cb2ad..b888245 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -1269,7 +1269,6 @@ name = "linux-clang-tidy-rel", executable = "recipe:tricium_clang_tidy_wrapper", goma_jobs = goma.jobs.J150, - experiments = {"luci.recipes.use_python3": 100}, ) try_.chromium_linux_builder(
diff --git a/ios/chrome/app/strings/resources/ios_strings_be.xtb b/ios/chrome/app/strings/resources/ios_strings_be.xtb index 1c732bc..e415360b 100644 --- a/ios/chrome/app/strings/resources/ios_strings_be.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_be.xtb
@@ -107,6 +107,7 @@ <translation id="1894205589103145703">Нешта пайшло не так падчас уваходу.</translation> <translation id="1911619930368729126">Запампаваць на Google Дыск</translation> <translation id="1923342640370224680">За апошнюю гадзіну</translation> +<translation id="1930989359703290198">Палітыка вашай арганізацыі дазваляе ўваходзіць у сістэмы, выкарыстоўваючы толькі пэўныя ўліковыя запісы. Уліковыя запісы, выкарыстоўваць якія не дазволена, не паказваюцца. <ph name="BEGIN_LINK" />Даведацца больш<ph name="END_LINK" /></translation> <translation id="1941314575388338491">Каб скапіраваць, націсніце двойчы.</translation> <translation id="1952172573699511566">Тэкст на вэб-сайтах будзе паказвацца на мове, выбранай вамі ў якасці прыярытэтнай, калі гэта магчыма.</translation> <translation id="1965935827552890526">Скончыце тое, што вы пачалі рабіць у іншым адкрытым акне Chrome.</translation> @@ -387,6 +388,8 @@ <translation id="4802417911091824046">Шыфраванне фразы-пароля не распаўсюджваецца на спосабы аплаты і адрасы з Google Pay. Каб змяніць гэту наладу, <ph name="BEGIN_LINK" />скіньце налады сінхранізацыі<ph name="END_LINK" /></translation> +<translation id="4803185665210547709">Пад кіраваннем вашай арганізацыі. +<ph name="BEGIN_LINK" />Даведацца больш<ph name="END_LINK" /></translation> <translation id="4805759445554688327">Несапраўдны нумар карты</translation> <translation id="4808744395915275922">Абнаўленні</translation> <translation id="4818522717893377262">Дадаць мову...</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_gl.xtb b/ios/chrome/app/strings/resources/ios_strings_gl.xtb index 3dc11f647..547c97c 100644 --- a/ios/chrome/app/strings/resources/ios_strings_gl.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_gl.xtb
@@ -107,6 +107,7 @@ <translation id="1894205589103145703">Produciuse un erro ao iniciar sesión.</translation> <translation id="1911619930368729126">Cargar en Google Drive</translation> <translation id="1923342640370224680">Última hora</translation> +<translation id="1930989359703290198">A túa organización só che permite iniciar sesión con certas contas. As contas que non están permitidas atópanse ocultas. <ph name="BEGIN_LINK" />Máis información<ph name="END_LINK" /></translation> <translation id="1941314575388338491">Toca dúas veces para copiar.</translation> <translation id="1952172573699511566">Os sitios web mostrarán o texto no teu idioma preferido, sempre que sexa posible.</translation> <translation id="1965935827552890526">Acaba o que estabas facendo na outra ventá de Chrome que tiñas aberta.</translation> @@ -387,6 +388,8 @@ <translation id="4802417911091824046">A encriptación mediante frase de acceso non inclúe métodos de pago nin enderezos de Google Pay. Para cambiar esta opción de configuración, deberás <ph name="BEGIN_LINK" />restablecer a sincronización<ph name="END_LINK" /></translation> +<translation id="4803185665210547709">Xestionado pola túa organización. +<ph name="BEGIN_LINK" />Máis información<ph name="END_LINK" /></translation> <translation id="4805759445554688327">O número de tarxeta non é válido</translation> <translation id="4808744395915275922">Actualizacións</translation> <translation id="4818522717893377262">Engadir idioma…</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_hr.xtb b/ios/chrome/app/strings/resources/ios_strings_hr.xtb index c5e8996..3321e50 100644 --- a/ios/chrome/app/strings/resources/ios_strings_hr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_hr.xtb
@@ -107,6 +107,7 @@ <translation id="1894205589103145703">Došlo je do pogreške tijekom prijave.</translation> <translation id="1911619930368729126">Prenesi na Google disk</translation> <translation id="1923342640370224680">Posljednji sat</translation> +<translation id="1930989359703290198">Vaša organizacija dopušta da se prijavite samo putem određenih računa. Nedopušteni su računi skriveni. <ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> <translation id="1941314575388338491">Dodirnite dvaput da biste kopirali.</translation> <translation id="1952172573699511566">Web-lokacije prikazivat će tekst na željenom jeziku kad god je to moguće.</translation> <translation id="1965935827552890526">Dovršite ono što ste radili u drugom otvorenom Chromeovom prozoru.</translation> @@ -387,6 +388,8 @@ <translation id="4802417911091824046">Enkripcija šifrom ne uključuje načine plaćanja i adrese s Google Paya. Da biste promijenili tu postavku, <ph name="BEGIN_LINK" />poništite sinkronizaciju<ph name="END_LINK" /></translation> +<translation id="4803185665210547709">Pod upravljanjem vaše organizacije. +<ph name="BEGIN_LINK" />Saznajte više<ph name="END_LINK" /></translation> <translation id="4805759445554688327">Nevažeći broj kartice</translation> <translation id="4808744395915275922">Ažuriranja</translation> <translation id="4818522717893377262">Dodaj jezik...</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_iw.xtb b/ios/chrome/app/strings/resources/ios_strings_iw.xtb index 8d0f245..86b7a8a594 100644 --- a/ios/chrome/app/strings/resources/ios_strings_iw.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_iw.xtb
@@ -107,6 +107,7 @@ <translation id="1894205589103145703">משהו השתבש במהלך הכניסה לחשבון.</translation> <translation id="1911619930368729126">העלאה אל Google Drive</translation> <translation id="1923342640370224680">בשעה האחרונה</translation> +<translation id="1930989359703290198">הארגון מאפשר לך להיכנס לדפדפן רק באמצעות חשבונות מסוימים. החשבונות שאינם מותרים מוסתרים. <ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /></translation> <translation id="1941314575388338491">כדי להעתיק, לוחצים פעמיים.</translation> <translation id="1952172573699511566">אתרים יציגו טקסט בשפה המועדפת שלך, כשזה אפשרי.</translation> <translation id="1965935827552890526">יש לסיים את הפעילות בחלון Chrome הפתוח הנוסף.</translation> @@ -386,6 +387,8 @@ <translation id="4802417911091824046">הצפנה באמצעות ביטוי סיסמה לא כוללת אמצעי תשלום וכתובות מ-Google Pay כדי לשנות את ההגדרה הזו צריך <ph name="BEGIN_LINK" />לאפס את הסנכרון<ph name="END_LINK" /></translation> +<translation id="4803185665210547709">מנוהל על-ידי הארגון שלך. +<ph name="BEGIN_LINK" />מידע נוסף<ph name="END_LINK" /></translation> <translation id="4805759445554688327">מספר כרטיס לא חוקי</translation> <translation id="4808744395915275922">עדכונים</translation> <translation id="4818522717893377262">הוספת שפה…</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_pl.xtb b/ios/chrome/app/strings/resources/ios_strings_pl.xtb index eca6ad3e..22a8f85 100644 --- a/ios/chrome/app/strings/resources/ios_strings_pl.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_pl.xtb
@@ -226,6 +226,7 @@ <translation id="3080525922482950719">Możesz zapisać strony, by przeczytać je później lub offline</translation> <translation id="3081338492074632642">Upewnij się, że zapisujesz hasło do witryny <ph name="WEBSITE" />.</translation> <translation id="3112556859945124369">Oznacz…</translation> +<translation id="3122484138405575719"><ph name="BEGIN_LINK" />Zobacz, co możesz synchronizować<ph name="END_LINK" /></translation> <translation id="3131206671572504478">Blokuj wszystkie</translation> <translation id="313283613037595347">Utwórz nową kartę incognito.</translation> <translation id="3153862085237805241">Zapisz kartę</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_sv.xtb b/ios/chrome/app/strings/resources/ios_strings_sv.xtb index e0d3b04d..568da0b 100644 --- a/ios/chrome/app/strings/resources/ios_strings_sv.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_sv.xtb
@@ -107,6 +107,7 @@ <translation id="1894205589103145703">Något gick fel vid inloggningen.</translation> <translation id="1911619930368729126">Ladda upp till Google Drive</translation> <translation id="1923342640370224680">Senaste timmen</translation> +<translation id="1930989359703290198">Organisationen tillåter endast inloggning med vissa konton. Konton som inte tillåts är dolda. <ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" /></translation> <translation id="1941314575388338491">Tryck snabbt två gånger om du vill kopiera informationen.</translation> <translation id="1952172573699511566">När det är möjligt visas text på webbplatser på önskat språk.</translation> <translation id="1965935827552890526">Gör klart det du höll på med i det andra öppna Chrome-fönstret.</translation> @@ -387,6 +388,8 @@ <translation id="4802417911091824046">Betalningsmetoder och adresser från Google Pay omfattas inte av kryptering med lösenfras. <ph name="BEGIN_LINK" />Återställ synkroniseringen<ph name="END_LINK" /> om du vill ändra den här inställningen.</translation> +<translation id="4803185665210547709">Hanteras av organisationen. +<ph name="BEGIN_LINK" />Läs mer<ph name="END_LINK" /></translation> <translation id="4805759445554688327">Ogiltigt kortnummer</translation> <translation id="4808744395915275922">Uppdateringar</translation> <translation id="4818522717893377262">Lägg till språk …</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_tr.xtb b/ios/chrome/app/strings/resources/ios_strings_tr.xtb index 35b3976..984bbc8 100644 --- a/ios/chrome/app/strings/resources/ios_strings_tr.xtb +++ b/ios/chrome/app/strings/resources/ios_strings_tr.xtb
@@ -107,6 +107,7 @@ <translation id="1894205589103145703">Oturum açılırken bir hata oluştu.</translation> <translation id="1911619930368729126">Google Drive'a yükle</translation> <translation id="1923342640370224680">Son Bir Saat</translation> +<translation id="1930989359703290198">Kuruluşunuz yalnızca belirli hesaplarla oturum açmanıza izin vermektedir. İzin verilmeyen hesaplar gösterilmez. <ph name="BEGIN_LINK" />Daha Fazla Bilgi<ph name="END_LINK" /></translation> <translation id="1941314575388338491">Kopyalamak için iki kez dokunun.</translation> <translation id="1952172573699511566">Web siteleri, mümkün olduğunda metni tercih ettiğiniz dilde gösterir.</translation> <translation id="1965935827552890526">Açık olan diğer Chrome pencerenizde yaptığınız işlemi tamamlayın.</translation> @@ -387,6 +388,8 @@ <translation id="4802417911091824046">Parolayla şifreleme, Google Pay'deki adresleri ve ödeme yöntemlerini kapsamaz. Bu ayarı değiştirmek için <ph name="BEGIN_LINK" />senkronizasyonu sıfırlayın<ph name="END_LINK" /></translation> +<translation id="4803185665210547709">Kuruluşunuz tarafından yönetiliyor. +<ph name="BEGIN_LINK" />Daha Fazla Bilgi<ph name="END_LINK" /></translation> <translation id="4805759445554688327">Geçersiz Kart Numarası</translation> <translation id="4808744395915275922">Güncellemeler</translation> <translation id="4818522717893377262">Dil Ekle...</translation>
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index ec01335d4..5772095b6 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -812,6 +812,11 @@ flag_descriptions::kEnableShortenedPasswordAutoFillInstructionDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kEnableShortenedPasswordAutoFillInstruction)}, + {"enable-password-manager-branding-update", + flag_descriptions::kIOSEnablePasswordManagerBrandingUpdateName, + flag_descriptions::kIOSEnablePasswordManagerBrandingUpdateDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE(kIOSEnablePasswordManagerBrandingUpdate)}, }; bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index fe54aee..110859d 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -245,6 +245,11 @@ "Enable folowing content from web and display Following feed on NTP based " "on websites that users followed."; +const char kIOSEnablePasswordManagerBrandingUpdateName[] = + "Enable new Google Password Manager branding"; +const char kIOSEnablePasswordManagerBrandingUpdateDescription[] = + "Updates icons, strings, and views for Google Password Manager."; + const char kExpandedTabStripName[] = "Enable expanded tabstrip"; const char kExpandedTabStripDescription[] = "Enables the new expanded tabstrip. Activated by swiping down the tabstrip"
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index cf718dc..8575dc3 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -218,6 +218,11 @@ extern const char kEnableWebChannelsName[]; extern const char kEnableWebChannelsDescription[]; +// Title and description for the flag to enable updated password manager +// branding. +extern const char kIOSEnablePasswordManagerBrandingUpdateName[]; +extern const char kIOSEnablePasswordManagerBrandingUpdateDescription[]; + // Title and description for the flag to enable an expanded tab strip. extern const char kExpandedTabStripName[]; extern const char kExpandedTabStripDescription[];
diff --git a/ios/chrome/browser/policy/BUILD.gn b/ios/chrome/browser/policy/BUILD.gn index 80e9e2be..fdcee3b 100644 --- a/ios/chrome/browser/policy/BUILD.gn +++ b/ios/chrome/browser/policy/BUILD.gn
@@ -37,6 +37,8 @@ "reporting/report_scheduler_ios.mm", "reporting/reporting_delegate_factory_ios.h", "reporting/reporting_delegate_factory_ios.mm", + "restrict_accounts_policy_handler.cc", + "restrict_accounts_policy_handler.h", "schema_registry_factory.h", "schema_registry_factory.mm", ] @@ -172,6 +174,7 @@ "reporting/profile_report_generator_ios_unittest.mm", "reporting/report_generator_ios_unittest.mm", "reporting/report_scheduler_ios_unittest.mm", + "restrict_accounts_policy_handler_unittest.cc", ] deps = [ ":policy",
diff --git a/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm b/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm index 4fa81871..2d5985dc 100644 --- a/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm +++ b/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm
@@ -33,6 +33,7 @@ #include "components/variations/service/variations_service.h" #include "ios/chrome/browser/policy/browser_signin_policy_handler.h" #include "ios/chrome/browser/policy/policy_features.h" +#import "ios/chrome/browser/policy/restrict_accounts_policy_handler.h" #include "ios/chrome/browser/pref_names.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -102,9 +103,6 @@ { policy::key::kUrlKeyedAnonymizedDataCollectionEnabled, unified_consent::prefs::kUrlKeyedAnonymizedDataCollectionEnabled, base::Value::Type::BOOLEAN }, - { policy::key::kRestrictAccountsToPatterns, - prefs::kRestrictAccountsToPatterns, - base::Value::Type::LIST }, }; // clang-format on @@ -140,6 +138,8 @@ std::make_unique<autofill::AutofillCreditCardPolicyHandler>()); handlers->AddHandler( std::make_unique<policy::BrowserSigninPolicyHandler>(chrome_schema)); + handlers->AddHandler( + std::make_unique<policy::RestrictAccountsPolicyHandler>(chrome_schema)); handlers->AddHandler(std::make_unique<policy::DefaultSearchPolicyHandler>()); handlers->AddHandler( std::make_unique<safe_browsing::SafeBrowsingPolicyHandler>());
diff --git a/ios/chrome/browser/policy/restrict_accounts_policy_handler.cc b/ios/chrome/browser/policy/restrict_accounts_policy_handler.cc new file mode 100644 index 0000000..741e4f9a --- /dev/null +++ b/ios/chrome/browser/policy/restrict_accounts_policy_handler.cc
@@ -0,0 +1,53 @@ +// 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. + +#import "ios/chrome/browser/policy/restrict_accounts_policy_handler.h" + +#include <memory> + +#include "base/values.h" +#include "components/policy/core/browser/policy_error_map.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/policy_constants.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/pref_value_map.h" +#include "components/signin/public/base/signin_pref_names.h" +#include "components/strings/grit/components_strings.h" +#import "ios/chrome/browser/signin/pattern_account_restriction.h" + +namespace policy { + +RestrictAccountsPolicyHandler::RestrictAccountsPolicyHandler( + Schema chrome_schema) + : SchemaValidatingPolicyHandler( + key::kRestrictAccountsToPatterns, + chrome_schema.GetKnownProperty(key::kRestrictAccountsToPatterns), + SCHEMA_ALLOW_UNKNOWN_AND_INVALID_LIST_ENTRY) {} + +RestrictAccountsPolicyHandler::~RestrictAccountsPolicyHandler() {} + +bool RestrictAccountsPolicyHandler::CheckPolicySettings( + const policy::PolicyMap& policies, + policy::PolicyErrorMap* errors) { + const base::Value* value = policies.GetValue(policy_name()); + if (!value) + return true; + if (!ArePatternsValid(value)) { + errors->AddError(policy_name(), IDS_POLICY_VALUE_FORMAT_ERROR); + } + if (!value->is_list()) + return false; + // Even if the pattern is not valid, the policy should be applied. + return true; +} + +void RestrictAccountsPolicyHandler::ApplyPolicySettings( + const PolicyMap& policies, + PrefValueMap* prefs) { + const base::Value* value = policies.GetValue(policy_name()); + if (value && value->is_list()) + prefs->SetValue(prefs::kRestrictAccountsToPatterns, value->Clone()); +} + +} // namespace policy
diff --git a/ios/chrome/browser/policy/restrict_accounts_policy_handler.h b/ios/chrome/browser/policy/restrict_accounts_policy_handler.h new file mode 100644 index 0000000..cf125df1 --- /dev/null +++ b/ios/chrome/browser/policy/restrict_accounts_policy_handler.h
@@ -0,0 +1,31 @@ +// 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 IOS_CHROME_BROWSER_POLICY_RESTRICT_ACCOUNTS_POLICY_HANDLER_H_ +#define IOS_CHROME_BROWSER_POLICY_RESTRICT_ACCOUNTS_POLICY_HANDLER_H_ + +#include "components/policy/core/browser/configuration_policy_handler.h" + +namespace policy { + +// Policy handler for the RestrictAccountsToPattern policy. +// TODO(crbug.com/1271066): Move this to components. +class RestrictAccountsPolicyHandler : public SchemaValidatingPolicyHandler { + public: + explicit RestrictAccountsPolicyHandler(Schema chrome_schema); + RestrictAccountsPolicyHandler(const RestrictAccountsPolicyHandler&) = delete; + RestrictAccountsPolicyHandler& operator=( + const RestrictAccountsPolicyHandler&) = delete; + ~RestrictAccountsPolicyHandler() override; + + // ConfigurationPolicyHandler methods: + bool CheckPolicySettings(const policy::PolicyMap& policies, + policy::PolicyErrorMap* errors) override; + void ApplyPolicySettings(const PolicyMap& policies, + PrefValueMap* prefs) override; +}; + +} // namespace policy + +#endif // IOS_CHROME_BROWSER_POLICY_RESTRICT_ACCOUNTS_POLICY_HANDLER_H_
diff --git a/ios/chrome/browser/policy/restrict_accounts_policy_handler_unittest.cc b/ios/chrome/browser/policy/restrict_accounts_policy_handler_unittest.cc new file mode 100644 index 0000000..bb1a3dbb --- /dev/null +++ b/ios/chrome/browser/policy/restrict_accounts_policy_handler_unittest.cc
@@ -0,0 +1,159 @@ +// 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 "ios/chrome/browser/policy/restrict_accounts_policy_handler.h" + +#include <memory> +#include <utility> + +#include "base/json/json_reader.h" +#include "base/memory/ptr_util.h" +#include "components/policy/core/browser/configuration_policy_pref_store.h" +#include "components/policy/core/browser/configuration_policy_pref_store_test.h" +#include "components/policy/core/browser/policy_error_map.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/core/common/policy_types.h" +#include "components/policy/core/common/schema.h" +#include "components/policy/policy_constants.h" +#include "components/signin/public/base/signin_pref_names.h" + +namespace policy { + +class RestrictAccountsPolicyHandlerTest + : public policy::ConfigurationPolicyPrefStoreTest { + void SetUp() override { + Schema chrome_schema = Schema::Wrap(policy::GetChromeSchemaData()); + handler_list_.AddHandler( + base::WrapUnique<policy::ConfigurationPolicyHandler>( + new RestrictAccountsPolicyHandler(chrome_schema))); + } + + protected: + // Returns a string of valid patterns. + std::string ValidPatternsString() { + return R"( + [ + "*@example.com", + "user@managedchrome.com" + ] + )"; + } + + // Returns a List of valid patterns. + base::Value ValidPatterns() { + base::ListValue value; + value.Append("*@example.com"); + value.Append("user@managedchrome.com"); + return value; + } + + // Returns a List of invalid patterns. + base::Value InvalidPatterns() { + base::ListValue value; + value.Append("*@example.com"); + value.Append("invalidPattern\\"); + value.Append("user@managedchrome.com"); + return value; + } +}; + +// Tests that the settings are correctly applied when the patterns are all +// valid. +TEST_F(RestrictAccountsPolicyHandlerTest, ApplyPolicySettings) { + EXPECT_FALSE(store_->GetValue(prefs::kRestrictAccountsToPatterns, nullptr)); + + PolicyMap policy; + policy.Set(key::kRestrictAccountsToPatterns, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, ValidPatterns(), nullptr); + UpdateProviderPolicy(policy); + const base::Value* pref_value = nullptr; + EXPECT_TRUE( + store_->GetValue(prefs::kRestrictAccountsToPatterns, &pref_value)); + ASSERT_TRUE(pref_value); + + absl::optional<base::Value> expected = ValidPatterns(); + EXPECT_EQ(expected, *pref_value); +} + +// Tests that the settings are correctly applied when a pattern is invalid. +TEST_F(RestrictAccountsPolicyHandlerTest, ApplyInvalidPolicySettings) { + EXPECT_FALSE(store_->GetValue(prefs::kRestrictAccountsToPatterns, nullptr)); + + PolicyMap policy; + policy.Set(key::kRestrictAccountsToPatterns, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, InvalidPatterns(), + nullptr); + UpdateProviderPolicy(policy); + const base::Value* pref_value = nullptr; + EXPECT_TRUE( + store_->GetValue(prefs::kRestrictAccountsToPatterns, &pref_value)); + ASSERT_TRUE(pref_value); + + // The setting is not filtering the invalid patterns out. + absl::optional<base::Value> expected = InvalidPatterns(); + EXPECT_EQ(expected, *pref_value); +} + +// Tests that the pref is not updated when the type of the policy wrong. +TEST_F(RestrictAccountsPolicyHandlerTest, WrongPolicyType) { + PolicyMap policy; + // The expected type is a list base::Value, but this policy sets it as an + // unparsed base::Value. Any type other than list should fail. + policy.Set(key::kRestrictAccountsToPatterns, policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, + base::Value(ValidPatternsString()), nullptr); + UpdateProviderPolicy(policy); + EXPECT_FALSE(store_->GetValue(prefs::kRestrictAccountsToPatterns, nullptr)); +} + +// Tests that the error handling is correct. +TEST_F(RestrictAccountsPolicyHandlerTest, CheckPolicySettings) { + Schema chrome_schema = Schema::Wrap(policy::GetChromeSchemaData()); + RestrictAccountsPolicyHandler handler(chrome_schema); + policy::PolicyErrorMap errors; + PolicyMap policy; + + // Valid patterns. + policy.Set(key::kRestrictAccountsToPatterns, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, ValidPatterns(), nullptr); + + EXPECT_TRUE(handler.CheckPolicySettings(policy, &errors)); + EXPECT_TRUE(errors.empty()); + + errors.Clear(); + + // Invalid patterns. + policy.Set(key::kRestrictAccountsToPatterns, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, InvalidPatterns(), + nullptr); + + EXPECT_TRUE(handler.CheckPolicySettings(policy, &errors)); + EXPECT_FALSE(errors.empty()); + EXPECT_FALSE(errors.GetErrors(key::kRestrictAccountsToPatterns).empty()); + + errors.Clear(); + + // Empty patterns. + policy.Set(key::kRestrictAccountsToPatterns, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::JSONReader::Read(""), + nullptr); + + EXPECT_TRUE(handler.CheckPolicySettings(policy, &errors)); + EXPECT_TRUE(errors.empty()); + + errors.Clear(); + + // Non-list patterns. + policy.Set(key::kRestrictAccountsToPatterns, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, + base::Value(ValidPatternsString()), nullptr); + + EXPECT_FALSE(handler.CheckPolicySettings(policy, &errors)); + EXPECT_FALSE(errors.empty()); + EXPECT_FALSE(errors.GetErrors(key::kRestrictAccountsToPatterns).empty()); + + errors.Clear(); +} + +} // namespace policy
diff --git a/ios/chrome/browser/signin/chrome_account_manager_service.mm b/ios/chrome/browser/signin/chrome_account_manager_service.mm index 6ee2de1..9a218787 100644 --- a/ios/chrome/browser/signin/chrome_account_manager_service.mm +++ b/ios/chrome/browser/signin/chrome_account_manager_service.mm
@@ -155,7 +155,6 @@ PrefService* pref_service) { auto maybe_restriction = PatternAccountRestrictionFromValue( pref_service->GetList(prefs::kRestrictAccountsToPatterns)); - CHECK(maybe_restriction.has_value()); return *std::move(maybe_restriction); }
diff --git a/ios/chrome/browser/signin/pattern_account_restriction.h b/ios/chrome/browser/signin/pattern_account_restriction.h index 4d509b25..6ee89e3 100644 --- a/ios/chrome/browser/signin/pattern_account_restriction.h +++ b/ios/chrome/browser/signin/pattern_account_restriction.h
@@ -5,8 +5,6 @@ #ifndef IOS_CHROME_BROWSER_SIGNIN_PATTERN_ACCOUNT_RESTRICTION_H_ #define IOS_CHROME_BROWSER_SIGNIN_PATTERN_ACCOUNT_RESTRICTION_H_ -#import <Foundation/Foundation.h> - #include <string> #include <vector> @@ -15,6 +13,7 @@ namespace base { class ListValue; +class Value; } // namespace base // This code is adapted from @@ -61,6 +60,10 @@ std::vector<Pattern> patterns_; }; +// Returns true if |value| holds a correct list of patterns. If one of the +// pattern is invalid, returns false. +bool ArePatternsValid(const base::Value* value); + // Creates a PatternAccountRestriction from |value| which needs to // be a list of strings. absl::optional<PatternAccountRestriction> PatternAccountRestrictionFromValue(
diff --git a/ios/chrome/browser/signin/pattern_account_restriction.mm b/ios/chrome/browser/signin/pattern_account_restriction.mm index d514f5b..5a57729 100644 --- a/ios/chrome/browser/signin/pattern_account_restriction.mm +++ b/ios/chrome/browser/signin/pattern_account_restriction.mm
@@ -77,6 +77,21 @@ return true; } +bool ArePatternsValid(const base::Value* value) { + // TODO(crbug.com/1271066): Check if we can use regex instead. + if (!value->is_list()) + return false; + + for (const base::Value& item : value->GetList()) { + if (!item.is_string()) + return false; + auto maybe_pattern = PatternFromString(item.GetString()); + if (!maybe_pattern) + return false; + } + return true; +} + absl::optional<PatternAccountRestriction> PatternAccountRestrictionFromValue( const base::ListValue* value) { DCHECK(value->is_list()); @@ -84,10 +99,10 @@ patterns.reserve(value->GetList().size()); for (const base::Value& item : value->GetList()) { if (!item.is_string()) - return absl::nullopt; + continue; auto maybe_pattern = PatternFromString(item.GetString()); if (!maybe_pattern) - return absl::nullopt; + continue; patterns.push_back(*std::move(maybe_pattern)); } return PatternAccountRestriction(std::move(patterns));
diff --git a/ios/chrome/browser/signin/pattern_account_restriction_unittest.mm b/ios/chrome/browser/signin/pattern_account_restriction_unittest.mm index 8def44d..b30d2d2 100644 --- a/ios/chrome/browser/signin/pattern_account_restriction_unittest.mm +++ b/ios/chrome/browser/signin/pattern_account_restriction_unittest.mm
@@ -28,9 +28,9 @@ value.Append("*google.com"); auto restriction = PatternAccountRestrictionFromValue(&value); - CHECK_EQ(restriction->IsAccountRestricted(email1), false); - CHECK_EQ(restriction->IsAccountRestricted(email2), false); - CHECK_EQ(restriction->IsAccountRestricted(email3), true); + EXPECT_EQ(restriction->IsAccountRestricted(email1), false); + EXPECT_EQ(restriction->IsAccountRestricted(email2), false); + EXPECT_EQ(restriction->IsAccountRestricted(email3), true); } // Tests that the PatternAccountRestriction does not filter emails when @@ -39,9 +39,22 @@ base::ListValue value; auto restriction = PatternAccountRestrictionFromValue(&value); - CHECK_EQ(restriction->IsAccountRestricted(email1), false); - CHECK_EQ(restriction->IsAccountRestricted(email2), false); - CHECK_EQ(restriction->IsAccountRestricted(email3), false); + EXPECT_EQ(restriction->IsAccountRestricted(email1), false); + EXPECT_EQ(restriction->IsAccountRestricted(email2), false); + EXPECT_EQ(restriction->IsAccountRestricted(email3), false); +} + +// Tests that the PatternAccountRestriction does not filter emails when the +// restriction is not correctly formatted. +TEST_F(PatternAccountRestrictionTest, FilterEmailsWithBadPattern) { + base::ListValue value; + value.Append("*gmail.com\\"); + value.Append("*google.com"); + auto restriction = PatternAccountRestrictionFromValue(&value); + + EXPECT_EQ(restriction->IsAccountRestricted(email1), true); + EXPECT_EQ(restriction->IsAccountRestricted(email2), false); + EXPECT_EQ(restriction->IsAccountRestricted(email3), true); } // Tests that the pattern created by PatternFromString(chunk) correctlty matches @@ -50,29 +63,56 @@ // characters, put a '\' in front of them. TEST_F(PatternAccountRestrictionTest, PatternMatchChunck) { auto pattern = PatternFromString("*gmail.com"); - CHECK_EQ(pattern->Match(email1), true); - CHECK_EQ(pattern->Match(email2), false); - CHECK_EQ(pattern->Match(email3), false); + EXPECT_EQ(pattern->Match(email1), true); + EXPECT_EQ(pattern->Match(email2), false); + EXPECT_EQ(pattern->Match(email3), false); pattern = PatternFromString("gmail.com"); - CHECK_EQ(pattern->Match(email1), false); - CHECK_EQ(pattern->Match(email2), false); - CHECK_EQ(pattern->Match(email3), false); + EXPECT_EQ(pattern->Match(email1), false); + EXPECT_EQ(pattern->Match(email2), false); + EXPECT_EQ(pattern->Match(email3), false); pattern = PatternFromString("foo*"); - CHECK_EQ(pattern->Match(email1), true); - CHECK_EQ(pattern->Match(email2), true); - CHECK_EQ(pattern->Match(email3), true); + EXPECT_EQ(pattern->Match(email1), true); + EXPECT_EQ(pattern->Match(email2), true); + EXPECT_EQ(pattern->Match(email3), true); // "foo\\*@gmail.com" is actually "foo\*@gmail.com". The escape character '\' // is doubled here because it's also an escape character for std::string. pattern = PatternFromString("foo\\*@gmail.com"); - CHECK_EQ(pattern->Match(email1), false); - CHECK_EQ(pattern->Match("foo*@gmail.com"), true); + EXPECT_EQ(pattern->Match(email1), false); + EXPECT_EQ(pattern->Match("foo*@gmail.com"), true); // "foo\\\\*" is "actually foo\\*". pattern = PatternFromString("foo\\\\*"); - CHECK_EQ(pattern->Match(email1), false); + EXPECT_EQ(pattern->Match(email1), false); // "foo\\@gmail.com" is actually "foo\@gmail.com". - CHECK_EQ(pattern->Match("foo\\@gmail.com"), true); + EXPECT_EQ(pattern->Match("foo\\@gmail.com"), true); +} + +// Tests that valid patterns are correctly identified. +TEST_F(PatternAccountRestrictionTest, ValidPattern) { + base::ListValue value; + value.Append("*gmail.com"); + value.Append("myemail@gmail.com"); + value.Append("myemail\\*@gmail.com"); + value.Append("\\\\google.com"); + + EXPECT_TRUE(ArePatternsValid(&value)); +} + +// Tests that invalid patterns are correctly identified. +TEST_F(PatternAccountRestrictionTest, InvalidPattern) { + base::ListValue value; + value.Append("*gmail.com\\"); + value.Append("*google.com"); + + EXPECT_FALSE(ArePatternsValid(&value)); +} + +// Tests that empty patterns are correctly identified. +TEST_F(PatternAccountRestrictionTest, EmptyPattern) { + base::ListValue value; + + EXPECT_TRUE(ArePatternsValid(&value)); }
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm index 8392332..f81a581c 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
@@ -176,6 +176,9 @@ - (void)shutdown { _searchEngineObserver.reset(); if (_webState && _webStateObserver) { + if (!IsSingleNtpEnabled()) { + [self saveContentOffsetForWebState:_webState]; + } _webState->RemoveObserver(_webStateObserver.get()); _webStateObserver.reset(); } @@ -200,12 +203,16 @@ - (void)setWebState:(web::WebState*)webState { if (_webState && _webStateObserver) { - [self saveContentOffsetForWebState:_webState]; + if (IsSingleNtpEnabled()) { + [self saveContentOffsetForWebState:_webState]; + } _webState->RemoveObserver(_webStateObserver.get()); } _webState = webState; if (_webState && _webStateObserver) { - [self setContentOffsetForWebState:webState]; + if (IsSingleNtpEnabled()) { + [self setContentOffsetForWebState:webState]; + } _webState->AddObserver(_webStateObserver.get()); } } @@ -552,6 +559,12 @@ // Save the NTP scroll offset into the last committed navigation item for the // before we navigate away. - (void)saveContentOffsetForWebState:(web::WebState*)webState { + if (!IsSingleNtpEnabled() && + webState->GetLastCommittedURL().DeprecatedGetOriginAsURL() != + kChromeUINewTabURL) { + return; + } + web::NavigationManager* manager = webState->GetNavigationManager(); web::NavigationItem* item = webState->GetLastCommittedURL() == kChromeUINewTabURL
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc index ce84ca01..65d84d5 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.cc +++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -40,6 +40,12 @@ "DefaultBrowserFullscreenPromoExperiment", base::FEATURE_DISABLED_BY_DEFAULT}; +// Feature flag that updates icons, strings, and views for Google Password +// Manager. +const base::Feature kIOSEnablePasswordManagerBrandingUpdate{ + "IOSEnablePasswordManagerBrandingUpdate", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kIOSNewOmniboxImplementation{ "kIOSNewOmniboxImplementation", 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 7a6c4cb9..07a6e85 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.h +++ b/ios/chrome/browser/ui/ui_feature_flags.h
@@ -49,6 +49,10 @@ // Feature flag that experiments with the default browser fullscreen promo UI. extern const base::Feature kDefaultBrowserFullscreenPromoExperiment; +// Feature flag that updates icons, strings, and views for Google Password +// Manager. +extern const base::Feature kIOSEnablePasswordManagerBrandingUpdate; + // Feature flag that swaps the omnibox textfield implementation. extern const base::Feature kIOSNewOmniboxImplementation;
diff --git a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_be.xtb b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_be.xtb index c55b1c6..d6dfefe 100644 --- a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_be.xtb +++ b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_be.xtb
@@ -9,6 +9,7 @@ <translation id="1706288056912586527">Паказаць пароль</translation> <translation id="1870148520156231997">Паказаць пароль</translation> <translation id="1977167321677356409">Пароль</translation> +<translation id="2286038806535735701">Каб адкрываць паведамленні хутчэй, скасуйце выбар звязка ключоў iCloud</translation> <translation id="2320166752086256636">Схаваць клавіятуру</translation> <translation id="2712586044587587728">Захаваныя ў браўзеры Chrome паролі можна будзе выкарыстоўваць у іншых праграмах. Выкарыстанне пароляў можна ў любы час выключыць у праграме "Налады".</translation> <translation id="2747003861858887689">Папярэдняе поле</translation> @@ -20,6 +21,7 @@ <translation id="4064278913989596727">Даведка</translation> <translation id="4241076354893135477">Няма пароляў Chrome</translation> <translation id="4452240207605337349">Не ўдалося захаваць пароль</translation> +<translation id="4818780572497527258">Зразумела</translation> <translation id="5118084770294029567">Усе паролі</translation> <translation id="5148402015874782921">Скасаваць</translation> <translation id="5366190986669335938">Атрымлівайце доступ да пароляў, захаваных у браўзеры Chrome, з усіх праграм.</translation> @@ -29,6 +31,7 @@ <translation id="6216401132953873625">Дадаць новы пароль</translation> <translation id="6539092367496845964">Нешта пайшло не так. Паўтарыце спробу пазней.</translation> <translation id="6657585470893396449">Пароль</translation> +<translation id="666236282349601348">Аўтазапаўненне ўключана</translation> <translation id="6710648923880003133">Прапанаваць надзейны пароль</translation> <translation id="6734440856654324363">Дадаць новы пароль</translation> <translation id="6867369562105931222">пароль</translation> @@ -36,6 +39,7 @@ <translation id="6994951856208641136">Прапанаваны пароль</translation> <translation id="7013045517548357694">Доступ да пароляў...</translation> <translation id="7021375594770280489">Даведацца больш</translation> +<translation id="7270843568750656178">Выкарыстоўвайце Chrome на вашай прыладзе для аўтазапаўнення захаванымі паролямі адпаведных палёў у іншых праграмах</translation> <translation id="7294706895582948780">Функцыя аўтазапаўнення для пароляў Chrome</translation> <translation id="7362314760212854110">Вы нядаўна выйшлі са свайго Уліковага запісу Google. Увайдзіце ў Chrome, каб паглядзець свае паролі.</translation> <translation id="7402321973924525978">Пароль будзе захаваны на гэтай прыладзе. Калі вы хочаце карыстацца паролямі на ўсіх сваіх прыладах, уключыце сінхранізацыю ў Chrome.</translation>
diff --git a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_et.xtb b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_et.xtb index 2902660..0c8dabdd 100644 --- a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_et.xtb +++ b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_et.xtb
@@ -9,6 +9,7 @@ <translation id="1706288056912586527">Kuva parool</translation> <translation id="1870148520156231997">Kuva parool</translation> <translation id="1977167321677356409">Parool</translation> +<translation id="2286038806535735701">Selleks et sõnumeid kiiremini saada, tühistage iCloudi võtmeahela valik</translation> <translation id="2320166752086256636">Peida klaviatuur</translation> <translation id="2712586044587587728">Teie Chrome'i paroole saab kasutada muudes rakendustes. Selle saab rakenduses Seaded alati välja lülitada.</translation> <translation id="2747003861858887689">Eelmine väli</translation> @@ -20,6 +21,7 @@ <translation id="4064278913989596727">Abi</translation> <translation id="4241076354893135477">Chrome'i paroole pole</translation> <translation id="4452240207605337349">Parooli salvestamine ebaõnnestus</translation> +<translation id="4818780572497527258">Selge</translation> <translation id="5118084770294029567">Kõik paroolid</translation> <translation id="5148402015874782921">Tühista</translation> <translation id="5366190986669335938">Pääsete mis tahes rakenduses juurde paroolidele, mille Chrome'is salvestate.</translation> @@ -29,6 +31,7 @@ <translation id="6216401132953873625">Uue parooli lisamine</translation> <translation id="6539092367496845964">Midagi läks valesti. Proovige hiljem uuesti.</translation> <translation id="6657585470893396449">Parool</translation> +<translation id="666236282349601348">Automaattäide on sees</translation> <translation id="6710648923880003133">Soovita tugevat parooli</translation> <translation id="6734440856654324363">Lisa uus parool</translation> <translation id="6867369562105931222">parool</translation> @@ -36,6 +39,7 @@ <translation id="6994951856208641136">Soovitatud parool</translation> <translation id="7013045517548357694">Juurdepääs paroolidele …</translation> <translation id="7021375594770280489">Juhised</translation> +<translation id="7270843568750656178">Kasutage Chrome'i, et oma salvestatud paroolid oma seadmes muudes rakendustes automaatselt sisestada</translation> <translation id="7294706895582948780">Chrome'i paroolide automaatne täitmine</translation> <translation id="7362314760212854110">Logisite hiljuti oma Google'i kontolt välja. Oma paroolide nägemiseks logige Chrome'i sisse.</translation> <translation id="7402321973924525978">Parool salvestatakse teie seadmesse. Kui soovite paroole ükskõik millises seadmes kasutada, lülitage Chrome'is sünkroonimine sisse.</translation>
diff --git a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_ky.xtb b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_ky.xtb index bddb94f..ca519ae 100644 --- a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_ky.xtb +++ b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_ky.xtb
@@ -9,6 +9,7 @@ <translation id="1706288056912586527">Сырсөздү көрсөтүү</translation> <translation id="1870148520156231997">Сырсөздү көрсөтүү</translation> <translation id="1977167321677356409">Сырсөз</translation> +<translation id="2286038806535735701">Билдирүүлөрдү тезирээк алуу үчүн iCloud ачкычтар чынжырын тандоодон чыгарыңыз</translation> <translation id="2320166752086256636">Баскычтопту жашыруу</translation> <translation id="2712586044587587728">Chrome'догу сырсөздөрүңүздү башка колдонмолордо пайдаланууга болот. Муну Жөндөөлөрдөн каалаган убакта өчүрүп койсоңуз болот.</translation> <translation id="2747003861858887689">Мурунку талаа</translation> @@ -20,6 +21,7 @@ <translation id="4064278913989596727">Жардам</translation> <translation id="4241076354893135477">Chrome сырсөздөрү жок</translation> <translation id="4452240207605337349">Сырсөз сакталбай жатат</translation> +<translation id="4818780572497527258">Түшүндүм</translation> <translation id="5118084770294029567">Бардык сырсөздөр</translation> <translation id="5148402015874782921">Жок</translation> <translation id="5366190986669335938">Chrome'до сактаган сырсөздөрүңүзгө каалаган колдонмодон мүмкүнчүлүк алыңыз.</translation> @@ -29,6 +31,7 @@ <translation id="6216401132953873625">Жаңы сырсөздү кошуу</translation> <translation id="6539092367496845964">Бир жерден ката кетти. Бир аздан кийин кайталап көрүңүз.</translation> <translation id="6657585470893396449">Сырсөз</translation> +<translation id="666236282349601348">Автотолтуруу күйүк</translation> <translation id="6710648923880003133">Татаал сырсөз сунушталсын</translation> <translation id="6734440856654324363">Жаңы сырсөздү кошуу</translation> <translation id="6867369562105931222">сырсөз</translation> @@ -36,6 +39,7 @@ <translation id="6994951856208641136">Сунушталган сырсөз</translation> <translation id="7013045517548357694">Сырсөздөргө мүмкүнчүлүк алуу...</translation> <translation id="7021375594770280489">Үйрөнүп алыңыз</translation> +<translation id="7270843568750656178">Сакталган сырсөздөрдү түзмөгүңүздөгү башка колдонмолордо автоматтык түрдө толтуруу үчүн Chrome'ду колдонуңуз</translation> <translation id="7294706895582948780">Chrome сырсөздөрүн автоматтык түрдө толтуруңүз</translation> <translation id="7362314760212854110">Google аккаунтуңуздан жакында чыгарылдыңыз. Сырсөздөрүңүздү көрүү үчүн Chrome'го кириңиз.</translation> <translation id="7402321973924525978">Сырсөзүңүз түзмөккө сакталат. Сырсөздөрдү каалаган түзмөктө колдонуу үчүн Chrome'до шайкештирүүнү күйгүзүңүз.</translation>
diff --git a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_lo.xtb b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_lo.xtb index 393859a..e47b9b5f 100644 --- a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_lo.xtb +++ b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_lo.xtb
@@ -9,6 +9,7 @@ <translation id="1706288056912586527">ສະແດງລະຫັດຜ່ານ</translation> <translation id="1870148520156231997">ເປີດເຜີຍລະຫັດຜ່ານ</translation> <translation id="1977167321677356409">ລະຫັດຜ່ານ</translation> +<translation id="2286038806535735701">ເພື່ອອ່ານຂໍ້ຄວາມຂອງທ່ານໄດ້ໄວຂຶ້ນ, ໃຫ້ເຊົາເລືອກພວງກະແຈ iCloud</translation> <translation id="2320166752086256636">ເຊື່ອງແປ້ນພິມ</translation> <translation id="2712586044587587728">ລະຫັດຜ່ານໃນ Chrome ຂອງທ່ານຈະມີໃຫ້ນຳໃຊ້ໃນແອັບອື່ນ. ທ່ານສາມາດປິດສິ່ງນີ້ໃນແອັບການຕັ້ງຄ່າໄດ້ທຸກເວລາ.</translation> <translation id="2747003861858887689">ຫ້ອງໃສ່ຂໍ້ມູນຜ່ານມາ</translation> @@ -20,6 +21,7 @@ <translation id="4064278913989596727">ຊ່ວຍເຫຼືອ</translation> <translation id="4241076354893135477">ບໍ່ມີລະຫັດຜ່ານໃນ Chrome</translation> <translation id="4452240207605337349">ບໍ່ສາມາດບັນທຶກລະຫັດຜ່ານໄດ້</translation> +<translation id="4818780572497527258">ເຂົ້າໃຈແລ້ວ</translation> <translation id="5118084770294029567">ລະຫັດຜ່ານທັງໝົດ</translation> <translation id="5148402015874782921">ຍົກເລີກ</translation> <translation id="5366190986669335938">ເຂົ້າເຖິງລະຫັດຜ່ານທີ່ທ່ານບັນທຶກໄວ້ໃນ Chrome ຈາກແອັບໃດໆກໍໄດ້.</translation> @@ -29,6 +31,7 @@ <translation id="6216401132953873625">ເພີ່ມລະຫັດຜ່ານໃໝ່</translation> <translation id="6539092367496845964">ມີບາງຢ່າງຜິດພາດ. ລອງໃໝ່ໃນພາຍຫລັງ.</translation> <translation id="6657585470893396449">ລະຫັດຜ່ານ</translation> +<translation id="666236282349601348">ເປີດໃຊ້ການຕື່ມຂໍ້ມູນອັດຕະໂນມັດແລ້ວ</translation> <translation id="6710648923880003133">ແນະນຳລະຫັດຜ່ານທີ່ຄາດເດົາໄດ້ຍາກ</translation> <translation id="6734440856654324363">ເພີ່ມລະຫັດຜ່ານໃໝ່</translation> <translation id="6867369562105931222">ລະຫັດຜ່ານ</translation> @@ -36,6 +39,7 @@ <translation id="6994951856208641136">ລະຫັດຜ່ານທີ່ແນະນຳ</translation> <translation id="7013045517548357694">ເຂົ້າເຖິງລະຫັດຜ່ານ...</translation> <translation id="7021375594770280489">ສຶກສາວິທີການ</translation> +<translation id="7270843568750656178">ໃຊ້ Chrome ເພື່ອຕື່ມຂໍ້ມູນລະຫັດຜ່ານທີ່ທ່ານບັນທຶກໄວ້ໂດຍອັດຕະໂນມັດໃນແອັບອື່ນໆຢູ່ອຸປະກອນຂອງທ່ານ</translation> <translation id="7294706895582948780">ຕື່ມລະຫັດຜ່ານໃນ Chrome ໂດຍອັດຕະໂນມັດ</translation> <translation id="7362314760212854110">ທ່ານໄດ້ອອກຈາກລະບົບບັນຊີ Google ຂອງທ່ານແລ້ວເມື່ອບໍ່ດົນມານີ້. ເພື່ອເຫັນລະຫັດຜ່ານຂອງທ່ານ, ກະລຸນາເຂົ້າສູ່ລະບົບ Chrome.</translation> <translation id="7402321973924525978">ລະຫັດຜ່ານຂອງທ່ານຈະຖືກບັນທຶກໄປໃສ່ອຸປະກອນທ່ານ. ເພື່ອໃຊ້ລະຫັດຜ່ານຢູ່ອຸປະກອນໃດກໍໄດ້, ໃຫ້ເປີດໃຊ້ການຊິ້ງຂໍ້ມູນໃນ Chrome ກ່ອນ.</translation>
diff --git a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_lv.xtb b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_lv.xtb index 07448c7..8ac5d43 100644 --- a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_lv.xtb +++ b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_lv.xtb
@@ -9,6 +9,7 @@ <translation id="1706288056912586527">Rādīt paroli</translation> <translation id="1870148520156231997">Rādīt paroli</translation> <translation id="1977167321677356409">Parole</translation> +<translation id="2286038806535735701">Lai ātrāk piekļūtu saviem ziņojumiem, noņemiet iCloud Keychain atlasi.</translation> <translation id="2320166752086256636">Paslēpt tastatūru</translation> <translation id="2712586044587587728">Jūsu Chrome paroles būs pieejamas izmantošanai citās lietotnēs. Varat jebkurā laikā izslēgt šo funkciju lietotnē Iestatījumi.</translation> <translation id="2747003861858887689">Iepriekšējais lauks</translation> @@ -20,6 +21,7 @@ <translation id="4064278913989596727">Palīdzība</translation> <translation id="4241076354893135477">Nav Chrome paroļu</translation> <translation id="4452240207605337349">Nevar saglabāt paroli</translation> +<translation id="4818780572497527258">Labi</translation> <translation id="5118084770294029567">Visas paroles</translation> <translation id="5148402015874782921">Atcelt</translation> <translation id="5366190986669335938">No jebkuras lietotnes piekļūstiet pārlūkā Chrome saglabātajām parolēm.</translation> @@ -29,6 +31,7 @@ <translation id="6216401132953873625">Jaunas paroles pievienošana</translation> <translation id="6539092367496845964">Radās kļūda. Vēlāk mēģiniet vēlreiz.</translation> <translation id="6657585470893396449">Parole</translation> +<translation id="666236282349601348">Automātiskā aizpilde ir ieslēgta</translation> <translation id="6710648923880003133">Ieteikt drošu paroli</translation> <translation id="6734440856654324363">Pievienot jaunu paroli</translation> <translation id="6867369562105931222">parole</translation> @@ -36,6 +39,7 @@ <translation id="6994951856208641136">Ieteiktā parole</translation> <translation id="7013045517548357694">Piekļūstiet parolēm...</translation> <translation id="7021375594770280489">Uzzināt, kā to izdarīt</translation> +<translation id="7270843568750656178">Izmantojiet pārlūku Chrome, lai automātiski aizpildītu savas saglabātās paroles citās lietotnēs savā ierīcē.</translation> <translation id="7294706895582948780">Chrome paroļu automātiskā aizpilde</translation> <translation id="7362314760212854110">Jūs nesen izrakstījāties no Google konta. Lai skatītu savas paroles, pierakstieties pārlūkā Chrome.</translation> <translation id="7402321973924525978">Jūsu parole tiks saglabāta jūsu ierīcē. Lai izmantotu paroles jebkurā ierīcē, ieslēdziet sinhronizāciju pārlūkā Chrome.</translation>
diff --git a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_pt-BR.xtb b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_pt-BR.xtb index d4e06295..2bb30a6a3 100644 --- a/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_pt-BR.xtb +++ b/ios/chrome/credential_provider_extension/strings/resources/ios_credential_provider_extension_strings_pt-BR.xtb
@@ -9,6 +9,7 @@ <translation id="1706288056912586527">Mostrar senha</translation> <translation id="1870148520156231997">Mostrar senha</translation> <translation id="1977167321677356409">Senha</translation> +<translation id="2286038806535735701">Para receber suas mensagens mais rapidamente, desmarque o keychain do iCloud</translation> <translation id="2320166752086256636">Ocultar teclado</translation> <translation id="2712586044587587728">Suas senhas do Chrome estarão disponíveis para uso em outros apps. É possível desativar essa opção no app Configurações a qualquer momento.</translation> <translation id="2747003861858887689">Campo anterior</translation> @@ -20,6 +21,7 @@ <translation id="4064278913989596727">Ajuda</translation> <translation id="4241076354893135477">Não há nenhuma senha no Chrome</translation> <translation id="4452240207605337349">Não foi possível salvar a senha</translation> +<translation id="4818780572497527258">Entendi</translation> <translation id="5118084770294029567">Todas as senhas</translation> <translation id="5148402015874782921">Cancelar</translation> <translation id="5366190986669335938">Acesse em qualquer app as senhas que você salvou no Chrome.</translation> @@ -29,6 +31,7 @@ <translation id="6216401132953873625">Adicionar nova senha</translation> <translation id="6539092367496845964">Algo deu errado. Tente novamente mais tarde.</translation> <translation id="6657585470893396449">Senha</translation> +<translation id="666236282349601348">O Preenchimento Automático está ativado</translation> <translation id="6710648923880003133">Sugerir senha forte</translation> <translation id="6734440856654324363">Adicionar nova senha</translation> <translation id="6867369562105931222">senha</translation> @@ -36,6 +39,7 @@ <translation id="6994951856208641136">Senha sugerida</translation> <translation id="7013045517548357694">Acessar senhas…</translation> <translation id="7021375594770280489">Saiba como</translation> +<translation id="7270843568750656178">Use o Chrome para preencher automaticamente suas senhas salvas em outros apps do dispositivo</translation> <translation id="7294706895582948780">Preenchimento automático de senhas do Chrome</translation> <translation id="7362314760212854110">Você saiu da sua Conta do Google recentemente. Faça login no Chrome para ver suas senhas.</translation> <translation id="7402321973924525978">Sua senha será salva neste dispositivo. Para usar as senhas em qualquer dispositivo, ative a sincronização no Chrome.</translation>
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index 49549f19..b7bda78 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -6198b8cad9e7a59a7b5006fa176c68870cbd9004 \ No newline at end of file +6845f3ba34f3349d39f634198b07ef1f2cc5ab6e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index 32a8552..24ac3a2 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -ab8303dd8bc3136bc04c5b3e1f11e2fb5abca88b \ No newline at end of file +46003525ddd5885a5edb93f17832793550139a7f \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index eaa566b..ab626cb 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -e047c3ff548fab479b828b013e3f56e751147e5b \ No newline at end of file +4c836b13a4ae6285a0c564fa5f0c354c0af0fc99 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index 9589945b..963939a 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -d633d8a26dba1767c14309b79e4d90dc9f5fed21 \ No newline at end of file +46a3b7e60cea428e3b446afa3486c6006002965f \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 index 545dde3..3ddf0d5 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -9bfba8fe2246eff75eb0fc984a2eeae18754f1f8 \ No newline at end of file +f835d148756c2e82356be1e4b89dbf61dedd45ae \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 index e3b6b55..31963a2a 100644 --- a/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_dogfood_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -9a4be276fcd86b6c67097051a49b8c1665e7bdab \ No newline at end of file +7347fa4be6b2f28f4f8fb2ecef8a5ff17248e019 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index 6185271..46196cd 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -1f6afd4cf78633738c8b22dc55bb7dd0dc32bc4e \ No newline at end of file +b05bf0b4f359596814d084ffda7b4a20dd5b981a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 68addc57..9d4367f 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -8b0453bb07689926aee384c8c844b6e4898df3b1 \ No newline at end of file +99b321eefc5b64034b67d9190c5588864b97a0cc \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index 81a64e8..117f028 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -b529bd36afa9cd3d67d58a04d9aae261dad5579a \ No newline at end of file +3af17c1f1401a6e7c9064f84647df651ffadffed \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index f66f456..e60b654 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -8aaf6972b116879b5835d58b5dac942a46e0b79f \ No newline at end of file +5575e140563c845b577b52f19cb2a8e03b0f0d28 \ No newline at end of file
diff --git a/ios/web_view/public/cwv_trusted_vault_utils.h b/ios/web_view/public/cwv_trusted_vault_utils.h index 72c2c29..47cd16f3 100644 --- a/ios/web_view/public/cwv_trusted_vault_utils.h +++ b/ios/web_view/public/cwv_trusted_vault_utils.h
@@ -7,6 +7,8 @@ #import <Foundation/Foundation.h> +#import "cwv_export.h" + NS_ASSUME_NONNULL_BEGIN // Possible states of the trusted vault. Keep in sync with @@ -21,6 +23,7 @@ }; // Utility methods for trusted vault. +CWV_EXPORT @interface CWVTrustedVaultUtils : NSObject // Call to log to UMA when trusted vault state changes.
diff --git a/media/base/key_system_properties.cc b/media/base/key_system_properties.cc index 3c835825..0a52ade 100644 --- a/media/base/key_system_properties.cc +++ b/media/base/key_system_properties.cc
@@ -12,6 +12,11 @@ return key_system == GetBaseKeySystemName(); } +bool KeySystemProperties::ShouldUseBaseKeySystemName() const { + // By default, use the sub key system names for creating CDMs. + return false; +} + SupportedCodecs KeySystemProperties::GetSupportedHwSecureCodecs() const { return EME_CODEC_NONE; }
diff --git a/media/base/key_system_properties.h b/media/base/key_system_properties.h index 84fae09c..2e4973d 100644 --- a/media/base/key_system_properties.h +++ b/media/base/key_system_properties.h
@@ -28,6 +28,10 @@ // could be supported, but "org.chromium.baz" should NOT be supported. virtual bool IsSupportedKeySystem(const std::string& key_system) const; + // Whether the base key system should be used for all supported key systems + // when creating CDMs. + virtual bool ShouldUseBaseKeySystemName() const; + // Returns whether |init_data_type| is supported by this key system. virtual bool IsSupportedInitDataType( EmeInitDataType init_data_type) const = 0;
diff --git a/media/base/key_systems.cc b/media/base/key_systems.cc index 328b40c..384ede79 100644 --- a/media/base/key_systems.cc +++ b/media/base/key_systems.cc
@@ -210,9 +210,9 @@ // appropriate glue/adapter code, and added all the appropriate data to // KeySystemsImpl. Only then should you change this function. static bool IsPotentiallySupportedKeySystem(const std::string& key_system) { - // Known and supported key systems. if (key_system == kWidevineKeySystem) return true; + if (key_system == kClearKeyKeySystem) return true; @@ -249,36 +249,30 @@ // Implementation of KeySystems interface. void UpdateIfNeeded() override; - + std::string GetBaseKeySystemName( + const std::string& key_system) const override; bool IsSupportedKeySystem(const std::string& key_system) const override; - + bool ShouldUseBaseKeySystemName(const std::string& key_system) const override; bool CanUseAesDecryptor(const std::string& key_system) const override; - bool IsSupportedInitDataType(const std::string& key_system, EmeInitDataType init_data_type) const override; - EmeConfigRule GetEncryptionSchemeConfigRule( const std::string& key_system, EncryptionScheme encryption_scheme) const override; - EmeConfigRule GetContentTypeConfigRule( const std::string& key_system, EmeMediaType media_type, const std::string& container_mime_type, const std::vector<std::string>& codecs) const override; - EmeConfigRule GetRobustnessConfigRule( const std::string& key_system, EmeMediaType media_type, const std::string& requested_robustness, const bool* hw_secure_requirement) const override; - EmeSessionTypeSupport GetPersistentLicenseSessionSupport( const std::string& key_system) const override; - EmeFeatureSupport GetPersistentStateSupport( const std::string& key_system) const override; - EmeFeatureSupport GetDistinctiveIdentifierSupport( const std::string& key_system) const override; @@ -605,12 +599,36 @@ RegisterMimeType(mime_type, static_cast<EmeCodec>(codecs_mask)); } +std::string KeySystemsImpl::GetBaseKeySystemName( + const std::string& key_system) const { + const auto* properties = GetKeySystemProperties(key_system); + if (!properties) { + NOTREACHED() << "Key system support should have been checked"; + return key_system; + } + + return properties->GetBaseKeySystemName(); +} + bool KeySystemsImpl::IsSupportedKeySystem(const std::string& key_system) const { DCHECK(thread_checker_.CalledOnValidThread()); return GetKeySystemProperties(key_system); } +bool KeySystemsImpl::ShouldUseBaseKeySystemName( + const std::string& key_system) const { + DCHECK(thread_checker_.CalledOnValidThread()); + + const auto* properties = GetKeySystemProperties(key_system); + if (!properties) { + NOTREACHED() << "Key system support should have been checked"; + return false; + } + + return properties->ShouldUseBaseKeySystemName(); +} + bool KeySystemsImpl::CanUseAesDecryptor(const std::string& key_system) const { DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/media/base/key_systems.h b/media/base/key_systems.h index 5acf2c8..494edf9 100644 --- a/media/base/key_systems.h +++ b/media/base/key_systems.h
@@ -32,9 +32,17 @@ // Refreshes the list of available key systems if it may be out of date. virtual void UpdateIfNeeded() = 0; + // Gets the base key system name, e.g. "org.chromium.foo". + virtual std::string GetBaseKeySystemName( + const std::string& key_system) const = 0; + // Returns whether |key_system| is a supported key system. virtual bool IsSupportedKeySystem(const std::string& key_system) const = 0; + // Whether the base key system name should be used for CDM creation. + virtual bool ShouldUseBaseKeySystemName( + const std::string& key_system) const = 0; + // Returns whether AesDecryptor can be used for the given |key_system|. virtual bool CanUseAesDecryptor(const std::string& key_system) const = 0;
diff --git a/media/filters/dav1d_video_decoder.cc b/media/filters/dav1d_video_decoder.cc index af6e795..78902eb 100644 --- a/media/filters/dav1d_video_decoder.cc +++ b/media/filters/dav1d_video_decoder.cc
@@ -186,44 +186,20 @@ // Compute the ideal thread count values. We'll then clamp these based on the // maximum number of recommended threads (using number of processors, etc). - // - // dav1d will spawn |n_tile_threads| per frame thread. - GetDecoderThreadCounts(config.coded_size().height(), &s.n_tile_threads, - &s.n_frame_threads); + int tile_threads, frame_threads; + GetDecoderThreadCounts(config.coded_size().height(), &tile_threads, + &frame_threads); - const int max_threads = VideoDecoder::GetRecommendedThreadCount( - s.n_frame_threads * (s.n_tile_threads + 1)); + // While dav1d has switched to a thread pool, preserve the same thread counts + // we used when tile and frame threads were configured distinctly. It may be + // possible to lower this after some performance analysis of the new system. + s.n_threads = VideoDecoder::GetRecommendedThreadCount(frame_threads * + (tile_threads + 1)); - // First clamp tile threads to the allowed maximum. We prefer tile threads - // over frame threads since dav1d folk indicate they are more efficient. In an - // ideal world this would be auto-detected by dav1d from the content. - // - // https://bugzilla.mozilla.org/show_bug.cgi?id=1536783#c0 - s.n_tile_threads = std::min(max_threads, s.n_tile_threads); - - // Now clamp frame threads based on the number of total threads that would be - // created with the given |n_tile_threads| value. Note: A thread count of 1 - // generates no additional threads since the calling thread (this thread) is - // counted as a thread. - // // We only want 1 frame thread in low delay mode, since otherwise we'll // require at least two buffers before the first frame can be output. - // - // If a system has the cores for it, we'll end up using the following: - // <300p: 2 tile threads, 2 frame threads = 2 * 2 + 2 = 6 total threads. - // <700p: 3 tile threads, 2 frame threads = 3 * 2 + 2 = 8 total threads. - // - // For higher resolutions we hit limits::kMaxVideoThreads (16): - // >700p: 4 tile threads, 3 frame threads = 4 * 3 + 3 = 15 total threads. - // - // Due to the (surprising) performance issues which occurred when setting - // |n_frame_threads|=1 (https://crbug.com/957511) the minimum total number of - // threads is 6 (two tile and two frame) regardless of core count. The maximum - // is min(2 * base::SysInfo::NumberOfProcessors(), limits::kMaxVideoThreads). if (low_delay || config.is_rtc()) - s.n_frame_threads = 1; - else if (s.n_frame_threads * (s.n_tile_threads + 1) > max_threads) - s.n_frame_threads = std::max(2, max_threads / (s.n_tile_threads + 1)); + s.max_frame_delay = 1; // Route dav1d internal logs through Chrome's DLOG system. s.logger = {nullptr, &LogDav1dMessage};
diff --git a/media/mojo/services/mojo_video_encode_accelerator_provider.cc b/media/mojo/services/mojo_video_encode_accelerator_provider.cc index f594ca0..2e46d47 100644 --- a/media/mojo/services/mojo_video_encode_accelerator_provider.cc +++ b/media/mojo/services/mojo_video_encode_accelerator_provider.cc
@@ -7,12 +7,29 @@ #include <memory> #include <utility> +#include "base/no_destructor.h" +#include "base/task/thread_pool.h" #include "media/base/bind_to_current_loop.h" #include "media/base/limits.h" #include "media/gpu/gpu_video_encode_accelerator_factory.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" #include "mojo/public/cpp/system/platform_handle.h" +namespace { +void BindVEAProvider( + mojo::PendingReceiver<media::mojom::VideoEncodeAcceleratorProvider> + receiver, + media::MojoVideoEncodeAcceleratorProvider:: + CreateAndInitializeVideoEncodeAcceleratorCallback create_vea_callback, + gpu::GpuPreferences gpu_preferences, + gpu::GpuDriverBugWorkarounds gpu_workarounds) { + auto vea_provider = + std::make_unique<media::MojoVideoEncodeAcceleratorProvider>( + std::move(create_vea_callback), gpu_preferences, gpu_workarounds); + mojo::MakeSelfOwnedReceiver(std::move(vea_provider), std::move(receiver)); +} +} // namespace + namespace media { // static @@ -21,10 +38,24 @@ CreateAndInitializeVideoEncodeAcceleratorCallback create_vea_callback, const gpu::GpuPreferences& gpu_preferences, const gpu::GpuDriverBugWorkarounds& gpu_workarounds) { - mojo::MakeSelfOwnedReceiver( - std::make_unique<MojoVideoEncodeAcceleratorProvider>( - std::move(create_vea_callback), gpu_preferences, gpu_workarounds), - std::move(receiver)); + // Offload VEA providers to a dedicated runner. Things like loading profiles + // and creating encoder might take quite some time, and they might block + // processing of other mojo calls if executed on the current runner. + // + // This runner needs to use sync primitives (and be DEDICATED) because + // MediaFoundationVEA waits for the encoding thread to stop when + // destroyed. Since a dedicated runner is basically a separate thread, it's + // declared static to avoid creation of a new thread for each renderer with + // GPU factories. + static base::NoDestructor<scoped_refptr<base::SingleThreadTaskRunner>> runner( + base::ThreadPool::CreateSingleThreadTaskRunner( + {base::TaskPriority::USER_BLOCKING, base::WithBaseSyncPrimitives()}, + base::SingleThreadTaskRunnerThreadMode::DEDICATED)); + + (*runner)->PostTask( + FROM_HERE, base::BindOnce(BindVEAProvider, std::move(receiver), + std::move(create_vea_callback), gpu_preferences, + gpu_workarounds)); } MojoVideoEncodeAcceleratorProvider::MojoVideoEncodeAcceleratorProvider(
diff --git a/media/mojo/services/mojo_video_encode_accelerator_provider.h b/media/mojo/services/mojo_video_encode_accelerator_provider.h index 6a25a04..df6ef81 100644 --- a/media/mojo/services/mojo_video_encode_accelerator_provider.h +++ b/media/mojo/services/mojo_video_encode_accelerator_provider.h
@@ -7,6 +7,7 @@ #include "base/compiler_specific.h" #include "gpu/config/gpu_driver_bug_workarounds.h" +#include "gpu/config/gpu_preferences.h" #include "media/mojo/mojom/video_encode_accelerator.mojom.h" #include "media/mojo/services/media_mojo_export.h" #include "media/mojo/services/mojo_video_encode_accelerator_service.h" @@ -57,7 +58,7 @@ private: const CreateAndInitializeVideoEncodeAcceleratorCallback create_vea_callback_; - const gpu::GpuPreferences& gpu_preferences_; + const gpu::GpuPreferences gpu_preferences_; const gpu::GpuDriverBugWorkarounds gpu_workarounds_; };
diff --git a/media/renderers/default_decoder_factory.cc b/media/renderers/default_decoder_factory.cc index 1ab8c79..e46c45af 100644 --- a/media/renderers/default_decoder_factory.cc +++ b/media/renderers/default_decoder_factory.cc
@@ -149,7 +149,7 @@ // Perfer an external decoder since one will only exist if it is hardware // accelerated. if (external_decoder_factory_ && gpu_factories && - gpu_factories->IsGpuVideoAcceleratorEnabled()) { + gpu_factories->IsGpuVideoDecodeAcceleratorEnabled()) { // |gpu_factories_| requires that its entry points be called on its // |GetTaskRunner()|. Since |pipeline_| will own decoders created from the // factories, require that their message loops are identical. @@ -162,7 +162,7 @@ #if defined(OS_FUCHSIA) // TODO(crbug.com/1122116): Minimize Fuchsia-specific code paths. - if (gpu_factories && gpu_factories->IsGpuVideoAcceleratorEnabled()) { + if (gpu_factories && gpu_factories->IsGpuVideoDecodeAcceleratorEnabled()) { auto* context_provider = gpu_factories->GetMediaContextProvider(); // GetMediaContextProvider() may return nullptr when the context was lost
diff --git a/media/video/gpu_video_accelerator_factories.h b/media/video/gpu_video_accelerator_factories.h index fd6bf53..a80a9dc7 100644 --- a/media/video/gpu_video_accelerator_factories.h +++ b/media/video/gpu_video_accelerator_factories.h
@@ -76,8 +76,10 @@ kUnknown, }; - // Return whether GPU encoding/decoding is enabled. - virtual bool IsGpuVideoAcceleratorEnabled() = 0; + // Return whether GPU decoding is enabled. + virtual bool IsGpuVideoDecodeAcceleratorEnabled() = 0; + // Return whether GPU encoding is enabled. + virtual bool IsGpuVideoEncodeAcceleratorEnabled() = 0; // Return the channel token, or an empty token if the channel is unusable. // |cb| could be called re-entrantly. This function is not thread safe.
diff --git a/media/video/mock_gpu_video_accelerator_factories.cc b/media/video/mock_gpu_video_accelerator_factories.cc index 8003efc..0f350c4b 100644 --- a/media/video/mock_gpu_video_accelerator_factories.cc +++ b/media/video/mock_gpu_video_accelerator_factories.cc
@@ -108,7 +108,11 @@ MockGpuVideoAcceleratorFactories::~MockGpuVideoAcceleratorFactories() = default; -bool MockGpuVideoAcceleratorFactories::IsGpuVideoAcceleratorEnabled() { +bool MockGpuVideoAcceleratorFactories::IsGpuVideoDecodeAcceleratorEnabled() { + return true; +} + +bool MockGpuVideoAcceleratorFactories::IsGpuVideoEncodeAcceleratorEnabled() { return true; }
diff --git a/media/video/mock_gpu_video_accelerator_factories.h b/media/video/mock_gpu_video_accelerator_factories.h index 0762f2b5..677b341 100644 --- a/media/video/mock_gpu_video_accelerator_factories.h +++ b/media/video/mock_gpu_video_accelerator_factories.h
@@ -32,7 +32,8 @@ ~MockGpuVideoAcceleratorFactories() override; - bool IsGpuVideoAcceleratorEnabled() override; + bool IsGpuVideoDecodeAcceleratorEnabled() override; + bool IsGpuVideoEncodeAcceleratorEnabled() override; MOCK_METHOD1(GetChannelToken, void(gpu::mojom::GpuChannel::GetChannelTokenCallback));
diff --git a/net/base/filename_util.h b/net/base/filename_util.h index ef64e64..c6fa118b 100644 --- a/net/base/filename_util.h +++ b/net/base/filename_util.h
@@ -16,7 +16,7 @@ class FilePath; } -namespace net { +namespace net { // Given the full path to a file name, creates a file: URL. The returned URL // may not be valid if the input is malformed.
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index 56386930..5f3deef 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc
@@ -852,7 +852,7 @@ // Create an SSLClientSocket object and use it to connect to a test server, // then wait for connection results. This must be called after a successful - // StartTestServer() call. + // StartEmbeddedTestServer() or StartTestServer() call. // // |ssl_config| The SSL configuration to use. // |host_port_pair| The hostname and port to use at the SSL layer. (The @@ -889,18 +889,12 @@ } // Adds the server certificate with provided cert status. - // Must be called after StartTestServer has been called. + // Must be called after StartEmbeddedTestServer has been called. void AddServerCertStatusToSSLConfig(CertStatus status, SSLConfig* ssl_config) { - ASSERT_TRUE(spawned_test_server() || embedded_test_server()); - // Find out the certificate the server is using. - scoped_refptr<X509Certificate> server_cert; - if (spawned_test_server()) { - server_cert = spawned_test_server()->GetCertificate(); - } else { - server_cert = embedded_test_server()->GetCertificate(); - } - // Get the MockCertVerifier to verify it as an EV cert. + ASSERT_TRUE(embedded_test_server()); + scoped_refptr<X509Certificate> server_cert = + embedded_test_server()->GetCertificate(); CertVerifyResult verify_result; verify_result.cert_status = status; verify_result.verified_cert = server_cert; @@ -1040,24 +1034,6 @@ SSL_PROTOCOL_VERSION_TLS1_2, SSL_PROTOCOL_VERSION_TLS1_3}; } -absl::optional<SpawnedTestServer::SSLOptions::TLSMaxVersion> -ProtocolVersionToSpawnedTestServer(uint16_t version) { - switch (version) { - case SSL_PROTOCOL_VERSION_TLS1: - return SpawnedTestServer::SSLOptions::TLS_MAX_VERSION_TLS1_0; - case SSL_PROTOCOL_VERSION_TLS1_1: - return SpawnedTestServer::SSLOptions::TLS_MAX_VERSION_TLS1_1; - case SSL_PROTOCOL_VERSION_TLS1_2: - return SpawnedTestServer::SSLOptions::TLS_MAX_VERSION_TLS1_2; - case SSL_PROTOCOL_VERSION_TLS1_3: - // SpawnedTestServer does not support TLS 1.3. - return absl::nullopt; - default: - ADD_FAILURE() << "Unknown version " << version; - return absl::nullopt; - } -} - class SSLClientSocketVersionTest : public SSLClientSocketTest, public ::testing::WithParamInterface<uint16_t> { @@ -1207,7 +1183,7 @@ // the client successfully false started, |callback.WaitForResult()| will // return OK without unblocking transport reads. But Read() will still block.) // - // Must be called after StartTestServer is called. + // Must be called after StartEmbeddedTestServer is called. void CreateAndConnectUntilServerFinishedReceived( const SSLConfig& client_config, TestCompletionCallback* callback, @@ -2339,14 +2315,10 @@ // Tests that fatal alerts from the peer are processed. This is a regression // test for https://crbug.com/466303. TEST_P(SSLClientSocketReadTest, Read_WithFatalAlert) { - SpawnedTestServer::SSLOptions ssl_options; - auto tls_max_version = ProtocolVersionToSpawnedTestServer(version()); - if (!tls_max_version) { - return; - } - ssl_options.tls_max_version = *tls_max_version; - ssl_options.alert_after_handshake = true; - ASSERT_TRUE(StartTestServer(ssl_options)); + SSLServerConfig server_config = GetServerConfig(); + server_config.alert_after_handshake_for_testing = SSL_AD_INTERNAL_ERROR; + ASSERT_TRUE( + StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config)); int rv; ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv)); @@ -2860,21 +2832,22 @@ } TEST_P(SSLClientSocketCertRequestInfoTest, CertKeyTypes) { - SpawnedTestServer::SSLOptions ssl_options; - auto tls_max_version = ProtocolVersionToSpawnedTestServer(version()); - if (!tls_max_version) { - return; - } - ssl_options.tls_max_version = *tls_max_version; - ssl_options.request_client_certificate = true; - ssl_options.client_cert_types.push_back(CLIENT_CERT_RSA_SIGN); - ssl_options.client_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); - ASSERT_TRUE(StartTestServer(ssl_options)); + SSLServerConfig config = GetServerConfig(); + config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT; + ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, config)); scoped_refptr<SSLCertRequestInfo> request_info = GetCertRequest(); ASSERT_TRUE(request_info.get()); - ASSERT_EQ(2u, request_info->cert_key_types.size()); - EXPECT_EQ(CLIENT_CERT_RSA_SIGN, request_info->cert_key_types[0]); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, request_info->cert_key_types[1]); + if (version() >= SSL_PROTOCOL_VERSION_TLS1_3) { + // TLS 1.3 does not use cert_key_types, only signature algorithms. This + // should be migrated to a more modern mechanism. See + // https://crbug.com/1270530. + EXPECT_EQ(0u, request_info->cert_key_types.size()); + } else { + // BoringSSL always sends rsa_sign and ecdsa_sign. + ASSERT_EQ(2u, request_info->cert_key_types.size()); + EXPECT_EQ(CLIENT_CERT_RSA_SIGN, request_info->cert_key_types[0]); + EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, request_info->cert_key_types[1]); + } } // Tests that the Certificate Transparency (RFC 6962) TLS extension is
diff --git a/net/socket/ssl_server_socket_impl.cc b/net/socket/ssl_server_socket_impl.cc index eb8e0e9..272066d 100644 --- a/net/socket/ssl_server_socket_impl.cc +++ b/net/socket/ssl_server_socket_impl.cc
@@ -729,7 +729,6 @@ int net_error = OK; int rv = SSL_do_handshake(ssl_.get()); if (rv == 1) { - completed_handshake_ = true; const STACK_OF(CRYPTO_BUFFER)* certs = SSL_get0_peer_certificates(ssl_.get()); if (certs) { @@ -746,6 +745,15 @@ alpn_len); negotiated_protocol_ = NextProtoFromString(proto); } + + if (context_->ssl_server_config_.alert_after_handshake_for_testing) { + SSL_send_fatal_alert(ssl_.get(), + context_->ssl_server_config_ + .alert_after_handshake_for_testing.value()); + return ERR_FAILED; + } + + completed_handshake_ = true; } else { int ssl_error = SSL_get_error(ssl_.get(), rv);
diff --git a/net/ssl/ssl_server_config.h b/net/ssl/ssl_server_config.h index 684134f..6b775069 100644 --- a/net/ssl/ssl_server_config.h +++ b/net/ssl/ssl_server_config.h
@@ -124,6 +124,10 @@ base::RepeatingCallback<bool(const SSL_CLIENT_HELLO*)> client_hello_callback_for_testing; + // If specified, causes the specified alert to be sent immediately after the + // handshake. + absl::optional<uint8_t> alert_after_handshake_for_testing; + // This is a workaround for BoringSSL's scopers not being copyable. See // https://crbug.com/boringssl/431. class NET_EXPORT ECHKeysContainer {
diff --git a/net/test/spawned_test_server/base_test_server.cc b/net/test/spawned_test_server/base_test_server.cc index 20548e6..c9383bc 100644 --- a/net/test/spawned_test_server/base_test_server.cc +++ b/net/test/spawned_test_server/base_test_server.cc
@@ -54,18 +54,6 @@ return "127.0.0.1"; } -std::string GetClientCertType(SSLClientCertType type) { - switch (type) { - case CLIENT_CERT_RSA_SIGN: - return "rsa_sign"; - case CLIENT_CERT_ECDSA_SIGN: - return "ecdsa_sign"; - default: - NOTREACHED(); - return ""; - } -} - bool GetLocalCertificatesDir(const base::FilePath& certificates_dir, base::FilePath* local_certificates_dir) { if (certificates_dir.IsAbsolute()) { @@ -445,16 +433,6 @@ arguments->SetKey("ssl-client-ca", base::Value(std::move(ssl_client_certs))); } - - std::vector<base::Value> client_cert_types; - for (size_t i = 0; i < ssl_options_.client_cert_types.size(); i++) { - client_cert_types.emplace_back( - GetClientCertType(ssl_options_.client_cert_types[i])); - } - if (client_cert_types.size()) { - arguments->SetKey("ssl-client-cert-type", - base::Value(std::move(client_cert_types))); - } } if (type_ == TYPE_HTTPS) { @@ -463,8 +441,6 @@ if (ssl_options_.tls_max_version != SSLOptions::TLS_MAX_VERSION_DEFAULT) { arguments->SetIntKey("tls-max-version", ssl_options_.tls_max_version); } - if (ssl_options_.alert_after_handshake) - arguments->SetKey("alert-after-handshake", base::Value()); if (ssl_options_.simulate_tls13_downgrade) { arguments->SetKey("simulate-tls13-downgrade", base::Value());
diff --git a/net/test/spawned_test_server/base_test_server.h b/net/test/spawned_test_server/base_test_server.h index a3fce3d..f61db24 100644 --- a/net/test/spawned_test_server/base_test_server.h +++ b/net/test/spawned_test_server/base_test_server.h
@@ -20,7 +20,6 @@ #include "base/memory/ref_counted.h" #include "base/values.h" #include "net/base/host_port_pair.h" -#include "net/ssl/ssl_client_cert_type.h" #include "third_party/abseil-cpp/absl/types/optional.h" class GURL; @@ -117,17 +116,9 @@ // field of the CertificateRequest. std::vector<base::FilePath> client_authorities; - // If |request_client_certificate| is true, an optional list of - // SSLClientCertType values to populate the certificate_types field of the - // CertificateRequest. - std::vector<SSLClientCertType> client_cert_types; - // The maximum TLS version to support. TLSMaxVersion tls_max_version = TLS_MAX_VERSION_DEFAULT; - // Whether to send a fatal alert immediately after completing the handshake. - bool alert_after_handshake = false; - // If true, sends the TLS 1.3 to TLS 1.2 downgrade signal in the ServerHello // random. bool simulate_tls13_downgrade = false;
diff --git a/net/tools/testserver/testserver.py b/net/tools/testserver/testserver.py index 3126802..d523f33 100755 --- a/net/tools/testserver/testserver.py +++ b/net/tools/testserver/testserver.py
@@ -101,8 +101,7 @@ client verification.""" def __init__(self, server_address, request_hander_class, pem_cert_and_key, - ssl_client_auth, ssl_client_cas, ssl_client_cert_types, - alert_after_handshake, simulate_tls13_downgrade, + ssl_client_auth, ssl_client_cas, simulate_tls13_downgrade, simulate_tls12_downgrade, tls_max_version): self.cert_chain = tlslite.api.X509CertChain() self.cert_chain.parsePemList(pem_cert_and_key) @@ -115,7 +114,6 @@ implementations=['python']) self.ssl_client_auth = ssl_client_auth self.ssl_client_cas = [] - self.ssl_client_cert_types = [] if ssl_client_auth: for ca_file in ssl_client_cas: @@ -124,17 +122,9 @@ x509.parse(s) self.ssl_client_cas.append(x509.subject) - for cert_type in ssl_client_cert_types: - self.ssl_client_cert_types.append({ - "rsa_sign": tlslite.api.ClientCertificateType.rsa_sign, - "ecdsa_sign": tlslite.api.ClientCertificateType.ecdsa_sign, - }[cert_type]) - self.ssl_handshake_settings = tlslite.api.HandshakeSettings() # Enable SSLv3 for testing purposes. self.ssl_handshake_settings.minVersion = (3, 0) - if alert_after_handshake: - self.ssl_handshake_settings.alertAfterHandshake = True if simulate_tls13_downgrade: self.ssl_handshake_settings.simulateTLS13Downgrade = True if simulate_tls12_downgrade: @@ -157,8 +147,7 @@ sessionCache=self.session_cache, reqCert=self.ssl_client_auth, settings=self.ssl_handshake_settings, - reqCAs=self.ssl_client_cas, - reqCertTypes=self.ssl_client_cert_types) + reqCAs=self.ssl_client_cas) tlsConnection.ignoreAbruptClose = True return True except tlslite.api.TLSAbruptCloseError: @@ -408,8 +397,6 @@ server = HTTPSServer( (host, port), TestPageHandler, pem_cert_and_key, self.options.ssl_client_auth, self.options.ssl_client_ca, - self.options.ssl_client_cert_type, - self.options.alert_after_handshake, self.options.simulate_tls13_downgrade, self.options.simulate_tls12_downgrade, self.options.tls_max_version) print('HTTPS server started on https://%s:%d...' % @@ -509,26 +496,12 @@ 'file. This option may appear multiple ' 'times, indicating multiple CA names should ' 'be sent in the request.') - self.option_parser.add_option('--ssl-client-cert-type', action='append', - default=[], help='Specify that the client ' - 'certificate request should include the ' - 'specified certificate_type value. This ' - 'option may appear multiple times, ' - 'indicating multiple values should be send ' - 'in the request. Valid values are ' - '"rsa_sign", "dss_sign", and "ecdsa_sign". ' - 'If omitted, "rsa_sign" will be used.') self.option_parser.add_option('--file-root-url', default='/files/', help='Specify a root URL for files served.') # TODO(ricea): Generalize this to support basic auth for HTTP too. self.option_parser.add_option('--ws-basic-auth', action='store_true', dest='ws_basic_auth', help='Enable basic-auth for WebSocket') - self.option_parser.add_option('--alert-after-handshake', - dest='alert_after_handshake', - default=False, action='store_true', - help='If set, the server will send a fatal ' - 'alert immediately after the handshake.') self.option_parser.add_option('--simulate-tls13-downgrade', action='store_true') self.option_parser.add_option('--simulate-tls12-downgrade',
diff --git a/remoting/protocol/host_video_stats_dispatcher.cc b/remoting/protocol/host_video_stats_dispatcher.cc index e3a1115..c1d433d 100644 --- a/remoting/protocol/host_video_stats_dispatcher.cc +++ b/remoting/protocol/host_video_stats_dispatcher.cc
@@ -25,6 +25,10 @@ HostVideoStatsDispatcher::~HostVideoStatsDispatcher() = default; +base::WeakPtr<HostVideoStatsDispatcher> HostVideoStatsDispatcher::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + void HostVideoStatsDispatcher::OnVideoFrameStats(uint32_t frame_id, const HostFrameStats& stats) { FrameStatsMessage message;
diff --git a/remoting/protocol/host_video_stats_dispatcher.h b/remoting/protocol/host_video_stats_dispatcher.h index 47bbf26..6d4d626 100644 --- a/remoting/protocol/host_video_stats_dispatcher.h +++ b/remoting/protocol/host_video_stats_dispatcher.h
@@ -5,7 +5,7 @@ #ifndef REMOTING_PROTOCOL_HOST_VIDEO_STATS_DISPATCHER_H_ #define REMOTING_PROTOCOL_HOST_VIDEO_STATS_DISPATCHER_H_ -#include "base/compiler_specific.h" +#include "base/memory/weak_ptr.h" #include "remoting/protocol/channel_dispatcher_base.h" #include "remoting/protocol/video_stats_stub.h" @@ -22,12 +22,16 @@ ~HostVideoStatsDispatcher() override; + base::WeakPtr<HostVideoStatsDispatcher> GetWeakPtr(); + // VideoStatsStub interface. void OnVideoFrameStats(uint32_t frame_id, const HostFrameStats& frame_stats) override; private: void OnIncomingMessage(std::unique_ptr<CompoundBuffer> message) override; + + base::WeakPtrFactory<HostVideoStatsDispatcher> weak_factory_{this}; }; } // namespace protocol
diff --git a/remoting/protocol/webrtc_connection_to_client.cc b/remoting/protocol/webrtc_connection_to_client.cc index 92dda3c..a0807065 100644 --- a/remoting/protocol/webrtc_connection_to_client.cc +++ b/remoting/protocol/webrtc_connection_to_client.cc
@@ -33,6 +33,12 @@ namespace remoting { namespace protocol { +namespace { + +const char kVideoStatsStreamLabel[] = "screen_stream"; + +} // namespace + // Currently the network thread is also used as worker thread for webrtc. // // TODO(sergeyu): Figure out if we would benefit from using a separate @@ -42,6 +48,7 @@ scoped_refptr<protocol::TransportContext> transport_context, scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner) : session_(std::move(session)), + video_stats_dispatcher_(kVideoStatsStreamLabel), audio_task_runner_(audio_task_runner), control_dispatcher_(new HostControlDispatcher()), event_dispatcher_(new HostEventDispatcher()) { @@ -82,8 +89,8 @@ DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(transport_); - std::unique_ptr<WebrtcVideoStream> stream( - new WebrtcVideoStream(session_options_)); + auto stream = std::make_unique<WebrtcVideoStream>(session_options_); + stream->set_video_stats_dispatcher(video_stats_dispatcher_.GetWeakPtr()); stream->Start(std::move(desktop_capturer), transport_.get(), video_encoder_factory_); stream->SetEventTimestampsSource( @@ -184,6 +191,12 @@ control_dispatcher_->Init( transport_->CreateOutgoingChannel(control_dispatcher_->channel_name()), this); + + // Create channel for sending per-frame statistics. The video-stream will + // only try to send any stats after this channel is connected. + video_stats_dispatcher_.Init( + transport_->CreateOutgoingChannel(video_stats_dispatcher_.channel_name()), + this); } void WebrtcConnectionToClient::OnWebrtcTransportConnected() { @@ -266,6 +279,11 @@ ChannelDispatcherBase* channel_dispatcher) { DCHECK(thread_checker_.CalledOnValidThread()); + if (channel_dispatcher == &video_stats_dispatcher_) { + LOG(WARNING) << "video_stats channel was closed."; + return; + } + LOG(ERROR) << "Channel " << channel_dispatcher->channel_name() << " was closed unexpectedly."; Disconnect(INCOMPATIBLE_PROTOCOL);
diff --git a/remoting/protocol/webrtc_connection_to_client.h b/remoting/protocol/webrtc_connection_to_client.h index d824553..c6e8640 100644 --- a/remoting/protocol/webrtc_connection_to_client.h +++ b/remoting/protocol/webrtc_connection_to_client.h
@@ -15,6 +15,7 @@ #include "base/threading/thread_checker.h" #include "remoting/protocol/channel_dispatcher_base.h" #include "remoting/protocol/connection_to_client.h" +#include "remoting/protocol/host_video_stats_dispatcher.h" #include "remoting/protocol/session.h" #include "remoting/protocol/webrtc_transport.h" @@ -92,6 +93,8 @@ WebrtcVideoEncoderFactory* video_encoder_factory_; + HostVideoStatsDispatcher video_stats_dispatcher_; + scoped_refptr<base::SingleThreadTaskRunner> audio_task_runner_; SessionOptions session_options_;
diff --git a/remoting/protocol/webrtc_video_renderer_adapter.cc b/remoting/protocol/webrtc_video_renderer_adapter.cc index 32d1a613..063fcd26 100644 --- a/remoting/protocol/webrtc_video_renderer_adapter.cc +++ b/remoting/protocol/webrtc_video_renderer_adapter.cc
@@ -68,6 +68,14 @@ WebrtcVideoRendererAdapter::~WebrtcVideoRendererAdapter() { DCHECK(task_runner_->BelongsToCurrentThread()); + // Needed for ConnectionTest unittests which set up a + // fake connection without starting any video. This + // video adapter is instantiated when the incoming + // video-stats data channel is created. + if (!media_stream_) { + return; + } + webrtc::VideoTrackVector video_tracks = media_stream_->GetVideoTracks(); DCHECK(!video_tracks.empty()); video_tracks[0]->RemoveSink(this);
diff --git a/remoting/protocol/webrtc_video_stream.cc b/remoting/protocol/webrtc_video_stream.cc index abce67e70..8b060792 100644 --- a/remoting/protocol/webrtc_video_stream.cc +++ b/remoting/protocol/webrtc_video_stream.cc
@@ -47,8 +47,7 @@ }; WebrtcVideoStream::WebrtcVideoStream(const SessionOptions& session_options) - : video_stats_dispatcher_(kStreamLabel), - session_options_(session_options) {} + : session_options_(session_options) {} WebrtcVideoStream::~WebrtcVideoStream() { DCHECK(thread_checker_.CalledOnValidThread()); @@ -94,10 +93,6 @@ scheduler_ = std::make_unique<WebrtcFrameSchedulerSimple>(session_options_); scheduler_->Start(base::BindRepeating(&WebrtcVideoStream::CaptureNextFrame, base::Unretained(this))); - - video_stats_dispatcher_.Init(webrtc_transport->CreateOutgoingChannel( - video_stats_dispatcher_.channel_name()), - this); } void WebrtcVideoStream::SelectSource(int id) { @@ -179,16 +174,6 @@ std::move(current_frame_stats_)); } -void WebrtcVideoStream::OnChannelInitialized( - ChannelDispatcherBase* channel_dispatcher) { - DCHECK(&video_stats_dispatcher_ == channel_dispatcher); -} -void WebrtcVideoStream::OnChannelClosed( - ChannelDispatcherBase* channel_dispatcher) { - DCHECK(&video_stats_dispatcher_ == channel_dispatcher); - LOG(WARNING) << "video_stats channel was closed."; -} - void WebrtcVideoStream::CaptureNextFrame() { DCHECK(thread_checker_.CalledOnValidThread()); @@ -227,7 +212,7 @@ } // Send FrameStats message. - if (video_stats_dispatcher_.is_connected()) { + if (video_stats_dispatcher_ && video_stats_dispatcher_->is_connected()) { // The down-cast is safe, because the |stats| object was originally created // by this class and attached to the frame. const auto* current_frame_stats = @@ -273,7 +258,7 @@ // interface, and move this logic to the encoders. stats.frame_quality = (63 - frame.quantizer) * 100 / 63; - video_stats_dispatcher_.OnVideoFrameStats(result.frame_id, stats); + video_stats_dispatcher_->OnVideoFrameStats(result.frame_id, stats); } }
diff --git a/remoting/protocol/webrtc_video_stream.h b/remoting/protocol/webrtc_video_stream.h index 36a2805..52c80da2 100644 --- a/remoting/protocol/webrtc_video_stream.h +++ b/remoting/protocol/webrtc_video_stream.h
@@ -13,7 +13,6 @@ #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" #include "remoting/base/session_options.h" -#include "remoting/protocol/host_video_stats_dispatcher.h" #include "remoting/protocol/video_channel_state_observer.h" #include "remoting/protocol/video_stream.h" #include "remoting/protocol/webrtc_video_track_source.h" @@ -35,7 +34,6 @@ class WebrtcVideoStream : public VideoStream, public webrtc::DesktopCapturer::Callback, - public HostVideoStatsDispatcher::EventHandler, public VideoChannelStateObserver { public: explicit WebrtcVideoStream(const SessionOptions& options); @@ -45,6 +43,11 @@ ~WebrtcVideoStream() override; + void set_video_stats_dispatcher( + base::WeakPtr<HostVideoStatsDispatcher> video_stats_dispatcher) { + video_stats_dispatcher_ = video_stats_dispatcher; + } + void Start(std::unique_ptr<webrtc::DesktopCapturer> desktop_capturer, WebrtcTransport* webrtc_transport, WebrtcVideoEncoderFactory* video_encoder_factory); @@ -75,10 +78,6 @@ void OnCaptureResult(webrtc::DesktopCapturer::Result result, std::unique_ptr<webrtc::DesktopFrame> frame) override; - // HostVideoStatsDispatcher::EventHandler interface. - void OnChannelInitialized(ChannelDispatcherBase* channel_dispatcher) override; - void OnChannelClosed(ChannelDispatcherBase* channel_dispatcher) override; - // Called by the |scheduler_|. void CaptureNextFrame(); @@ -95,7 +94,7 @@ scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_; - HostVideoStatsDispatcher video_stats_dispatcher_; + base::WeakPtr<HostVideoStatsDispatcher> video_stats_dispatcher_; // Stats of the frame that's being captured. std::unique_ptr<FrameStats> current_frame_stats_;
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc index 049e921..6bcb599 100644 --- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc +++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy.cc
@@ -358,6 +358,14 @@ } #endif + // https://crbug.com/644759 + // https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3278691 + if (sysno == __NR_rt_tgsigqueueinfo) { + const Arg<pid_t> tgid(0); + return If(tgid == current_pid, Allow()) + .Else(Error(EPERM)); + } + if (IsBaselinePolicyWatched(sysno)) { // Previously unseen syscalls. TODO(jln): some of these should // be denied gracefully right away.
diff --git a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc index 7610acd..dfb80a61 100644 --- a/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc +++ b/sandbox/linux/seccomp-bpf-helpers/baseline_policy_android.cc
@@ -160,13 +160,6 @@ return RestrictPtrace(); } - // https://crbug.com/644759 - if (sysno == __NR_rt_tgsigqueueinfo) { - const Arg<pid_t> tgid(0); - return If(tgid == policy_pid(), Allow()) - .Else(Error(EPERM)); - } - // https://crbug.com/766245 if (sysno == __NR_process_vm_readv) { const Arg<pid_t> pid(0);
diff --git a/services/device/binder_overrides.cc b/services/device/binder_overrides.cc index 845eb38..cac7f1ac 100644 --- a/services/device/binder_overrides.cc +++ b/services/device/binder_overrides.cc
@@ -14,5 +14,12 @@ return *binder; } +#if defined(OS_ANDROID) +NFCProviderBinder& GetNFCProviderBinderOverride() { + static base::NoDestructor<NFCProviderBinder> binder; + return *binder; +} +#endif + } // namespace internal } // namespace device
diff --git a/services/device/binder_overrides.h b/services/device/binder_overrides.h index a000f15a..d6aa092 100644 --- a/services/device/binder_overrides.h +++ b/services/device/binder_overrides.h
@@ -7,9 +7,14 @@ #include "base/callback.h" #include "base/component_export.h" +#include "build/build_config.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "services/device/public/mojom/geolocation_context.mojom.h" +#if defined(OS_ANDROID) +#include "services/device/public/mojom/nfc_provider.mojom.h" +#endif + namespace device { namespace internal { @@ -18,6 +23,13 @@ COMPONENT_EXPORT(DEVICE_SERVICE_BINDER_OVERRIDES) GeolocationContextBinder& GetGeolocationContextBinderOverride(); +#if defined(OS_ANDROID) +using NFCProviderBinder = base::RepeatingCallback<void( + mojo::PendingReceiver<device::mojom::NFCProvider>)>; +COMPONENT_EXPORT(DEVICE_SERVICE_BINDER_OVERRIDES) +NFCProviderBinder& GetNFCProviderBinderOverride(); +#endif + } // namespace internal } // namespace device
diff --git a/services/device/device_service.cc b/services/device/device_service.cc index 0d6f225..b9ae467 100644 --- a/services/device/device_service.cc +++ b/services/device/device_service.cc
@@ -185,9 +185,19 @@ } #if defined(OS_ANDROID) +// static +void DeviceService::OverrideNFCProviderBinderForTesting( + NFCProviderBinder binder) { + internal::GetNFCProviderBinderOverride() = std::move(binder); +} + void DeviceService::BindNFCProvider( mojo::PendingReceiver<mojom::NFCProvider> receiver) { - GetJavaInterfaceProvider()->GetInterface(std::move(receiver)); + const auto& binder_override = internal::GetNFCProviderBinderOverride(); + if (binder_override) + binder_override.Run(std::move(receiver)); + else + GetJavaInterfaceProvider()->GetInterface(std::move(receiver)); } #endif
diff --git a/services/device/device_service.h b/services/device/device_service.h index a12af40e..0467202 100644 --- a/services/device/device_service.h +++ b/services/device/device_service.h
@@ -131,6 +131,13 @@ static void OverrideGeolocationContextBinderForTesting( GeolocationContextBinder binder); +#if defined(OS_ANDROID) + // Allows tests to override how frame hosts bind NFCProvider receivers. + using NFCProviderBinder = base::RepeatingCallback<void( + mojo::PendingReceiver<device::mojom::NFCProvider>)>; + static void OverrideNFCProviderBinderForTesting(NFCProviderBinder binder); +#endif + private: // mojom::DeviceService implementation: void BindFingerprint(
diff --git a/services/device/public/cpp/BUILD.gn b/services/device/public/cpp/BUILD.gn index 5812638..1590d80 100644 --- a/services/device/public/cpp/BUILD.gn +++ b/services/device/public/cpp/BUILD.gn
@@ -55,6 +55,13 @@ "test/test_wake_lock_provider.h", ] + if (is_android) { + sources += [ + "test/scoped_nfc_overrider.cc", + "test/scoped_nfc_overrider.h", + ] + } + public_deps = [ "//base", "//services/device/public/cpp/generic_sensor",
diff --git a/services/device/public/cpp/test/scoped_nfc_overrider.cc b/services/device/public/cpp/test/scoped_nfc_overrider.cc new file mode 100644 index 0000000..2a408fb --- /dev/null +++ b/services/device/public/cpp/test/scoped_nfc_overrider.cc
@@ -0,0 +1,99 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/device/public/cpp/test/scoped_nfc_overrider.h" +#include <memory> + +#include "base/bind.h" +#include "services/device/device_service.h" +#include "services/device/public/mojom/nfc.mojom.h" + +namespace device { + +namespace { + +// FakeNFC which can be connected to the corresponding instance in a renderer +// process. +class FakeNFC : public mojom::NFC { + public: + FakeNFC() = default; + ~FakeNFC() override = default; + + void Bind(mojo::PendingReceiver<mojom::NFC> receiver) { + receiver_.Bind(std::move(receiver)); + } + + // device::mojom::NFC: + void SetClient(mojo::PendingRemote<mojom::NFCClient> client) override {} + void Push(mojom::NDEFMessagePtr message, + mojom::NDEFWriteOptionsPtr, + PushCallback callback) override { + std::move(callback).Run(nullptr); + } + void CancelPush() override {} + void Watch(uint32_t id, WatchCallback callback) override { + std::move(callback).Run(nullptr); + } + void CancelWatch(uint32_t id) override {} + + private: + mojo::Receiver<mojom::NFC> receiver_{this}; +}; + +} // namespace + +// FakeNFCProvider which can be connected to the corresponding instance in the +// browser process. +class ScopedNFCOverrider::FakeNFCProvider : public mojom::NFCProvider { + public: + FakeNFCProvider() = default; + ~FakeNFCProvider() override = default; + + void Bind(mojo::PendingReceiver<mojom::NFCProvider> receiver) { + receiver_.Bind(std::move(receiver)); + receiver_.set_disconnect_handler(base::BindOnce( + &FakeNFCProvider::OnMojoDisconnect, base::Unretained(this))); + is_connected_ = true; + } + + void OnMojoDisconnect() { is_connected_ = false; } + + // device::mojom::NFCProvider: + void GetNFCForHost( + int32_t host_id, + mojo::PendingReceiver<device::mojom::NFC> receiver) override { + fake_nfc_.Bind(std::move(receiver)); + } + void SuspendNFCOperations() override {} + void ResumeNFCOperations() override {} + + bool is_connected() { return is_connected_; } + + private: + bool is_connected_{false}; + + FakeNFC fake_nfc_; + mojo::Receiver<mojom::NFCProvider> receiver_{this}; +}; + +ScopedNFCOverrider::ScopedNFCOverrider() { + fake_nfc_provider_ = std::make_unique<FakeNFCProvider>(); + DeviceService::OverrideNFCProviderBinderForTesting(base::BindRepeating( + &ScopedNFCOverrider::BindFakeNFCProvider, base::Unretained(this))); +} + +ScopedNFCOverrider::~ScopedNFCOverrider() { + DeviceService::OverrideNFCProviderBinderForTesting(base::NullCallback()); +} + +bool ScopedNFCOverrider::IsConnected() { + return fake_nfc_provider_->is_connected(); +} + +void ScopedNFCOverrider::BindFakeNFCProvider( + mojo::PendingReceiver<device::mojom::NFCProvider> receiver) { + fake_nfc_provider_->Bind(std::move(receiver)); +} + +} // namespace device
diff --git a/services/device/public/cpp/test/scoped_nfc_overrider.h b/services/device/public/cpp/test/scoped_nfc_overrider.h new file mode 100644 index 0000000..ae5d22f --- /dev/null +++ b/services/device/public/cpp/test/scoped_nfc_overrider.h
@@ -0,0 +1,36 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SERVICES_DEVICE_PUBLIC_CPP_TEST_SCOPED_NFC_OVERRIDER_H_ +#define SERVICES_DEVICE_PUBLIC_CPP_TEST_SCOPED_NFC_OVERRIDER_H_ + +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "services/device/public/mojom/nfc_provider.mojom.h" + +namespace device { + +// A helper class which overrides NFC instance for testing. Note that for this +// override to work properly, it must be constructed in the same process that +// runs the Device Service implementation. +class ScopedNFCOverrider { + public: + ScopedNFCOverrider(); + ~ScopedNFCOverrider(); + ScopedNFCOverrider(const ScopedNFCOverrider&) = delete; + ScopedNFCOverrider& operator=(const ScopedNFCOverrider&) = delete; + + // Return whether the mojo connection of NFC instance is connected. + bool IsConnected(); + + private: + class FakeNFCProvider; + + void BindFakeNFCProvider(mojo::PendingReceiver<mojom::NFCProvider> receiver); + + std::unique_ptr<FakeNFCProvider> fake_nfc_provider_; +}; + +} // namespace device + +#endif // SERVICES_DEVICE_PUBLIC_CPP_TEST_SCOPED_NFC_OVERRIDER_H_
diff --git a/services/device/public/mojom/BUILD.gn b/services/device/public/mojom/BUILD.gn index 01a7672..0af9514 100644 --- a/services/device/public/mojom/BUILD.gn +++ b/services/device/public/mojom/BUILD.gn
@@ -75,6 +75,7 @@ visibility_blink = [ "//third_party/blink/renderer/platform:blink_platform_public_deps", + "//third_party/blink/renderer/platform/media:*", "//third_party/blink/public/mojom:mojom_platform_blink", ] }
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc index da7f97c..f14c9986 100644 --- a/services/network/public/cpp/resource_request.cc +++ b/services/network/public/cpp/resource_request.cc
@@ -216,7 +216,6 @@ resource_type == request.resource_type && priority == request.priority && devtools_stack_id == request.devtools_stack_id && - should_reset_appcache == request.should_reset_appcache && is_external_request == request.is_external_request && cors_preflight_policy == request.cors_preflight_policy && originated_from_service_worker ==
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h index 7119f5b..7c835d2 100644 --- a/services/network/public/cpp/resource_request.h +++ b/services/network/public/cpp/resource_request.h
@@ -136,7 +136,6 @@ int load_flags = 0; int resource_type = 0; net::RequestPriority priority = net::IDLE; - bool should_reset_appcache = false; bool is_external_request = false; mojom::CorsPreflightPolicy cors_preflight_policy = mojom::CorsPreflightPolicy::kConsiderPreflight;
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc index 2c840cf..9fefb0c 100644 --- a/services/network/public/cpp/url_request_mojom_traits.cc +++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -198,7 +198,6 @@ data.update_first_party_url_on_redirect(); out->load_flags = data.load_flags(); out->resource_type = data.resource_type(); - out->should_reset_appcache = data.should_reset_appcache(); out->is_external_request = data.is_external_request(); out->originated_from_service_worker = data.originated_from_service_worker(); out->skip_service_worker = data.skip_service_worker();
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h index d401695..53b1cd2 100644 --- a/services/network/public/cpp/url_request_mojom_traits.h +++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -210,9 +210,6 @@ const network::ResourceRequest& request) { return request.priority; } - static bool should_reset_appcache(const network::ResourceRequest& request) { - return request.should_reset_appcache; - } static bool is_external_request(const network::ResourceRequest& request) { return request.is_external_request; }
diff --git a/services/network/public/cpp/url_request_mojom_traits_unittest.cc b/services/network/public/cpp/url_request_mojom_traits_unittest.cc index ec93331..111956b 100644 --- a/services/network/public/cpp/url_request_mojom_traits_unittest.cc +++ b/services/network/public/cpp/url_request_mojom_traits_unittest.cc
@@ -70,7 +70,6 @@ original.load_flags = 3; original.resource_type = 2; original.priority = net::IDLE; - original.should_reset_appcache = true; original.is_external_request = false; original.cors_preflight_policy = mojom::CorsPreflightPolicy::kConsiderPreflight;
diff --git a/services/network/public/mojom/network_service.mojom b/services/network/public/mojom/network_service.mojom index 7a7d0e3b..8fab775 100644 --- a/services/network/public/mojom/network_service.mojom +++ b/services/network/public/mojom/network_service.mojom
@@ -397,7 +397,7 @@ // when the raw headers represent untrustworthy input and the URLLoader used // lives in a non-sandboxed process. It can also happen from some exotic // URLLoader where parsing hasn't been implemented. - // In particular, this is used for request served from AppCache, WebBundle, + // In particular, this is used for request served from WebBundle, // Extensions, etc. ParseHeaders(url.mojom.Url url, HttpResponseHeaders headers) => (ParsedHeaders parsed_headers);
diff --git a/services/network/public/mojom/url_request.mojom b/services/network/public/mojom/url_request.mojom index 58733d9..27477d5 100644 --- a/services/network/public/mojom/url_request.mojom +++ b/services/network/public/mojom/url_request.mojom
@@ -242,9 +242,6 @@ // The priority of this request determined by Blink. RequestPriority priority; - // True if corresponding AppCache group should be reset. - bool should_reset_appcache; - // https://wicg.github.io/cors-rfc1918/#external-request // TODO(toyoshim): The browser should know better than renderers do. // This is used to plumb Blink decided information for legacy code path, but
diff --git a/services/network/public/mojom/url_response_head.mojom b/services/network/public/mojom/url_response_head.mojom index faa5ed32..76a0a19 100644 --- a/services/network/public/mojom/url_response_head.mojom +++ b/services/network/public/mojom/url_response_head.mojom
@@ -52,16 +52,6 @@ // True if the request accessed the network in the process of retrieving data. bool network_accessed = false; - // The appcache this response was loaded from, or - // kAppCacheNoCacheId (hard-coded as 0 because services/network - // can't take a dependency on Blink). - // TODO(rdsmith): Remove conceptual dependence on appcache. - int64 appcache_id = 0; - - // The manifest url of the appcache this response was loaded from. - // Note: this value is only populated for main resource requests. - url.mojom.Url appcache_manifest_url; - // Detailed timing information used by the WebTiming, HAR and Developer // Tools. Includes socket ID and socket reuse information. LoadTimingInfo load_timing;
diff --git a/services/network/radio_monitor_android.cc b/services/network/radio_monitor_android.cc index 1593e136..aa4f5387 100644 --- a/services/network/radio_monitor_android.cc +++ b/services/network/radio_monitor_android.cc
@@ -72,8 +72,17 @@ ? radio_activity_override_for_testing_ : base::android::RadioUtils::GetCellDataActivity(); - return radio_activity.has_value() && - *radio_activity == base::android::RadioDataActivity::kDormant; + if (!radio_activity.has_value()) + return false; + + // When the last activity was dormant, don't treat this event as a wakeup + // trigger since there could be state transition delay and startup latency. + bool should_record = + *radio_activity == base::android::RadioDataActivity::kDormant && + last_radio_data_activity_ != base::android::RadioDataActivity::kDormant; + last_radio_data_activity_ = *radio_activity; + + return should_record; } } // namespace network
diff --git a/services/network/radio_monitor_android.h b/services/network/radio_monitor_android.h index dcd7762..7afe7f0 100644 --- a/services/network/radio_monitor_android.h +++ b/services/network/radio_monitor_android.h
@@ -58,11 +58,16 @@ // overridden for testing. bool IsRadioUtilsSupported(); - // Returns true when radio data activity is dormant. + // Returns true when an incoming network event such as creating URLLoader and + // resolving a host name could trigger a radio wakeup. // TODO(crbug.com/1232623): Consider optimizing this function. This function // uses Android's platform APIs which add non-negligible overheads. bool ShouldRecordRadioWakeupTrigger(); + // Updated when ShouldRecordRadioWakeupTrigger() is called. + base::android::RadioDataActivity last_radio_data_activity_ = + base::android::RadioDataActivity::kNone; + // Radio state overrides for testing. absl::optional<base::android::RadioDataActivity> radio_activity_override_for_testing_;
diff --git a/storage/browser/quota/quota_manager_impl.h b/storage/browser/quota/quota_manager_impl.h index 718e177..266d392 100644 --- a/storage/browser/quota/quota_manager_impl.h +++ b/storage/browser/quota/quota_manager_impl.h
@@ -330,9 +330,9 @@ // bucket. Used by the Storage Bucket API for bucket deletion. If no bucket is // found, it will return QuotaStatusCode::kOk since it has no bucket data to // delete. - void FindAndDeleteBucketData(const blink::StorageKey& storage_key, - const std::string& bucket_name, - StatusCallback callback); + virtual void FindAndDeleteBucketData(const blink::StorageKey& storage_key, + const std::string& bucket_name, + StatusCallback callback); // Instructs each QuotaClient to remove possible traces of deleted // data on the disk.
diff --git a/storage/browser/test/mock_quota_manager.cc b/storage/browser/test/mock_quota_manager.cc index 0f935a65f..f245771 100644 --- a/storage/browser/test/mock_quota_manager.cc +++ b/storage/browser/test/mock_quota_manager.cc
@@ -14,6 +14,7 @@ #include "base/memory/ref_counted.h" #include "base/task/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "components/services/storage/public/cpp/buckets/bucket_locator.h" #include "storage/browser/quota/quota_client_type.h" using ::blink::StorageKey; @@ -173,11 +174,29 @@ } base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&MockQuotaManager::DidDeleteStorageKeyData, + FROM_HERE, base::BindOnce(&MockQuotaManager::DidDeleteBucketData, weak_factory_.GetWeakPtr(), std::move(callback), blink::mojom::QuotaStatusCode::kOk)); } +void MockQuotaManager::FindAndDeleteBucketData(const StorageKey& storage_key, + const std::string& bucket_name, + StatusCallback callback) { + QuotaErrorOr<BucketInfo> result = FindBucket( + storage_key, bucket_name, blink::mojom::StorageType::kTemporary); + if (!result.ok()) { + if (result.error() == QuotaError::kNotFound) { + std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk); + } else { + std::move(callback).Run(blink::mojom::QuotaStatusCode::kUnknown); + } + return; + } + + DeleteBucketData(result->ToBucketLocator(), AllQuotaClientTypes(), + std::move(callback)); +} + void MockQuotaManager::NotifyWriteFailed(const StorageKey& storage_key) { auto storage_key_error_log = write_error_tracker_.insert(std::pair<StorageKey, int>(storage_key, 0)) @@ -223,7 +242,7 @@ std::move(callback).Run(*buckets, storage_type); } -void MockQuotaManager::DidDeleteStorageKeyData( +void MockQuotaManager::DidDeleteBucketData( StatusCallback callback, blink::mojom::QuotaStatusCode status) { std::move(callback).Run(status);
diff --git a/storage/browser/test/mock_quota_manager.h b/storage/browser/test/mock_quota_manager.h index cb6e5b9..ce5ea607 100644 --- a/storage/browser/test/mock_quota_manager.h +++ b/storage/browser/test/mock_quota_manager.h
@@ -83,6 +83,13 @@ QuotaClientTypes quota_client_types, StatusCallback callback) override; + // Finds and removes a bucket from the canned list of buckets, but doesn't + // touch anything on disk. Will remove bucket data from all QuotaClientTypes. + // Will return kOk if deletion is successful or there is no bucket to delete. + void FindAndDeleteBucketData(const blink::StorageKey& storage_key, + const std::string& bucket_name, + StatusCallback callback) override; + // Overrides QuotaManager's implementation so that tests can observe // calls to this function. void NotifyWriteFailed(const blink::StorageKey& storage_key) override; @@ -179,8 +186,8 @@ GetBucketsCallback callback, std::unique_ptr<std::set<BucketLocator>> buckets, blink::mojom::StorageType storage_type); - void DidDeleteStorageKeyData(StatusCallback callback, - blink::mojom::QuotaStatusCode status); + void DidDeleteBucketData(StatusCallback callback, + blink::mojom::QuotaStatusCode status); BucketId::Generator bucket_id_generator_;
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 37018d9e..4c46614 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -5787,7 +5787,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.52" + "revision": "version:96.0.4664.54" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -5875,7 +5875,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M97", - "revision": "version:97.0.4692.17" + "revision": "version:97.0.4692.21" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -6051,7 +6051,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.52" + "revision": "version:96.0.4664.54" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -6139,7 +6139,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M97", - "revision": "version:97.0.4692.17" + "revision": "version:97.0.4692.21" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index a0caa03..5721a43 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -43662,7 +43662,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.52" + "revision": "version:96.0.4664.54" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -43750,7 +43750,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M97", - "revision": "version:97.0.4692.17" + "revision": "version:97.0.4692.21" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -43926,7 +43926,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.52" + "revision": "version:96.0.4664.54" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -44014,7 +44014,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M97", - "revision": "version:97.0.4692.17" + "revision": "version:97.0.4692.21" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -44265,7 +44265,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.52" + "revision": "version:96.0.4664.54" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -44353,7 +44353,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M97", - "revision": "version:97.0.4692.17" + "revision": "version:97.0.4692.21" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -44529,7 +44529,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.52" + "revision": "version:96.0.4664.54" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -44617,7 +44617,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M97", - "revision": "version:97.0.4692.17" + "revision": "version:97.0.4692.21" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -44868,7 +44868,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.52" + "revision": "version:96.0.4664.54" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -44956,7 +44956,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M97", - "revision": "version:97.0.4692.17" + "revision": "version:97.0.4692.21" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -45132,7 +45132,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M96", - "revision": "version:96.0.4664.52" + "revision": "version:96.0.4664.54" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}", @@ -45220,7 +45220,7 @@ { "cipd_package": "chromium/testing/weblayer-x86", "location": "weblayer_instrumentation_test_M97", - "revision": "version:97.0.4692.17" + "revision": "version:97.0.4692.21" }, { "cipd_package": "infra/tools/luci/logdog/butler/${platform}",
diff --git a/testing/buildbot/filters/mac.mac11-arm64-rel.browser_tests.filter b/testing/buildbot/filters/mac.mac11-arm64-rel.browser_tests.filter index 47a5ef584..fd8de02 100644 --- a/testing/buildbot/filters/mac.mac11-arm64-rel.browser_tests.filter +++ b/testing/buildbot/filters/mac.mac11-arm64-rel.browser_tests.filter
@@ -17,3 +17,4 @@ -BackForwardCachePageLoadMetricsObserverBrowserTest.ResumesLoggingAfterRestoringFromCacheAfterBackgrounding -WebAppBrowserTest.WebAppCreateAndDeleteShortcut -SaveAsMhtml/SavePageOriginalVsSavedComparisonTest.NestedFrames/0 +-WorkerDevToolsTest.PauseInSharedWorkerInitialization
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 61eee04b..ba3ef40 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -1473,6 +1473,7 @@ "label": "//chrome/test:performance_webview_test_suite", "script": "//third_party/catapult/devil/devil/android/tools/system_app.py", "type": "script", + "python3": True, }, "performance_weblayer_test_suite": { "args": [ @@ -1481,6 +1482,7 @@ "label": "//chrome/test:performance_weblayer_test_suite", "script": "//testing/scripts/run_performance_tests.py", "type": "script", + "python3": True, }, "polymer_tools_python_unittests": { "args": [
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 789874d..9699606b 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -30,6 +30,11 @@ 'shards': 2, }, }, + 'android-marshmallow-arm64-rel-rts': { + 'swarming': { + 'shards': 2, + }, + }, 'android-marshmallow-x86-rel': { 'swarming': { 'shards': 2, @@ -64,6 +69,7 @@ 'remove_from': [ # Remove from CQ bots due to capacity. 'android-marshmallow-arm64-rel', + 'android-marshmallow-arm64-rel-rts', ], }, 'android_webview_unittests': { @@ -1083,6 +1089,7 @@ 'remove_from': [ # https://crbug.com/1147531 - covered on marshmallow emulator. 'android-marshmallow-arm64-rel', + 'android-marshmallow-arm64-rel-rts', ], 'modifications': { 'Linux ASan LSan Tests (1)': { @@ -1147,6 +1154,7 @@ 'remove_from': [ 'CrWinAsan(dll)', # https://crbug.com/935598 'android-marshmallow-arm64-rel', # http://crbug.com/1060245#c30: due to low utility and capacity. + 'android-marshmallow-arm64-rel-rts', ], 'modifications': { 'Cast Audio Linux': { @@ -2359,6 +2367,7 @@ 'android-code-coverage', 'android-code-coverage-native', 'android-marshmallow-arm64-rel', + 'android-marshmallow-arm64-rel-rts', 'android-marshmallow-x86-rel-non-cq', 'android-pie-arm64-coverage-experimental-rel', # Does not generate profraw data. 'android-pie-arm64-rel', @@ -2783,6 +2792,7 @@ 'remove_from': [ # Monochrome isn't supported on M. 'android-marshmallow-arm64-rel', + 'android-marshmallow-arm64-rel-rts', 'android-marshmallow-x86-rel-non-cq', ], }, @@ -2863,6 +2873,7 @@ # marshmallow on the CQ. https://crbug.com/1026487. # TODO(crbug/1260494): Test suite isn't running on android. 'android-marshmallow-arm64-rel', + 'android-marshmallow-arm64-rel-rts', 'android-pie-arm64-rel', # crbug.com/936540 'Mac10.11 Tests', @@ -3249,6 +3260,7 @@ 'Win 7 Tests x64 (1)', # Runs on android-marshmallow-x86-rel already (crbug.com/1127110) 'android-marshmallow-arm64-rel', + 'android-marshmallow-arm64-rel-rts', 'android-marshmallow-x86-rel-non-cq', ], 'modifications': { @@ -3421,6 +3433,7 @@ # from android-marshmallow-arm64-rel-swarming). # https://crbug.com/1147531 - covered on pie 'android-marshmallow-arm64-rel', + 'android-marshmallow-arm64-rel-rts', ], 'modifications': { # chromium.android.fyi
diff --git a/testing/buildbot/tryserver.chromium.android.json b/testing/buildbot/tryserver.chromium.android.json index b9cf5c1..f958f6e 100644 --- a/testing/buildbot/tryserver.chromium.android.json +++ b/testing/buildbot/tryserver.chromium.android.json
@@ -1,6 +1,3890 @@ { "AAAAA1 AUTOGENERATED FILE DO NOT EDIT": {}, "AAAAA2 See generate_buildbot_json.py to make changes": {}, + "android-marshmallow-arm64-rel-rts": { + "additional_compile_targets": [ + "cronet_test_instrumentation_apk", + "chrome_nocompile_tests", + "monochrome_static_initializers", + "weblayer_shell" + ], + "gtest_tests": [ + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "absl_hardening_tests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "absl_hardening_tests", + "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "android_browsertests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "android_browsertests", + "test_id_prefix": "ninja://chrome/test:android_browsertests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "android_webview_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "android_webview_unittests", + "test_id_prefix": "ninja://android_webview/test:android_webview_unittests/" + }, + { + "args": [ + "angle_unittests", + "-v" + ], + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "angle_unittests", + "test_id_prefix": "ninja://third_party/angle/src/tests:angle_unittests/", + "use_isolated_scripts_api": true + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "base_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "base_unittests", + "test_id_prefix": "ninja://base:base_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "blink_common_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_common_unittests", + "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "blink_heap_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_heap_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform/heap:blink_heap_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "blink_platform_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_platform_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "boringssl_crypto_tests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "boringssl_crypto_tests", + "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "boringssl_ssl_tests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "boringssl_ssl_tests", + "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "breakpad_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "breakpad_unittests", + "test_id_prefix": "ninja://third_party/breakpad:breakpad_unittests/" + }, + { + "args": [ + "--gtest_filter=-*UsingRealWebcam*", + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "capture_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "capture_unittests", + "test_id_prefix": "ninja://media/capture:capture_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "cast_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cast_unittests", + "test_id_prefix": "ninja://media/cast:cast_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "cc_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cc_unittests", + "test_id_prefix": "ninja://cc:cc_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_modern_public_bundle_fake_modules_smoke_test" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "chrome_modern_public_bundle_fake_modules_smoke_test", + "test_id_prefix": "ninja://chrome/android:chrome_modern_public_bundle_fake_modules_smoke_test/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_modern_public_bundle_smoke_test" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "chrome_modern_public_bundle_smoke_test", + "test_id_prefix": "ninja://chrome/android:chrome_modern_public_bundle_smoke_test/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_public_smoke_test" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "chrome_public_smoke_test", + "test_id_prefix": "ninja://chrome/android:chrome_public_smoke_test/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--git-revision=${got_revision}" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_public_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chrome-gold@chops-service-accounts.iam.gserviceaccount.com", + "shards": 20 + }, + "test": "chrome_public_test_apk", + "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/" + }, + { + "args": [ + "--shared-prefs-file=//chrome/android/shared_preference_files/test/vr_cardboard_skipdon_setupcomplete.json", + "--additional-apk=//third_party/gvr-android-sdk/test-apks/vr_services/vr_services_current.apk", + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_public_test_vr_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "chrome_public_test_vr_apk", + "test_id_prefix": "ninja://chrome/android:chrome_public_test_vr_apk/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--git-revision=${got_revision}" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_public_unit_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chrome-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "chrome_public_unit_test_apk", + "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "components_browsertests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "components_browsertests", + "test_id_prefix": "ninja://components:components_browsertests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "content_shell_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "content_shell_test_apk", + "test_id_prefix": "ninja://content/shell/android:content_shell_test_apk/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "content_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "content_unittests", + "test_id_prefix": "ninja://content/test:content_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "crashpad_tests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "crashpad_tests", + "test_id_prefix": "ninja://third_party/crashpad/crashpad:crashpad_tests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "crypto_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "crypto_unittests", + "test_id_prefix": "ninja://crypto:crypto_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "device_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "device_unittests", + "test_id_prefix": "ninja://device:device_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "display_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "display_unittests", + "test_id_prefix": "ninja://ui/display:display_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "events_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "events_unittests", + "test_id_prefix": "ninja://ui/events:events_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "gcm_unit_tests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gcm_unit_tests", + "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "gfx_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gfx_unittests", + "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "gin_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gin_unittests", + "test_id_prefix": "ninja://gin:gin_unittests/" + }, + { + "args": [ + "--use-cmd-decoder=validating", + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "gl_tests_validating" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "name": "gl_tests_validating", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gl_tests", + "test_id_prefix": "ninja://gpu:gl_tests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "gl_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gl_unittests", + "test_id_prefix": "ninja://ui/gl:gl_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "google_apis_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "google_apis_unittests", + "test_id_prefix": "ninja://google_apis:google_apis_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "gpu_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gpu_unittests", + "test_id_prefix": "ninja://gpu:gpu_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "gwp_asan_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "gwp_asan_unittests", + "test_id_prefix": "ninja://components/gwp_asan:gwp_asan_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "ipc_tests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ipc_tests", + "test_id_prefix": "ninja://ipc:ipc_tests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "jingle_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "jingle_unittests", + "test_id_prefix": "ninja://jingle:jingle_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "latency_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "latency_unittests", + "test_id_prefix": "ninja://ui/latency:latency_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "libjingle_xmpp_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "libjingle_xmpp_unittests", + "test_id_prefix": "ninja://third_party/libjingle_xmpp:libjingle_xmpp_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "liburlpattern_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "liburlpattern_unittests", + "test_id_prefix": "ninja://third_party/liburlpattern:liburlpattern_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "media_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "media_unittests", + "test_id_prefix": "ninja://media:media_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "midi_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "midi_unittests", + "test_id_prefix": "ninja://media/midi:midi_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "mojo_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "mojo_test_apk", + "test_id_prefix": "ninja://mojo/public/java/system:mojo_test_apk/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "mojo_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "mojo_unittests", + "test_id_prefix": "ninja://mojo:mojo_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "net_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 3 + }, + "test": "net_unittests", + "test_id_prefix": "ninja://net:net_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "sandbox_linux_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "sandbox_linux_unittests", + "test_id_prefix": "ninja://sandbox/linux:sandbox_linux_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "services_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "services_unittests", + "test_id_prefix": "ninja://services:services_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "shell_dialogs_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "shell_dialogs_unittests", + "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "skia_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "skia_unittests", + "test_id_prefix": "ninja://skia:skia_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "sql_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "sql_unittests", + "test_id_prefix": "ninja://sql:sql_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "storage_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "storage_unittests", + "test_id_prefix": "ninja://storage:storage_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "ui_android_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ui_android_unittests", + "test_id_prefix": "ninja://ui/android:ui_android_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "ui_base_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ui_base_unittests", + "test_id_prefix": "ninja://ui/base:ui_base_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "ui_touch_selection_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "ui_touch_selection_unittests", + "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "unit_tests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "unit_tests", + "test_id_prefix": "ninja://chrome/test:unit_tests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "url_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "url_unittests", + "test_id_prefix": "ninja://url:url_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "ci_only": true, + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "viz_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "viz_unittests", + "test_id_prefix": "ninja://components/viz:viz_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "vr_android_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "vr_android_unittests", + "test_id_prefix": "ninja://chrome/browser/android/vr:vr_android_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "vr_common_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "vr_common_unittests", + "test_id_prefix": "ninja://chrome/browser/vr:vr_common_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "vr_pixeltests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "vr_pixeltests", + "test_id_prefix": "ninja://chrome/browser/vr:vr_pixeltests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "weblayer_browsertests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "weblayer_browsertests", + "test_id_prefix": "ninja://weblayer/test:weblayer_browsertests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "weblayer_bundle_test" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "weblayer_bundle_test", + "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_bundle_test/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "weblayer_instrumentation_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "weblayer_instrumentation_test_apk", + "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_instrumentation_test_apk/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "weblayer_private_instrumentation_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "weblayer_private_instrumentation_test_apk", + "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_private_instrumentation_test_apk/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "weblayer_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "weblayer_unittests", + "test_id_prefix": "ninja://weblayer/test:weblayer_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "wtf_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "wtf_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "isolate_profile_data": true, + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "zlib_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "zlib_unittests", + "test_id_prefix": "ninja://third_party/zlib:zlib_unittests/" + } + ], + "isolated_scripts": [ + { + "args": [ + "--gtest-benchmark-name=components_perftests" + ], + "isolate_name": "components_perftests", + "isolate_profile_data": true, + "merge": { + "args": [ + "--smoke-test-mode" + ], + "script": "//tools/perf/process_perf_results.py" + }, + "name": "components_perftests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://components:components_perftests/" + }, + { + "args": [ + "--platform=android" + ], + "isolate_name": "content_shell_crash_test", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "content_shell_crash_test", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://content/shell:content_shell_crash_test/" + }, + { + "args": [ + "BrowserMinidumpTest", + "--browser=android-chromium", + "-v", + "--passthrough", + "--retry-limit=2" + ], + "isolate_name": "telemetry_perf_unittests_android_chrome", + "isolate_profile_data": true, + "merge": { + "args": [], + "script": "//testing/merge_scripts/standard_isolated_script_merge.py" + }, + "name": "telemetry_chromium_minidump_unittests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_os_type": "userdebug", + "device_type": "bullhead", + "os": "Android" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test_id_prefix": "ninja://chrome/test:telemetry_perf_unittests_android_chrome/" + } + ], + "junit_tests": [ + { + "isolate_profile_data": true, + "name": "android_webview_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "android_webview_junit_tests", + "test_id_prefix": "ninja://android_webview/test:android_webview_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "base_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "base_junit_tests", + "test_id_prefix": "ninja://base:base_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "chrome_java_test_pagecontroller_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "chrome_java_test_pagecontroller_junit_tests", + "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "chrome_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "chrome_junit_tests", + "test_id_prefix": "ninja://chrome/android:chrome_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "components_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "components_junit_tests", + "test_id_prefix": "ninja://components:components_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "content_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "content_junit_tests", + "test_id_prefix": "ninja://content/public/android:content_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "device_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "device_junit_tests", + "test_id_prefix": "ninja://device:device_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "incremental_javac_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "incremental_javac_junit_tests", + "test_id_prefix": "ninja://build/android/test:incremental_javac_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "junit_unit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "junit_unit_tests", + "test_id_prefix": "ninja://testing/android/junit:junit_unit_tests/" + }, + { + "isolate_profile_data": true, + "name": "keyboard_accessory_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "keyboard_accessory_junit_tests", + "test_id_prefix": "ninja://chrome/android/features/keyboard_accessory:keyboard_accessory_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "media_base_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "media_base_junit_tests", + "test_id_prefix": "ninja://media/base/android:media_base_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "module_installer_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "module_installer_junit_tests", + "test_id_prefix": "ninja://components/module_installer/android:module_installer_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "net_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "net_junit_tests", + "test_id_prefix": "ninja://net/android:net_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "paint_preview_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "paint_preview_junit_tests", + "test_id_prefix": "ninja://components/paint_preview/player/android:paint_preview_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "password_check_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "password_check_junit_tests", + "test_id_prefix": "ninja://chrome/browser/password_check/android:password_check_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "password_manager_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "password_manager_junit_tests", + "test_id_prefix": "ninja://chrome/browser/password_manager/android:password_manager_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "services_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "services_junit_tests", + "test_id_prefix": "ninja://services:services_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "touch_to_fill_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "touch_to_fill_junit_tests", + "test_id_prefix": "ninja://chrome/browser/touch_to_fill/android:touch_to_fill_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "ui_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "ui_junit_tests", + "test_id_prefix": "ninja://ui/android:ui_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "webapk_client_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "webapk_client_junit_tests", + "test_id_prefix": "ninja://chrome/android/webapk/libs/client:webapk_client_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "webapk_shell_apk_h2o_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "webapk_shell_apk_h2o_junit_tests", + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_h2o_junit_tests/" + }, + { + "isolate_profile_data": true, + "name": "webapk_shell_apk_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "webapk_shell_apk_junit_tests", + "test_id_prefix": "ninja://chrome/android/webapk/shell_apk:webapk_shell_apk_junit_tests/" + }, + { + "experiment_percentage": 100, + "isolate_profile_data": true, + "name": "weblayer_junit_tests", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": {}, + "test": "weblayer_junit_tests", + "test_id_prefix": "ninja://weblayer/browser/java:weblayer_junit_tests/" + } + ], + "scripts": [ + { + "isolate_profile_data": true, + "name": "check_network_annotations", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "script": "check_network_annotations.py", + "swarming": {} + } + ] + }, "android-opus-arm-rel": { "gtest_tests": [ { @@ -53,6 +3937,1066 @@ } ] }, + "android-pie-arm64-rel-rts": { + "additional_compile_targets": [ + "monochrome_static_initializers", + "weblayer_shell" + ], + "gtest_tests": [ + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "android_browsertests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "android_browsertests", + "test_id_prefix": "ninja://chrome/test:android_browsertests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "blink_platform_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "blink_platform_unittests", + "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "cc_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "cc_unittests", + "test_id_prefix": "ninja://cc:cc_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_java_test_pagecontroller_tests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "chrome_java_test_pagecontroller_tests", + "test_id_prefix": "ninja://chrome/test/android:chrome_java_test_pagecontroller_tests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_public_smoke_test" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "chrome_public_smoke_test", + "test_id_prefix": "ninja://chrome/android:chrome_public_smoke_test/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--git-revision=${got_revision}" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_public_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chrome-gold@chops-service-accounts.iam.gserviceaccount.com", + "shards": 20 + }, + "test": "chrome_public_test_apk", + "test_id_prefix": "ninja://chrome/android:chrome_public_test_apk/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices", + "--git-revision=${got_revision}" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_public_unit_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "precommit_args": [ + "--gerrit-issue=${patch_issue}", + "--gerrit-patchset=${patch_set}", + "--buildbucket-id=${buildbucket_build_id}" + ], + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chrome-gold@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "chrome_public_unit_test_apk", + "test_id_prefix": "ninja://chrome/android:chrome_public_unit_test_apk/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "chrome_webapk_integration_tests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "chrome_webapk_integration_tests", + "test_id_prefix": "ninja://chrome/test/android:chrome_webapk_integration_tests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "content_browsertests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 15 + }, + "test": "content_browsertests", + "test_id_prefix": "ninja://content/test:content_browsertests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "monochrome_public_bundle_fake_modules_smoke_test" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "monochrome_public_bundle_fake_modules_smoke_test", + "test_id_prefix": "ninja://chrome/android:monochrome_public_bundle_fake_modules_smoke_test/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "monochrome_public_bundle_smoke_test" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "monochrome_public_bundle_smoke_test", + "test_id_prefix": "ninja://chrome/android:monochrome_public_bundle_smoke_test/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "monochrome_public_smoke_test" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "monochrome_public_smoke_test", + "test_id_prefix": "ninja://chrome/android:monochrome_public_smoke_test/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "viz_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "viz_unittests", + "test_id_prefix": "ninja://components/viz:viz_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "weblayer_browsertests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "weblayer_browsertests", + "test_id_prefix": "ninja://weblayer/test:weblayer_browsertests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "weblayer_bundle_test" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "weblayer_bundle_test", + "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_bundle_test/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "weblayer_instrumentation_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "weblayer_instrumentation_test_apk", + "test_id_prefix": "ninja://weblayer/browser/android/javatests:weblayer_instrumentation_test_apk/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "weblayer_unittests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "weblayer_unittests", + "test_id_prefix": "ninja://weblayer/test:weblayer_unittests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "webview_64_cts_tests" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "chromium/android_webview/tools/cts_archive", + "location": "android_webview/tools/cts_archive", + "revision": "ai8Ig4HlO0vG6aP_JP2uhyruE2yPzze8PFP1g8Z4_hgC" + }, + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 + }, + "test": "webview_64_cts_tests", + "test_id_prefix": "ninja://android_webview/test:webview_64_cts_tests/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "webview_instrumentation_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 7 + }, + "test": "webview_instrumentation_test_apk", + "test_id_prefix": "ninja://android_webview/test:webview_instrumentation_test_apk/" + }, + { + "args": [ + "--gs-results-bucket=chromium-result-details", + "--recover-devices" + ], + "merge": { + "args": [ + "--bucket", + "chromium-result-details", + "--test-name", + "webview_ui_test_app_test_apk" + ], + "script": "//build/android/pylib/results/presentation/test_results_presentation.py" + }, + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" + } + ], + "dimension_sets": [ + { + "device_os": "PQ3A.190801.002", + "device_os_flavor": "google", + "device_os_type": "userdebug", + "device_type": "walleye", + "os": "Android" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ], + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + }, + "test": "webview_ui_test_app_test_apk", + "test_id_prefix": "ninja://android_webview/tools/automated_ui_tests:webview_ui_test_app_test_apk/" + } + ], + "scripts": [ + { + "name": "check_network_annotations", + "resultdb": { + "enable": true, + "has_native_resultdb_integration": true + }, + "script": "check_network_annotations.py", + "swarming": {} + } + ] + }, "android_blink_rel": { "gtest_tests": [ {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index 389a124..c955e1dc 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -363,7 +363,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M97', - 'revision': 'version:97.0.4692.17', + 'revision': 'version:97.0.4692.21', } ], }, @@ -387,7 +387,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M96', - 'revision': 'version:96.0.4664.52', + 'revision': 'version:96.0.4664.54', } ], }, @@ -435,7 +435,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M97', - 'revision': 'version:97.0.4692.17', + 'revision': 'version:97.0.4692.21', } ], }, @@ -459,7 +459,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M96', - 'revision': 'version:96.0.4664.52', + 'revision': 'version:96.0.4664.54', } ], }, @@ -507,7 +507,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M97', - 'revision': 'version:97.0.4692.17', + 'revision': 'version:97.0.4692.21', } ], }, @@ -531,7 +531,7 @@ { 'cipd_package': 'chromium/testing/weblayer-x86', 'location': 'weblayer_instrumentation_test_M96', - 'revision': 'version:96.0.4664.52', + 'revision': 'version:96.0.4664.54', } ], },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index f52d868..274b6da 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -898,6 +898,7 @@ }, 'os_type': 'android', }, + # To be kept in sync with android-marshmallow-arm64-rel-rts 'android-marshmallow-arm64-rel': { 'mixins': [ 'has_native_resultdb_integration', @@ -979,6 +980,7 @@ 'gtest_tests': 'android_pie_gtests', } }, + # To be kept in sync with android-pie-arm64-rel-rts 'android-pie-arm64-rel': { 'mixins': [ 'has_native_resultdb_integration', @@ -6441,6 +6443,28 @@ 'name': 'tryserver.chromium.android', 'mixins': ['chromium-tester-service-account'], 'machines': { + # To be kept in sync with android-marshmallow-arm64-rel + 'android-marshmallow-arm64-rel-rts': { + 'mixins': [ + 'has_native_resultdb_integration', + 'bullhead', + 'isolate_profile_data', + 'marshmallow', + ], + 'additional_compile_targets': [ + 'cronet_test_instrumentation_apk', + 'chrome_nocompile_tests', + 'monochrome_static_initializers', + 'weblayer_shell', + ], + 'test_suites': { + 'gtest_tests': 'android_marshmallow_device_gtests', + 'junit_tests': 'chromium_junit_tests', + 'isolated_scripts': 'marshmallow_pie_isolated_scripts', + 'scripts': 'chromium_android_scripts', + }, + 'os_type': 'android', + }, 'android-opus-arm-rel': { 'mixins': [ 'marshmallow', @@ -6451,6 +6475,27 @@ }, 'os_type': 'android', }, + # To be kept in sync with android-pie-arm64-rel + 'android-pie-arm64-rel-rts': { + 'mixins': [ + 'has_native_resultdb_integration', + 'pie_fleet', + 'walleye', + ], + 'additional_compile_targets': [ + 'monochrome_static_initializers', + 'weblayer_shell', + ], + 'test_suites': { + 'gtest_tests': 'android_pie_rel_gtests', + # TODO(crbug.com/1111436): Re-enable this if/when additional capacity + # has been deployed. + #'isolated_scripts': 'marshmallow_nougat_pie_isolated_scripts_with_proguard', + 'scripts': 'chromium_android_scripts', + }, + 'use_swarming': True, + 'os_type': 'android', + }, 'android_blink_rel': { 'mixins': [ 'marshmallow',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 6780a43..d0b6e4f 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2163,21 +2163,6 @@ ] } ], - "ChromeOSLanguageSettingsUpdate2": [ - { - "platforms": [ - "chromeos" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "LanguageSettingsUpdate2" - ] - } - ] - } - ], "ChromeOSNeuralPalm": [ { "platforms": [ @@ -2697,24 +2682,6 @@ ] } ], - "ContextMenuSearchWithGoogleLens": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "EnabledWithUpdatedMenuItemString_20210325", - "params": { - "useSearchImageWithGoogleLensItemName": "true" - }, - "enable_features": [ - "ContextMenuSearchWithGoogleLens" - ] - } - ] - } - ], "ContextMenuShopWithGoogleLens": [ { "platforms": [ @@ -7434,23 +7401,6 @@ ] } ], - "SharingHubDesktop": [ - { - "platforms": [ - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "SharingHubDesktopOmnibox" - ] - } - ] - } - ], "SharingHubLinkToggle": [ { "platforms": [
diff --git a/third_party/blink/common/web_preferences/web_preferences.cc b/third_party/blink/common/web_preferences/web_preferences.cc index db2d0536..045b29c01 100644 --- a/third_party/blink/common/web_preferences/web_preferences.cc +++ b/third_party/blink/common/web_preferences/web_preferences.cc
@@ -61,7 +61,6 @@ data_saver_holdback_web_api_enabled(false), local_storage_enabled(false), databases_enabled(false), - application_cache_enabled(false), tabs_to_links(true), disable_ipc_flooding_protection(false), hyperlink_auditing_enabled(true),
diff --git a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc index e9f2e215..f58fe2d 100644 --- a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc +++ b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc
@@ -80,7 +80,6 @@ data.data_saver_holdback_web_api_enabled(); out->local_storage_enabled = data.local_storage_enabled(); out->databases_enabled = data.databases_enabled(); - out->application_cache_enabled = data.application_cache_enabled(); out->tabs_to_links = data.tabs_to_links(); out->disable_ipc_flooding_protection = data.disable_ipc_flooding_protection(); out->hyperlink_auditing_enabled = data.hyperlink_auditing_enabled();
diff --git a/third_party/blink/public/common/frame/event_page_show_persisted.h b/third_party/blink/public/common/frame/event_page_show_persisted.h index 1a1b5e3..1277106 100644 --- a/third_party/blink/public/common/frame/event_page_show_persisted.h +++ b/third_party/blink/public/common/frame/event_page_show_persisted.h
@@ -22,6 +22,9 @@ // should be almost the same as kYesInRenderer. See crbug.com/1234634. kYesInBrowser = 2, + // TODO(https://crbug.com/1234634): Below here is for tracking down the + // mismatch. Remove these when debugging is complete. + // Browser triggers a pageshow event with persisted flag, counted in the // back-forward cache code. The recorded count should be almost the same as // kYesInRenderer. See crbug.com/1234634. @@ -29,10 +32,22 @@ kYesInBrowser_BackForwardCache_RestoreEntry_Attempt = 4, kYesInBrowser_BackForwardCache_RestoreEntry_Succeed = 5, kYesInBrowser_RenderFrameHostManager_CommitPending = 6, + + // Renderer has a received a state with + // `should_dispatch_pageshow_for_debugging` set to true. + kBrowserYesInRenderer = 7, + + // As kBrowserYesInRenderer but we have confirmed that we have a Page object. + kBrowserYesInRendererWithPage = 8, + + // Browser received an ACK after sending state with + // `should_dispatch_pageshow_for_debugging` set to true. + kYesInBrowserAck = 9, + // There is not kNoInBrowser as we don't have to compare the counts of // pageshow events without persisted between browser and renderer so far. - kMaxValue = kYesInBrowser_RenderFrameHostManager_CommitPending, + kMaxValue = kYesInBrowserAck, }; BLINK_COMMON_EXPORT void RecordUMAEventPageShowPersisted(
diff --git a/third_party/blink/public/common/web_preferences/web_preferences.h b/third_party/blink/public/common/web_preferences/web_preferences.h index 0d74719b..42c089b 100644 --- a/third_party/blink/public/common/web_preferences/web_preferences.h +++ b/third_party/blink/public/common/web_preferences/web_preferences.h
@@ -81,7 +81,6 @@ bool data_saver_holdback_web_api_enabled; bool local_storage_enabled; bool databases_enabled; - bool application_cache_enabled; bool tabs_to_links; bool disable_ipc_flooding_protection; bool hyperlink_auditing_enabled;
diff --git a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h index e008459..e5fa468 100644 --- a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h +++ b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h
@@ -155,11 +155,6 @@ return r.databases_enabled; } - static bool application_cache_enabled( - const blink::web_pref::WebPreferences& r) { - return r.application_cache_enabled; - } - static bool tabs_to_links(const blink::web_pref::WebPreferences& r) { return r.tabs_to_links; }
diff --git a/third_party/blink/public/mojom/buckets/bucket_manager_host.mojom b/third_party/blink/public/mojom/buckets/bucket_manager_host.mojom index 5e0d2909..fffff86 100644 --- a/third_party/blink/public/mojom/buckets/bucket_manager_host.mojom +++ b/third_party/blink/public/mojom/buckets/bucket_manager_host.mojom
@@ -67,9 +67,10 @@ interface BucketManagerHost { // Open or create or bucket with the specified name and policies. // On success, it will return a mojo data pipe to the BucketHost in the - // browser process. + // browser process. Returns a null remote on error, e.g. if the storage bucket + // failed to be created or retrieved due to a database error. OpenBucket(string name, BucketPolicies policy) - => (pending_remote<BucketHost> remote); + => (pending_remote<BucketHost>? remote); // Returns a list of stored bucket names in alphabetical order. Keys() => (array<string> buckets, bool success);
diff --git a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom index af5ba07..3dba1b2 100644 --- a/third_party/blink/public/mojom/webpreferences/web_preferences.mojom +++ b/third_party/blink/public/mojom/webpreferences/web_preferences.mojom
@@ -137,7 +137,6 @@ bool data_saver_holdback_web_api_enabled; bool local_storage_enabled; bool databases_enabled; - bool application_cache_enabled; bool tabs_to_links; bool disable_ipc_flooding_protection; bool hyperlink_auditing_enabled;
diff --git a/third_party/blink/public/platform/media/BUILD.gn b/third_party/blink/public/platform/media/BUILD.gn index 1a4bc79..ac9788a 100644 --- a/third_party/blink/public/platform/media/BUILD.gn +++ b/third_party/blink/public/platform/media/BUILD.gn
@@ -16,7 +16,6 @@ "key_system_config_selector.h", "lru.h", "multi_buffer.h", - "power_status_helper.h", "remote_playback_client_wrapper_impl.h", "resource_fetch_context.h", "url_index.h", @@ -31,10 +30,8 @@ "//media", "//media/mojo/mojom", "//mojo/public/cpp/bindings", - "//services/device/public/mojom", "//third_party/blink/public:blink", "//third_party/blink/public:blink_headers", - "//ui/gfx/geometry", "//url", ]
diff --git a/third_party/blink/public/platform/media/DEPS b/third_party/blink/public/platform/media/DEPS index 0063616..3d9f3a3 100644 --- a/third_party/blink/public/platform/media/DEPS +++ b/third_party/blink/public/platform/media/DEPS
@@ -14,7 +14,6 @@ "+media/learning/common", "+media/mojo/mojom", "+media/renderers", - "+services/device/public/mojom", "+services/media_session/public/cpp", "+third_party/blink/public/web", ]
diff --git a/third_party/blink/public/platform/media/key_system_config_selector.h b/third_party/blink/public/platform/media/key_system_config_selector.h index 13121b8..9c7595d9 100644 --- a/third_party/blink/public/platform/media/key_system_config_selector.h +++ b/third_party/blink/public/platform/media/key_system_config_selector.h
@@ -75,8 +75,11 @@ // Callback for the result of `SelectConfig()`. The returned configs must be // non-null iff `status` is `kSupported`. - using SelectConfigCB = base::OnceCallback< - void(Status status, WebMediaKeySystemConfiguration*, media::CdmConfig*)>; + using SelectConfigCB = + base::OnceCallback<void(Status status, + const std::string& key_system, + WebMediaKeySystemConfiguration*, + media::CdmConfig*)>; void SelectConfig( const WebString& key_system,
diff --git a/third_party/blink/public/platform/media/web_encrypted_media_client_impl.h b/third_party/blink/public/platform/media/web_encrypted_media_client_impl.h index d005cc3..9ca67db 100644 --- a/third_party/blink/public/platform/media/web_encrypted_media_client_impl.h +++ b/third_party/blink/public/platform/media/web_encrypted_media_client_impl.h
@@ -55,11 +55,14 @@ class Reporter; // Callback for `KeySystemConfigSelector::SelectConfig()`. + // `key_system` is the same as the requested key system in most cases unless + // a sub key system is queried and the base key system should be used. // `accumulated_configuration` and `cdm_config` are non-null iff `status` is // `kSupported`. void OnConfigSelected( WebEncryptedMediaRequest request, KeySystemConfigSelector::Status status, + const std::string& key_system, WebMediaKeySystemConfiguration* accumulated_configuration, media::CdmConfig* cdm_config);
diff --git a/third_party/blink/public/platform/media/web_media_player_impl.h b/third_party/blink/public/platform/media/web_media_player_impl.h index a70c8dd4..9f5da07 100644 --- a/third_party/blink/public/platform/media/web_media_player_impl.h +++ b/third_party/blink/public/platform/media/web_media_player_impl.h
@@ -15,6 +15,7 @@ #include "base/compiler_specific.h" #include "base/memory/memory_pressure_listener.h" #include "base/memory/ref_counted.h" +#include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread.h" #include "base/time/default_tick_clock.h" @@ -82,6 +83,7 @@ namespace blink { class PowerStatusHelper; +class ThreadSafeBrowserInterfaceBrokerProxy; class UrlIndex; class VideoDecodeStatsReporter; class VideoFrameCompositor; @@ -112,6 +114,7 @@ std::unique_ptr<media::RendererFactorySelector> renderer_factory_selector, UrlIndex* url_index, std::unique_ptr<VideoFrameCompositor> compositor, + scoped_refptr<ThreadSafeBrowserInterfaceBrokerProxy> remote_interfaces, std::unique_ptr<WebMediaPlayerParams> params); WebMediaPlayerImpl(const WebMediaPlayerImpl&) = delete; WebMediaPlayerImpl& operator=(const WebMediaPlayerImpl&) = delete;
diff --git a/third_party/blink/public/platform/media/web_media_player_params.h b/third_party/blink/public/platform/media/web_media_player_params.h index 9800411..0397ba5 100644 --- a/third_party/blink/public/platform/media/web_media_player_params.h +++ b/third_party/blink/public/platform/media/web_media_player_params.h
@@ -19,7 +19,6 @@ #include "media/base/routing_token_callback.h" #include "media/mojo/mojom/media_metrics_provider.mojom.h" #include "mojo/public/cpp/bindings/pending_remote.h" -#include "third_party/blink/public/platform/media/power_status_helper.h" #include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/public/platform/web_media_player.h" #include "third_party/blink/public/platform/web_video_frame_submitter.h" @@ -83,8 +82,7 @@ bool is_background_suspend_enabled, bool is_background_video_play_enabled, bool is_background_video_track_optimization_supported, - std::unique_ptr<media::Demuxer> demuxer_override, - std::unique_ptr<PowerStatusHelper> power_status_helper); + std::unique_ptr<media::Demuxer> demuxer_override); WebMediaPlayerParams(const WebMediaPlayerParams&) = delete; WebMediaPlayerParams& operator=(const WebMediaPlayerParams&) = delete; @@ -172,10 +170,6 @@ std::unique_ptr<media::Demuxer> TakeDemuxerOverride(); - std::unique_ptr<PowerStatusHelper> TakePowerStatusHelper() { - return std::move(power_status_helper_); - } - private: DeferLoadCB defer_load_cb_; scoped_refptr<media::SwitchableAudioRendererSink> audio_renderer_sink_; @@ -207,8 +201,6 @@ // Optional custom demuxer to use instead of the standard demuxers. std::unique_ptr<media::Demuxer> demuxer_override_; - - std::unique_ptr<PowerStatusHelper> power_status_helper_; }; } // namespace blink
diff --git a/third_party/blink/public/strings/translations/blink_strings_nl.xtb b/third_party/blink/public/strings/translations/blink_strings_nl.xtb index 14fa96249..6b541058 100644 --- a/third_party/blink/public/strings/translations/blink_strings_nl.xtb +++ b/third_party/blink/public/strings/translations/blink_strings_nl.xtb
@@ -115,6 +115,7 @@ <translation id="4908855810237020461">Klokicoon, betekent misschien Tijd</translation> <translation id="4912200001568447310">huidig item</translation> <translation id="4915360478455618802">Tijdkiezer bekijken</translation> +<translation id="4924138096460353083">onbepaald</translation> <translation id="4950364064308314478">Kiezer voor lokale datum en tijd bekijken</translation> <translation id="4971739861736909480"><ph name="ACCNAME" /> geselecteerd</translation> <translation id="4975562563186953947"><ph name="SELECTED_COUNT" /> geselecteerd</translation>
diff --git a/third_party/blink/public/strings/translations/blink_strings_pl.xtb b/third_party/blink/public/strings/translations/blink_strings_pl.xtb index b534c4d4..bf0726d 100644 --- a/third_party/blink/public/strings/translations/blink_strings_pl.xtb +++ b/third_party/blink/public/strings/translations/blink_strings_pl.xtb
@@ -115,6 +115,7 @@ <translation id="4908855810237020461">Ikona zegara, może oznaczać Godzinę</translation> <translation id="4912200001568447310">bieżący element</translation> <translation id="4915360478455618802">Pokaż selektor godziny</translation> +<translation id="4924138096460353083">nieokreślony</translation> <translation id="4950364064308314478">Pokaż selektor lokalnej daty i godziny</translation> <translation id="4971739861736909480">Wybrano <ph name="ACCNAME" /></translation> <translation id="4975562563186953947">Wybrano: <ph name="SELECTED_COUNT" /></translation>
diff --git a/third_party/blink/public/strings/translations/blink_strings_pt-PT.xtb b/third_party/blink/public/strings/translations/blink_strings_pt-PT.xtb index 9e3784b6..c98d8983 100644 --- a/third_party/blink/public/strings/translations/blink_strings_pt-PT.xtb +++ b/third_party/blink/public/strings/translations/blink_strings_pt-PT.xtb
@@ -115,6 +115,7 @@ <translation id="4908855810237020461">Ícone Relógio, pode significar hora</translation> <translation id="4912200001568447310">item atual</translation> <translation id="4915360478455618802">Mostrar selecionador de hora</translation> +<translation id="4924138096460353083">indeterminado</translation> <translation id="4950364064308314478">Mostrar selecionador de data e hora locais</translation> <translation id="4971739861736909480">Selecionado: <ph name="ACCNAME" /></translation> <translation id="4975562563186953947"><ph name="SELECTED_COUNT" /> selecionados</translation>
diff --git a/third_party/blink/public/strings/translations/blink_strings_ru.xtb b/third_party/blink/public/strings/translations/blink_strings_ru.xtb index f1429de6..2a52576 100644 --- a/third_party/blink/public/strings/translations/blink_strings_ru.xtb +++ b/third_party/blink/public/strings/translations/blink_strings_ru.xtb
@@ -115,6 +115,7 @@ <translation id="4908855810237020461">Значок часов, может означать время</translation> <translation id="4912200001568447310">текущий объект</translation> <translation id="4915360478455618802">Показать окно выбора времени</translation> +<translation id="4924138096460353083">Не определено</translation> <translation id="4950364064308314478">Показать окно выбора даты и местного времени</translation> <translation id="4971739861736909480">Выбрано: <ph name="ACCNAME" /></translation> <translation id="4975562563186953947">Выбрано: <ph name="SELECTED_COUNT" /></translation>
diff --git a/third_party/blink/public/strings/translations/blink_strings_sv.xtb b/third_party/blink/public/strings/translations/blink_strings_sv.xtb index a5cf9b1..651673f 100644 --- a/third_party/blink/public/strings/translations/blink_strings_sv.xtb +++ b/third_party/blink/public/strings/translations/blink_strings_sv.xtb
@@ -115,6 +115,7 @@ <translation id="4908855810237020461">Klockikon, kan betyda tid</translation> <translation id="4912200001568447310">aktuellt objekt</translation> <translation id="4915360478455618802">Visa tidsväljare</translation> +<translation id="4924138096460353083">obestämt</translation> <translation id="4950364064308314478">Visa datum- och tidsväljare för lokal tid</translation> <translation id="4971739861736909480"><ph name="ACCNAME" /> har valts</translation> <translation id="4975562563186953947"><ph name="SELECTED_COUNT" /> valda</translation>
diff --git a/third_party/blink/public/web/web_script_source.h b/third_party/blink/public/web/web_script_source.h index 89a7f25..eabaeec 100644 --- a/third_party/blink/public/web/web_script_source.h +++ b/third_party/blink/public/web/web_script_source.h
@@ -39,13 +39,10 @@ struct WebScriptSource { WebString code; WebURL url; - int start_line; - WebScriptSource(const WebString& code) : code(code), start_line(1) {} + explicit WebScriptSource(const WebString& code) : code(code) {} WebScriptSource(const WebString& code, const WebURL& url) - : code(code), url(url), start_line(1) {} - WebScriptSource(const WebString& code, const WebURL& url, int start_line) - : code(code), url(url), start_line(start_line) {} + : code(code), url(url) {} }; } // namespace blink
diff --git a/third_party/blink/public/web/web_settings.h b/third_party/blink/public/web/web_settings.h index 73a644e..38a115a 100644 --- a/third_party/blink/public/web/web_settings.h +++ b/third_party/blink/public/web/web_settings.h
@@ -171,7 +171,6 @@ virtual void SetMinimumFontSize(int) = 0; virtual void SetMinimumLogicalFontSize(int) = 0; virtual void SetHideScrollbars(bool) = 0; - virtual void SetOfflineWebApplicationCacheEnabled(bool) = 0; virtual void SetPasswordEchoDurationInSeconds(double) = 0; virtual void SetPasswordEchoEnabled(bool) = 0; virtual void SetPictographFontFamily(const WebString&,
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn index 8ebb66f..c007905 100644 --- a/third_party/blink/renderer/core/BUILD.gn +++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1436,6 +1436,7 @@ "paint/compositing/compositing_reason_finder_test.cc", "paint/compositing/compositing_test.cc", "paint/css_mask_painter_test.cc", + "paint/cull_rect_updater_test.cc", "paint/first_meaningful_paint_detector_test.cc", "paint/fragment_data_test.cc", "paint/highlight_painting_utils_test.cc",
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 0eacde3..85ed63b 100644 --- a/third_party/blink/renderer/core/css/media_query_exp.cc +++ b/third_party/blink/renderer/core/css/media_query_exp.cc
@@ -565,6 +565,38 @@ return builder.ReleaseString(); } +std::unique_ptr<MediaQueryExpNode> MediaQueryExpNode::Not( + std::unique_ptr<MediaQueryExpNode> operand) { + if (!operand) + return nullptr; + return std::make_unique<MediaQueryNotExpNode>(std::move(operand)); +} + +std::unique_ptr<MediaQueryExpNode> MediaQueryExpNode::Nested( + std::unique_ptr<MediaQueryExpNode> operand) { + if (!operand) + return nullptr; + return std::make_unique<MediaQueryNestedExpNode>(std::move(operand)); +} + +std::unique_ptr<MediaQueryExpNode> MediaQueryExpNode::And( + std::unique_ptr<MediaQueryExpNode> left, + std::unique_ptr<MediaQueryExpNode> right) { + if (!left || !right) + return nullptr; + return std::make_unique<MediaQueryAndExpNode>(std::move(left), + std::move(right)); +} + +std::unique_ptr<MediaQueryExpNode> MediaQueryExpNode::Or( + std::unique_ptr<MediaQueryExpNode> left, + std::unique_ptr<MediaQueryExpNode> right) { + if (!left || !right) + return nullptr; + return std::make_unique<MediaQueryOrExpNode>(std::move(left), + std::move(right)); +} + PhysicalAxes MediaQueryFeatureExpNode::QueriedAxes() const { PhysicalAxes axes(kPhysicalAxisNone);
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 cd16c5f..7b62a6f4 100644 --- a/third_party/blink/renderer/core/css/media_query_exp.h +++ b/third_party/blink/renderer/core/css/media_query_exp.h
@@ -287,6 +287,18 @@ virtual void SerializeTo(StringBuilder&) const = 0; virtual void CollectExpressions(Vector<MediaQueryExp>&) const = 0; virtual std::unique_ptr<MediaQueryExpNode> Copy() const = 0; + + // These helper functions return nullptr if any argument is nullptr. + static std::unique_ptr<MediaQueryExpNode> Not( + std::unique_ptr<MediaQueryExpNode>); + static std::unique_ptr<MediaQueryExpNode> Nested( + std::unique_ptr<MediaQueryExpNode>); + static std::unique_ptr<MediaQueryExpNode> And( + std::unique_ptr<MediaQueryExpNode>, + std::unique_ptr<MediaQueryExpNode>); + static std::unique_ptr<MediaQueryExpNode> Or( + std::unique_ptr<MediaQueryExpNode>, + std::unique_ptr<MediaQueryExpNode>); }; class CORE_EXPORT MediaQueryFeatureExpNode : public MediaQueryExpNode {
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 d1602f5..1d9d6ab 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
@@ -80,26 +80,24 @@ std::unique_ptr<MediaQueryExpNode> NestedNode( std::unique_ptr<MediaQueryExpNode> child) { - return std::make_unique<MediaQueryNestedExpNode>(std::move(child)); + return MediaQueryExpNode::Nested(std::move(child)); } std::unique_ptr<MediaQueryExpNode> NotNode( std::unique_ptr<MediaQueryExpNode> operand) { - return std::make_unique<MediaQueryNotExpNode>(std::move(operand)); + return MediaQueryExpNode::Not(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)); + return MediaQueryExpNode::And(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)); + return MediaQueryExpNode::Or(std::move(left), std::move(right)); } } // namespace @@ -364,4 +362,17 @@ LeftExp("width", LtCmp(RemValue(10.0))).GetUnitFlags()); } +TEST(MediaQueryExpTest, UtilsNullptrHandling) { + MediaQueryExp exp = RightExp("width", LtCmp(PxValue(10))); + + EXPECT_FALSE(MediaQueryExpNode::Nested(nullptr)); + EXPECT_FALSE(MediaQueryExpNode::Not(nullptr)); + EXPECT_FALSE(MediaQueryExpNode::And(nullptr, FeatureNode(exp))); + EXPECT_FALSE(MediaQueryExpNode::And(FeatureNode(exp), nullptr)); + EXPECT_FALSE(MediaQueryExpNode::And(nullptr, nullptr)); + EXPECT_FALSE(MediaQueryExpNode::Or(nullptr, FeatureNode(exp))); + EXPECT_FALSE(MediaQueryExpNode::Or(FeatureNode(exp), nullptr)); + EXPECT_FALSE(MediaQueryExpNode::Or(nullptr, nullptr)); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/css/parser/media_query_parser.cc b/third_party/blink/renderer/core/css/parser/media_query_parser.cc index 9c3c9c0..ac153b1 100644 --- a/third_party/blink/renderer/core/css/parser/media_query_parser.cc +++ b/third_party/blink/renderer/core/css/parser/media_query_parser.cc
@@ -146,35 +146,24 @@ CSSParserTokenRange& range, ConditionMode mode) { // <media-not> - if (IsNotKeywordEnabled() && ConsumeIfIdent(range, "not")) { - if (auto node = ConsumeInParens(range)) - return std::make_unique<MediaQueryNotExpNode>(std::move(node)); - return nullptr; - } + if (IsNotKeywordEnabled() && ConsumeIfIdent(range, "not")) + return MediaQueryExpNode::Not(ConsumeInParens(range)); // Otherwise: // <media-in-parens> [ <media-and>* | <media-or>* ] std::unique_ptr<MediaQueryExpNode> result = ConsumeInParens(range); - if (!result) - return nullptr; if (AtIdent(range.Peek(), "and")) { - while (ConsumeIfIdent(range, "and")) { - std::unique_ptr<MediaQueryExpNode> in_parens = ConsumeInParens(range); - if (!in_parens) - return nullptr; - result = std::make_unique<MediaQueryAndExpNode>(std::move(result), - std::move(in_parens)); + while (result && ConsumeIfIdent(range, "and")) { + result = + MediaQueryExpNode::And(std::move(result), ConsumeInParens(range)); } - } else if (AtIdent(range.Peek(), "or") && mode == ConditionMode::kNormal && + } else if (result && AtIdent(range.Peek(), "or") && + mode == ConditionMode::kNormal && RuntimeEnabledFeatures::CSSMediaQueries4Enabled()) { - while (ConsumeIfIdent(range, "or")) { - std::unique_ptr<MediaQueryExpNode> in_parens = ConsumeInParens(range); - if (!in_parens) - return nullptr; - result = std::make_unique<MediaQueryOrExpNode>(std::move(result), - std::move(in_parens)); + while (result && ConsumeIfIdent(range, "or")) { + result = MediaQueryExpNode::Or(std::move(result), ConsumeInParens(range)); } } @@ -193,7 +182,7 @@ range.ConsumeWhitespace(); auto node = ConsumeCondition(block); if (node && block.AtEnd()) - return std::make_unique<MediaQueryNestedExpNode>(std::move(node)); + return MediaQueryExpNode::Nested(std::move(node)); } range = original_range;
diff --git a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc index acad582..87475f3 100644 --- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc +++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -345,19 +345,6 @@ if (IsA<HTMLDivElement>(element) || IsA<HTMLSpanElement>(element)) return; - if (IsA<HTMLTableCellElement>(element)) { - if (style.WhiteSpace() == EWhiteSpace::kWebkitNowrap) { - // Figure out if we are really nowrapping or if we should just - // use normal instead. If the width of the cell is fixed, then - // we don't actually use NOWRAP. - if (style.Width().IsFixed()) - style.SetWhiteSpace(EWhiteSpace::kNormal); - else - style.SetWhiteSpace(EWhiteSpace::kNowrap); - } - return; - } - if (auto* image = DynamicTo<HTMLImageElement>(element)) { if (image->IsCollapsed() || style.Display() == EDisplay::kContents) style.SetDisplay(EDisplay::kNone);
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 22fe14e..8d4f6a8 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -2669,6 +2669,9 @@ viewport_style_dirty_ = false; + if (!resolver_) + return; + scoped_refptr<ComputedStyle> viewport_style = resolver_->StyleForViewport(); if (ComputedStyle::ComputeDifference( viewport_style.get(), GetDocument().GetLayoutView()->Style()) !=
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 17dd19c30..f5698fc 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -1759,6 +1759,16 @@ if (interactive_detector) { interactive_detector->OnPageHiddenChanged(hidden()); } + + // Don't create a |ukm_recorder_| and |ukm_source_id_| unless necessary. + if (hidden() && IdentifiabilityStudySettings::Get()->IsActive()) { + // Flush UKM data here in addition to Document::Shutdown(). We want to flush + // the UKM data before this document becomes invisible (e.g. before entering + // back/forward cache) because we want to send the UKM data before the + // renderer process is killed. + IdentifiabilitySampleCollector::Get()->FlushSource(UkmRecorder(), + UkmSourceID()); + } } String Document::nodeName() const {
diff --git a/third_party/blink/renderer/core/exported/web_media_player_impl_unittest.cc b/third_party/blink/renderer/core/exported/web_media_player_impl_unittest.cc index 1c9d3c5..f2320a43 100644 --- a/third_party/blink/renderer/core/exported/web_media_player_impl_unittest.cc +++ b/third_party/blink/renderer/core/exported/web_media_player_impl_unittest.cc
@@ -52,6 +52,7 @@ #include "mojo/public/cpp/bindings/remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/public/platform/media/web_media_player_params.h" #include "third_party/blink/public/platform/media/webmediaplayer_delegate.h" @@ -70,6 +71,7 @@ #include "third_party/blink/public/web/web_view.h" #include "third_party/blink/public/web/web_widget.h" #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" +#include "third_party/blink/renderer/platform/media/power_status_helper.h" #include "third_party/blink/renderer/platform/media/resource_multi_buffer_data_provider.h" #include "third_party/blink/renderer/platform/media/testing/mock_resource_fetch_context.h" #include "third_party/blink/renderer/platform/media/testing/mock_web_associated_url_loader.h" @@ -432,7 +434,7 @@ viz::TestContextProvider::Create(), WebMediaPlayer::SurfaceLayerMode::kAlways, is_background_suspend_enabled_, is_background_video_playback_enabled_, - true, std::move(demuxer_override), nullptr); + true, std::move(demuxer_override)); auto compositor = std::make_unique<NiceMock<MockVideoFrameCompositor>>( params->video_frame_compositor_task_runner()); @@ -441,7 +443,7 @@ wmpi_ = std::make_unique<WebMediaPlayerImpl>( GetWebLocalFrame(), &client_, &encrypted_client_, &delegate_, std::move(factory_selector), url_index_.get(), std::move(compositor), - std::move(params)); + nullptr, std::move(params)); } std::unique_ptr<WebSurfaceLayerBridge> CreateMockSurfaceLayerBridge(
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.cc b/third_party/blink/renderer/core/exported/web_settings_impl.cc index 8580bfa..5b2491b 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.cc +++ b/third_party/blink/renderer/core/exported/web_settings_impl.cc
@@ -432,10 +432,6 @@ settings_->SetBarrelButtonForDragEnabled(enabled); } -void WebSettingsImpl::SetOfflineWebApplicationCacheEnabled(bool enabled) { - settings_->SetOfflineWebApplicationCacheEnabled(enabled); -} - void WebSettingsImpl::SetWebGL1Enabled(bool enabled) { settings_->SetWebGL1Enabled(enabled); }
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.h b/third_party/blink/renderer/core/exported/web_settings_impl.h index f4468e25..2fe8b492 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.h +++ b/third_party/blink/renderer/core/exported/web_settings_impl.h
@@ -122,7 +122,6 @@ void SetMinimumFontSize(int) override; void SetMinimumLogicalFontSize(int) override; void SetHideScrollbars(bool) override; - void SetOfflineWebApplicationCacheEnabled(bool) override; void SetPasswordEchoDurationInSeconds(double) override; void SetPasswordEchoEnabled(bool) override; void SetPictographFontFamily(const WebString&,
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 41172a1f..d87580a 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -45,6 +45,7 @@ #include "media/base/media_switches.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/frame/event_page_show_persisted.h" #include "third_party/blink/public/common/history/session_history_constants.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/input/web_menu_source_type.h" @@ -1456,8 +1457,6 @@ settings->SetAllowNonEmptyNavigatorPlugins( prefs.allow_non_empty_navigator_plugins); RuntimeEnabledFeatures::SetDatabaseEnabled(prefs.databases_enabled); - settings->SetOfflineWebApplicationCacheEnabled( - prefs.application_cache_enabled); settings->SetShouldProtectAgainstIpcFlooding( !prefs.disable_ipc_flooding_protection); settings->SetHyperlinkAuditingEnabled(prefs.hyperlink_auditing_enabled); @@ -2317,6 +2316,8 @@ void WebViewImpl::SetPageLifecycleStateFromNewPageCommit( mojom::blink::PageVisibilityState visibility, mojom::blink::PagehideDispatch pagehide_dispatch) { + TRACE_EVENT0("navigation", + "WebViewImpl::SetPageLifecycleStateFromNewPageCommit"); mojom::blink::PageLifecycleStatePtr state = GetPage()->GetPageLifecycleState().Clone(); state->visibility = visibility; @@ -2329,6 +2330,12 @@ mojom::blink::PageLifecycleStatePtr state, mojom::blink::PageRestoreParamsPtr page_restore_params, SetPageLifecycleStateCallback callback) { + TRACE_EVENT0("navigation", "WebViewImpl::SetPageLifecycleState"); + // TODO(https://crbug.com/1234634): Remove this. + if (state->should_dispatch_pageshow_for_debugging) { + blink::RecordUMAEventPageShowPersisted( + blink::EventPageShowPersisted::kBrowserYesInRenderer); + } SetPageLifecycleStateInternal(std::move(state), std::move(page_restore_params)); // Tell the browser that the lifecycle update was successful. @@ -2342,6 +2349,12 @@ if (!page) return; auto& old_state = page->GetPageLifecycleState(); + TRACE_EVENT2("navigation", "WebViewImpl::SetPageLifecycleStateInternal", + "old_state", old_state, "new_state", new_state); + if (new_state->should_dispatch_pageshow_for_debugging) { + blink::RecordUMAEventPageShowPersisted( + blink::EventPageShowPersisted::kBrowserYesInRendererWithPage); + } bool storing_in_bfcache = new_state->is_in_back_forward_cache && !old_state->is_in_back_forward_cache;
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5 index 3720a82e..9d28d37 100644 --- a/third_party/blink/renderer/core/frame/settings.json5 +++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -152,10 +152,6 @@ }, { - name: "offlineWebApplicationCacheEnabled", - initial: true, - }, - { name: "allowScriptsToCloseWindows", initial: false, },
diff --git a/third_party/blink/renderer/core/html/html_table_cell_element.cc b/third_party/blink/renderer/core/html/html_table_cell_element.cc index 42963945..ccfadda 100644 --- a/third_party/blink/renderer/core/html/html_table_cell_element.cc +++ b/third_party/blink/renderer/core/html/html_table_cell_element.cc
@@ -99,7 +99,7 @@ MutableCSSPropertyValueSet* style) { if (name == html_names::kNowrapAttr) { AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kWhiteSpace, - CSSValueID::kWebkitNowrap); + CSSValueID::kNowrap); } else if (name == html_names::kWidthAttr) { if (!value.IsEmpty()) { int width_int = value.ToInt();
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index b14b8680..e1e4265b 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -4255,7 +4255,7 @@ if (StyleRef().AspectRatio().IsAuto()) return false; - if (IsGridItem() && HasStretchedLogicalWidth(StretchingMode::Explicit)) + if (IsGridItem() && HasStretchedLogicalWidth(StretchingMode::kExplicit)) return false; if (!HasOverrideLogicalHeight() && @@ -4588,7 +4588,7 @@ // Flexbox Items, which obviously should have a container. return false; } - auto defaultItemPosition = stretchingMode == StretchingMode::Any + auto defaultItemPosition = stretchingMode == StretchingMode::kAny ? cb->SelfAlignmentNormalBehavior(this) : ItemPosition::kNormal; if (cb->IsHorizontalWritingMode() != IsHorizontalWritingMode()) {
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index ddae5f4..8203463 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -2140,8 +2140,8 @@ bool ColumnFlexItemHasStretchAlignment() const; bool IsStretchingColumnFlexItem() const; - enum class StretchingMode { Any, Explicit }; - bool HasStretchedLogicalWidth(StretchingMode = StretchingMode::Any) const; + enum class StretchingMode { kAny, kExplicit }; + bool HasStretchedLogicalWidth(StretchingMode = StretchingMode::kAny) const; bool HasStretchedLogicalHeight() const; void ExcludeScrollbars(
diff --git a/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc b/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc index cc54995..cb6791a 100644 --- a/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc +++ b/third_party/blink/renderer/core/layout/layout_deprecated_flexible_box.cc
@@ -452,7 +452,7 @@ last_visible_line->PlaceEllipsis(ellipsis_str, left_to_right, block_left_edge, block_right_edge, LayoutUnit(total_width), LayoutUnit(), - &box_truncation_starts_at, ForceEllipsis); + &box_truncation_starts_at, kForceEllipsis); dest_block.SetHasMarkupTruncation(true); } }
diff --git a/third_party/blink/renderer/core/layout/layout_iframe.h b/third_party/blink/renderer/core/layout/layout_iframe.h index 66ed05f..0162a8a2 100644 --- a/third_party/blink/renderer/core/layout/layout_iframe.h +++ b/third_party/blink/renderer/core/layout/layout_iframe.h
@@ -53,6 +53,13 @@ PaintLayerType LayerTypeRequired() const override; }; +template <> +struct DowncastTraits<LayoutIFrame> { + static bool AllowFrom(const LayoutObject& object) { + return object.IsLayoutIFrame(); + } +}; + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_IFRAME_H_
diff --git a/third_party/blink/renderer/core/layout/layout_shift_region.cc b/third_party/blink/renderer/core/layout/layout_shift_region.cc index 14080dfd..c13b858 100644 --- a/third_party/blink/renderer/core/layout/layout_shift_region.cc +++ b/third_party/blink/renderer/core/layout/layout_shift_region.cc
@@ -18,8 +18,8 @@ }; // An "event" occurs when a rectangle starts intersecting the sweep line -// (START), or when it ceases to intersect the sweep line (END). -enum class EventType { START, END }; +// (kStart), or when it ceases to intersect the sweep line (kEnd). +enum class EventType { kStart, kEnd }; struct SweepEvent { // X-coordinate at which the event occurs. int x; @@ -280,8 +280,8 @@ events.ReserveInitialCapacity(rects_.size() << 1); for (const gfx::Rect& rect : rects_) { Segment segment = y_vals.SegmentFromEndpoints(rect.y(), rect.bottom()); - events.push_back(SweepEvent{rect.x(), EventType::START, segment}); - events.push_back(SweepEvent{rect.right(), EventType::END, segment}); + events.push_back(SweepEvent{rect.x(), EventType::kStart, segment}); + events.push_back(SweepEvent{rect.right(), EventType::kEnd, segment}); } std::sort(events.begin(), events.end(), [](const SweepEvent& e1, const SweepEvent& e2) -> bool { @@ -299,7 +299,7 @@ area += (uint64_t)(e.x - sweep_x) * (uint64_t)tree.ActiveLength(); sweep_x = e.x; } - if (e.type == EventType::START) + if (e.type == EventType::kStart) tree.RefSegment(e.y_segment); else tree.DerefSegment(e.y_segment);
diff --git a/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h b/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h index ffe2f588..1641aef 100644 --- a/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h +++ b/third_party/blink/renderer/core/layout/line/breaking_context_inline_headers.h
@@ -449,8 +449,8 @@ } enum CollapsibleWhiteSpace { - IgnoreCollapsibleWhiteSpace, - UseCollapsibleWhiteSpace + kIgnoreCollapsibleWhiteSpace, + kUseCollapsibleWhiteSpace }; inline bool ShouldAddBorderPaddingMargin(LineLayoutItem child, @@ -463,7 +463,7 @@ // collapsible whitespace if they haven't already been added to the line's // width, such as when adding end-BPM when about to place a float after a // linebox. - if (white_space == UseCollapsibleWhiteSpace && + if (white_space == kUseCollapsibleWhiteSpace && LineLayoutText(child).IsAllCollapsibleWhitespace()) return true; if (!LineLayoutText(child).TextLength()) @@ -477,7 +477,7 @@ LineLayoutItem child, bool start = true, bool end = true, - CollapsibleWhiteSpace white_space = IgnoreCollapsibleWhiteSpace) { + CollapsibleWhiteSpace white_space = kIgnoreCollapsibleWhiteSpace) { unsigned line_depth = 1; LayoutUnit extra_width; LineLayoutItem parent = child.Parent(); @@ -561,7 +561,7 @@ // inline ancestors has been applied to the end of the previous inline box. float width_from_ancestors = InlineLogicalWidthFromAncestorsIfNeeded(float_box, false, true, - UseCollapsibleWhiteSpace) + kUseCollapsibleWhiteSpace) .ToFloat(); width_.AddUncommittedWidth(width_from_ancestors); if (width_.FitsOnLine(
diff --git a/third_party/blink/renderer/core/layout/line/root_inline_box.cc b/third_party/blink/renderer/core/layout/line/root_inline_box.cc index ba6105f..15df956 100644 --- a/third_party/blink/renderer/core/layout/line/root_inline_box.cc +++ b/third_party/blink/renderer/core/layout/line/root_inline_box.cc
@@ -137,7 +137,7 @@ // FIXME: Do we need an RTL version of this? LayoutUnit adjusted_logical_left = logical_left_offset + LogicalLeft(); - if (force_ellipsis == ForceEllipsis && ltr && + if (force_ellipsis == kForceEllipsis && ltr && (adjusted_logical_left + LogicalWidth() + ellipsis_width) <= block_right_edge) { if (HasEllipsisBox())
diff --git a/third_party/blink/renderer/core/layout/line/root_inline_box.h b/third_party/blink/renderer/core/layout/line/root_inline_box.h index 6faa56d..afbc41e 100644 --- a/third_party/blink/renderer/core/layout/line/root_inline_box.h +++ b/third_party/blink/renderer/core/layout/line/root_inline_box.h
@@ -33,7 +33,7 @@ struct BidiStatus; -enum ForceEllipsisOnLine { DoNotForceEllipsis, ForceEllipsis }; +enum ForceEllipsisOnLine { kDoNotForceEllipsis, kForceEllipsis }; class RootInlineBox : public InlineFlowBox { public: @@ -116,7 +116,7 @@ LayoutUnit ellipsis_width, LayoutUnit logical_left_offset, InlineBox** found_box, - ForceEllipsisOnLine = DoNotForceEllipsis); + ForceEllipsisOnLine = kDoNotForceEllipsis); // Return the position of the EllipsisBox or -1. LayoutUnit PlaceEllipsisBox(bool ltr, LayoutUnit block_left_edge,
diff --git a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc index cb84bc7..c32a16e9 100644 --- a/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/flex/ng_flex_layout_algorithm.cc
@@ -365,8 +365,8 @@ : ChildAvailableSize().inline_size; available_size.block_size = item_main_axis_final_size; space_builder.SetIsFixedBlockSize(true); - if (WillChildCrossSizeBeContainerCrossSize(flex_item_node) || - line_cross_size_for_stretch) + if (line_cross_size_for_stretch || + WillChildCrossSizeBeContainerCrossSize(flex_item_node)) space_builder.SetInlineAutoBehavior(NGAutoBehavior::kStretchExplicit); // https://drafts.csswg.org/css-flexbox/#definite-sizes // If the flex container has a definite main size, a flex item's @@ -383,8 +383,8 @@ ? *line_cross_size_for_stretch : ChildAvailableSize().block_size; space_builder.SetIsFixedInlineSize(true); - if (WillChildCrossSizeBeContainerCrossSize(flex_item_node) || - line_cross_size_for_stretch) + if (line_cross_size_for_stretch || + WillChildCrossSizeBeContainerCrossSize(flex_item_node)) space_builder.SetBlockAutoBehavior(NGAutoBehavior::kStretchExplicit); } if (!line_cross_size_for_stretch && DoesItemStretch(flex_item_node)) {
diff --git a/third_party/blink/renderer/core/layout/pointer_events_hit_rules.cc b/third_party/blink/renderer/core/layout/pointer_events_hit_rules.cc index 145bb01..f9547a6 100644 --- a/third_party/blink/renderer/core/layout/pointer_events_hit_rules.cc +++ b/third_party/blink/renderer/core/layout/pointer_events_hit_rules.cc
@@ -41,7 +41,7 @@ if (request.SvgClipContent()) pointer_events = EPointerEvents::kFill; - if (hit_testing == SVG_GEOMETRY_HITTESTING) { + if (hit_testing == kSvgGeometryHitTesting) { switch (pointer_events) { case EPointerEvents::kBoundingBox: can_hit_bounding_box = true;
diff --git a/third_party/blink/renderer/core/layout/pointer_events_hit_rules.h b/third_party/blink/renderer/core/layout/pointer_events_hit_rules.h index 52a1c466..2c967b9 100644 --- a/third_party/blink/renderer/core/layout/pointer_events_hit_rules.h +++ b/third_party/blink/renderer/core/layout/pointer_events_hit_rules.h
@@ -31,9 +31,9 @@ public: enum EHitTesting { - SVG_IMAGE_HITTESTING, - SVG_GEOMETRY_HITTESTING, - SVG_TEXT_HITTESTING + kSvgImageHitTesting, + kSvgGeometryHitTesting, + kSvgTextHitTesting }; PointerEventsHitRules(EHitTesting, const HitTestRequest&, EPointerEvents);
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc index 63f1c98..b5b48de 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc
@@ -216,7 +216,7 @@ return false; const ComputedStyle& style = StyleRef(); - PointerEventsHitRules hit_rules(PointerEventsHitRules::SVG_IMAGE_HITTESTING, + PointerEventsHitRules hit_rules(PointerEventsHitRules::kSvgImageHitTesting, result.GetHitTestRequest(), style.UsedPointerEvents()); if (hit_rules.require_visible && style.Visibility() != EVisibility::kVisible)
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc index 1f62f9df..4e1033d 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_shape.cc
@@ -401,8 +401,8 @@ return false; const ComputedStyle& style = StyleRef(); const PointerEventsHitRules hit_rules( - PointerEventsHitRules::SVG_GEOMETRY_HITTESTING, - result.GetHitTestRequest(), style.UsedPointerEvents()); + PointerEventsHitRules::kSvgGeometryHitTesting, result.GetHitTestRequest(), + style.UsedPointerEvents()); if (hit_rules.require_visible && style.Visibility() != EVisibility::kVisible) return false;
diff --git a/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.cc b/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.cc index e3db41f..672facda 100644 --- a/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.cc +++ b/third_party/blink/renderer/core/layout/svg/line/svg_inline_text_box.cc
@@ -307,7 +307,7 @@ auto line_layout_item = LineLayoutSVGInlineText(GetLineLayoutItem()); const ComputedStyle& style = line_layout_item.StyleRef(); - PointerEventsHitRules hit_rules(PointerEventsHitRules::SVG_TEXT_HITTESTING, + PointerEventsHitRules hit_rules(PointerEventsHitRules::kSvgTextHitTesting, result.GetHitTestRequest(), style.UsedPointerEvents()); if (hit_rules.require_visible && style.Visibility() != EVisibility::kVisible)
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc index 9487d5f3..6339629c 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -1436,9 +1436,9 @@ ASSERT_TRUE(container_layer); ASSERT_TRUE(contents_layer); - const base::flat_map<cc::RegionCaptureCropId, gfx::Rect>& container_bounds = + const base::flat_map<viz::RegionCaptureCropId, gfx::Rect>& container_bounds = container_layer->capture_bounds().bounds(); - const base::flat_map<cc::RegionCaptureCropId, gfx::Rect>& contents_bounds = + const base::flat_map<viz::RegionCaptureCropId, gfx::Rect>& contents_bounds = contents_layer->capture_bounds().bounds(); EXPECT_EQ(1u, container_bounds.size());
diff --git a/third_party/blink/renderer/core/paint/cull_rect_updater.cc b/third_party/blink/renderer/core/paint/cull_rect_updater.cc index be82ce9b..c764d1c 100644 --- a/third_party/blink/renderer/core/paint/cull_rect_updater.cc +++ b/third_party/blink/renderer/core/paint/cull_rect_updater.cc
@@ -251,9 +251,31 @@ PaintLayer& layer, const FragmentData& fragment, const FragmentData& parent_fragment) { + auto local_state = fragment.LocalBorderBoxProperties().Unalias(); + if (layer.GetLayoutObject().IsFixedPositioned()) { + const auto& view_fragment = layer.GetLayoutObject().View()->FirstFragment(); + auto view_state = view_fragment.LocalBorderBoxProperties().Unalias(); + if (local_state.Transform().Parent() == &view_state.Transform()) { + // Use the viewport clip and ignore additional clips (e.g. clip-paths) + // because they are applied on this fixed-position layer by non-containers + // which may change location relative to this layer on viewport scroll + // for which we don't want to change fixed-position cull rects for + // performance. + local_state.SetClip(view_fragment.ContentsProperties().Clip().Unalias()); + CullRect cull_rect = view_fragment.GetCullRect(); + // We don't expand cull rect for fixed-position because it doesn't scroll, + // so the ChangedEnough logic doesn't apply and we pass nullopt for the + // old cull rect. + bool expanded = + cull_rect.ApplyPaintProperties(root_state_, view_state, local_state, + /*old_cull_rect*/ absl::nullopt); + DCHECK(!expanded); + return cull_rect; + } + } + CullRect cull_rect = parent_fragment.GetContentsCullRect(); auto parent_state = parent_fragment.ContentsProperties().Unalias(); - auto local_state = fragment.LocalBorderBoxProperties().Unalias(); if (parent_state != local_state) { absl::optional<CullRect> old_cull_rect; // Not using |old_cull_rect| will force the cull rect to be updated @@ -302,6 +324,40 @@ return layer.SelfOrDescendantNeedsRepaint(); } +void CullRectUpdater::PaintPropertiesChanged(const LayoutObject& object, + PaintLayer& painting_layer) { + if (object.HasLayer()) { + To<LayoutBoxModelObject>(object).Layer()->SetNeedsCullRectUpdate(); + if (object.IsLayoutView() && + object.GetFrameView()->HasViewportConstrainedObjects()) { + // Fixed-position cull rects depend on view clip. See + // ComputeFragmentCullRect(). + if (const auto* clip_node = + object.FirstFragment().PaintProperties()->OverflowClip()) { + if (clip_node->NodeChanged() != PaintPropertyChangeType::kUnchanged) { + for (auto constrained : + *object.GetFrameView()->ViewportConstrainedObjects()) { + if (constrained->IsFixedPositioned()) { + To<LayoutBoxModelObject>(constrained.Get()) + ->Layer() + ->SetNeedsCullRectUpdate(); + } + } + } + } + } + return; + } + + if (object.SlowFirstChild()) { + // This ensures cull rect update of the child PaintLayers affected by the + // paint property change on a non-PaintLayer. Though this may unnecessarily + // force update of unrelated children, the situation is rare and this is + // much easier. + painting_layer.SetForcesChildrenCullRectUpdate(); + } +} + OverriddenCullRectScope::OverriddenCullRectScope(PaintLayer& starting_layer, const CullRect& cull_rect) : starting_layer_(starting_layer) {
diff --git a/third_party/blink/renderer/core/paint/cull_rect_updater.h b/third_party/blink/renderer/core/paint/cull_rect_updater.h index 8789906..02eca9f 100644 --- a/third_party/blink/renderer/core/paint/cull_rect_updater.h +++ b/third_party/blink/renderer/core/paint/cull_rect_updater.h
@@ -13,6 +13,7 @@ namespace blink { class FragmentData; +class LayoutObject; class PaintLayer; // This class is used for updating the cull rects of PaintLayer fragments (see: @@ -32,6 +33,9 @@ void Update(); + static void PaintPropertiesChanged(const LayoutObject&, + PaintLayer& painting_layer); + private: friend class OverriddenCullRectScope;
diff --git a/third_party/blink/renderer/core/paint/cull_rect_updater_test.cc b/third_party/blink/renderer/core/paint/cull_rect_updater_test.cc new file mode 100644 index 0000000..71ab03bc --- /dev/null +++ b/third_party/blink/renderer/core/paint/cull_rect_updater_test.cc
@@ -0,0 +1,51 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/paint/cull_rect_updater.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/paint/paint_layer.h" +#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" + +namespace blink { + +class CullRectUpdaterTest : public RenderingTest { + protected: + CullRect GetCullRect(const char* id) { + return GetLayoutObjectByElementId(id)->FirstFragment().GetCullRect(); + } +}; + +// TODO(wangxianzhu): Move other cull rect tests from PaintLayerPainterTest +// into this file. + +CullRect GetCullRect(const PaintLayer& layer) { + return layer.GetLayoutObject().FirstFragment().GetCullRect(); +} + +TEST_F(CullRectUpdaterTest, FixedPositionUnderClipPath) { + GetDocument().View()->Resize(800, 600); + SetBodyInnerHTML(R"HTML( + <div style="height: 100vh"></div> + <div style="width: 100px; height: 100px; clip-path: inset(0 0 0 0)"> + <div id="fixed" style="position: fixed; top: 0; left: 0; width: 1000px; + height: 1000px"></div> + </div> + )HTML"); + + EXPECT_EQ(gfx::Rect(0, 0, 800, 600), GetCullRect("fixed").Rect()); + + GetDocument().GetFrame()->DomWindow()->scrollTo(0, 1000); + GetDocument().View()->UpdateAllLifecyclePhasesExceptPaint( + DocumentUpdateReason::kTest); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ(gfx::Rect(0, 0, 800, 600), GetCullRect("fixed").Rect()); + + GetDocument().View()->Resize(800, 1000); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ(gfx::Rect(0, 0, 800, 1000), GetCullRect("fixed").Rect()); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index 40d02bc..fae49fa 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -116,7 +116,7 @@ if (item.IsHiddenForPaint()) return false; - PointerEventsHitRules hit_rules(PointerEventsHitRules::SVG_TEXT_HITTESTING, + PointerEventsHitRules hit_rules(PointerEventsHitRules::kSvgTextHitTesting, request, style.UsedPointerEvents()); if (hit_rules.require_visible && style.Visibility() != EVisibility::kVisible) return false;
diff --git a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc index b97d647..db966d5e 100644 --- a/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc +++ b/third_party/blink/renderer/core/paint/pre_paint_tree_walk.cc
@@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" +#include "third_party/blink/renderer/core/paint/cull_rect_updater.h" #include "third_party/blink/renderer/core/paint/object_paint_invalidator.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/paint/paint_property_tree_printer.h" @@ -648,16 +649,8 @@ (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled() && context.paint_invalidator_context.painting_layer ->SelfOrDescendantNeedsRepaint())) { - if (object.HasLayer()) { - To<LayoutBoxModelObject>(object).Layer()->SetNeedsCullRectUpdate(); - } else if (object.SlowFirstChild()) { - // This ensures cull rect update of the child PaintLayers affected by - // the paint property change on a non-PaintLayer. Though this may - // unnecessarily force update of unrelated children, the situation is - // rare and this is much easier. - context.paint_invalidator_context.painting_layer - ->SetForcesChildrenCullRectUpdate(); - } + CullRectUpdater::PaintPropertiesChanged( + object, *context.paint_invalidator_context.painting_layer); } } else if (context.clip_changed && object.HasLayer()) { // When this or ancestor clip changed, the layer needs repaint because it
diff --git a/third_party/blink/renderer/core/scheduler_integration_tests/scheduler_affecting_features_test.cc b/third_party/blink/renderer/core/scheduler_integration_tests/scheduler_affecting_features_test.cc index a56367a..2cb0ac35 100644 --- a/third_party/blink/renderer/core/scheduler_integration_tests/scheduler_affecting_features_test.cc +++ b/third_party/blink/renderer/core/scheduler_integration_tests/scheduler_affecting_features_test.cc
@@ -68,7 +68,7 @@ GetNonTrivialMainFrameFeatures(), testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket)); - MainFrame().ExecuteScript(WebString("socket.close();")); + MainFrame().ExecuteScript(WebScriptSource(WebString("socket.close();"))); EXPECT_FALSE(GetPageScheduler()->OptedOutFromAggressiveThrottlingForTest()); EXPECT_THAT(GetNonTrivialMainFrameFeatures(),
diff --git a/third_party/blink/renderer/core/script/classic_script.cc b/third_party/blink/renderer/core/script/classic_script.cc index 53a916e1..8811a64c 100644 --- a/third_party/blink/renderer/core/script/classic_script.cc +++ b/third_party/blink/renderer/core/script/classic_script.cc
@@ -48,11 +48,9 @@ ClassicScript* ClassicScript::CreateUnspecifiedScript( const WebScriptSource& source, SanitizeScriptErrors sanitize_script_errors) { - TextPosition position(OrdinalNumber::FromOneBasedInt(source.start_line), - OrdinalNumber::First()); return ClassicScript::CreateUnspecifiedScript( ScriptSourceCode(source.code, ScriptSourceLocationType::kUnknown, - nullptr /* cache_handler */, source.url, position), + nullptr /* cache_handler */, source.url), sanitize_script_errors); }
diff --git a/third_party/blink/renderer/core/scroll/build.gni b/third_party/blink/renderer/core/scroll/build.gni index 17299db..1cd15bf 100644 --- a/third_party/blink/renderer/core/scroll/build.gni +++ b/third_party/blink/renderer/core/scroll/build.gni
@@ -46,8 +46,8 @@ blink_core_sources_scroll += [ "mac_scrollbar_animator_impl.h", "mac_scrollbar_animator_impl.mm", + "scrollbar_theme_mac.cc", "scrollbar_theme_mac.h", - "scrollbar_theme_mac.mm", "web_scrollbar_theme.mm", ] } @@ -66,7 +66,3 @@ "scrollbar_test_suite.h", "scrollbar_theme_overlay_test.cc", ] - -if (is_mac) { - blink_core_tests_scroll += [ "scrollbar_theme_mac_test.mm" ] -}
diff --git a/third_party/blink/renderer/core/scroll/mac_scrollbar_animator.h b/third_party/blink/renderer/core/scroll/mac_scrollbar_animator.h index 6d5f918c..93f7df5 100644 --- a/third_party/blink/renderer/core/scroll/mac_scrollbar_animator.h +++ b/third_party/blink/renderer/core/scroll/mac_scrollbar_animator.h
@@ -13,6 +13,20 @@ class ScrollableArea; class Scrollbar; +// This class stores the state for an individual scrollbar (in contrast with +// MacScrollbarAnimator which has state for the full ScrollableArea). +class CORE_EXPORT MacScrollbar { + public: + static MacScrollbar* GetForScrollbar(const Scrollbar&); + virtual ~MacScrollbar() = default; + + virtual void SetEnabled(bool) = 0; + virtual void SetOverlayColorTheme(ScrollbarOverlayColorTheme) = 0; + virtual float GetKnobAlpha() = 0; + virtual float GetTrackAlpha() = 0; + virtual int GetTrackBoxWidth() = 0; +}; + // This is a base class for MacScrollbarAnimatorImpl. This is required because // mac_scrollbar_animator_impl.h has some #include that can't be included in // most platform-agnostic code.
diff --git a/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.h b/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.h index e758bf9..2664d17 100644 --- a/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.h +++ b/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.h
@@ -16,6 +16,7 @@ #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" #include "third_party/blink/renderer/platform/timer.h" +@class BlinkScrollbarObserver; @class BlinkScrollbarPainterControllerDelegate; @class BlinkScrollbarPainterDelegate; @@ -23,6 +24,44 @@ typedef id ScrollbarPainter; namespace blink { + +class ScrollbarThemeMac; + +class PLATFORM_EXPORT MacScrollbarImpl : public MacScrollbar { + public: + MacScrollbarImpl(Scrollbar&, + base::scoped_nsobject<ScrollbarPainterController>, + scoped_refptr<base::SingleThreadTaskRunner>, + ScrollbarThemeMac*, + std::unique_ptr<MacScrollbarImpl> old_scrollbar); + ~MacScrollbarImpl() override; + + static MacScrollbarImpl* GetForScrollbar(const Scrollbar&); + + void SetEnabled(bool) final; + void SetOverlayColorTheme(ScrollbarOverlayColorTheme) final; + float GetKnobAlpha() final; + float GetTrackAlpha() final; + int GetTrackBoxWidth() final; + + BlinkScrollbarPainterDelegate* painter_delegate() { + return painter_delegate_.get(); + } + BlinkScrollbarObserver* observer() { return observer_.get(); } + ScrollbarPainter painter(); + + private: + const bool is_horizontal_; + + // `painter_controller_` is also owned by the MacScrollbarAnimatorImpl + // that owns `this`. + base::scoped_nsobject<ScrollbarPainterController> painter_controller_; + + base::scoped_nsobject<BlinkScrollbarPainterDelegate> painter_delegate_; + + base::scoped_nsobject<BlinkScrollbarObserver> observer_; +}; + // This class handles scrollbar opacity animations by delegating to native // Cocoa APIs (.mm). // It was created with the goal of solving (crbug.com/682209), but we still @@ -116,14 +155,16 @@ } protected: + // Recreate the scrollbar painter for the specified scrollbar. + void RecreateScrollbarPainter(Scrollbar& scrollbar); + base::scoped_nsobject<ScrollbarPainterController> scrollbar_painter_controller_; base::scoped_nsobject<BlinkScrollbarPainterControllerDelegate> scrollbar_painter_controller_delegate_; - base::scoped_nsobject<BlinkScrollbarPainterDelegate> - horizontal_scrollbar_painter_delegate_; - base::scoped_nsobject<BlinkScrollbarPainterDelegate> - vertical_scrollbar_painter_delegate_; + + std::unique_ptr<MacScrollbarImpl> horizontal_scrollbar_; + std::unique_ptr<MacScrollbarImpl> vertical_scrollbar_; Member<ScrollableArea> scrollable_area_; };
diff --git a/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.mm b/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.mm index fe0539e4..d69bfe84 100644 --- a/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.mm +++ b/third_party/blink/renderer/core/scroll/mac_scrollbar_animator_impl.mm
@@ -16,6 +16,21 @@ #include "third_party/blink/renderer/platform/mac/block_exceptions.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" +namespace blink { +namespace { + +typedef HeapHashMap<WeakMember<const Scrollbar>, MacScrollbarImpl*> + ScrollbarToAnimatorMap; + +ScrollbarToAnimatorMap& GetScrollbarToAnimatorMap() { + DEFINE_STATIC_LOCAL(Persistent<ScrollbarToAnimatorMap>, map, + (MakeGarbageCollected<ScrollbarToAnimatorMap>())); + return *map; +} + +} // namespace +} // namespace blink + namespace { bool SupportsUIStateTransitionProgress() { // FIXME: This is temporary until all platforms that support ScrollbarPainter @@ -48,16 +63,92 @@ : nil; } -ScrollbarPainter ScrollbarPainterForScrollbar(blink::Scrollbar& scrollbar) { +bool IsScrollbarRegistered(blink::Scrollbar& scrollbar) { if (blink::ScrollbarThemeMac* scrollbar_theme = - MacOverlayScrollbarTheme(scrollbar.GetTheme())) - return scrollbar_theme->PainterForScrollbar(scrollbar); + MacOverlayScrollbarTheme(scrollbar.GetTheme())) { + return scrollbar_theme->IsScrollbarRegistered(scrollbar); + } + return false; +} +ScrollbarPainter ScrollbarPainterForScrollbar( + const blink::Scrollbar& scrollbar) { + if (auto* mac_scrollbar_impl = + blink::MacScrollbarImpl::GetForScrollbar(scrollbar)) { + return mac_scrollbar_impl->painter(); + } return nil; } } // namespace +@interface BlinkScrollbarObserver : NSObject { + blink::Scrollbar* _scrollbar; + base::scoped_nsobject<ScrollbarPainter> _scrollbarPainter; + BOOL _suppressSetScrollbarsHidden; + CGFloat _saved_knob_alpha; +} +- (instancetype) + initWithScrollbar:(blink::Scrollbar*)scrollbar + painter:(const base::scoped_nsobject<ScrollbarPainter>&)painter; +- (id)painter; +- (void)setSuppressSetScrollbarsHidden:(BOOL)value; +- (blink::Scrollbar*)scrollbar; +@end + +@implementation BlinkScrollbarObserver + +- (instancetype) + initWithScrollbar:(blink::Scrollbar*)scrollbar + painter:(const base::scoped_nsobject<ScrollbarPainter>&)painter { + if (!(self = [super init])) + return nil; + _scrollbar = scrollbar; + _scrollbarPainter = painter; + [_scrollbarPainter addObserver:self + forKeyPath:@"knobAlpha" + options:0 + context:nil]; + return self; +} + +- (id)painter { + return _scrollbarPainter; +} + +- (blink::Scrollbar*)scrollbar { + return _scrollbar; +} + +- (void)setSuppressSetScrollbarsHidden:(BOOL)value { + _suppressSetScrollbarsHidden = value; + if (value) { + _saved_knob_alpha = [_scrollbarPainter knobAlpha]; + } else { + [_scrollbarPainter setKnobAlpha:_saved_knob_alpha]; + _scrollbar->SetScrollbarsHiddenFromExternalAnimator(_saved_knob_alpha == 0); + } +} + +- (void)dealloc { + [_scrollbarPainter removeObserver:self forKeyPath:@"knobAlpha"]; + [super dealloc]; +} + +- (void)observeValueForKeyPath:(NSString*)keyPath + ofObject:(id)object + change:(NSDictionary*)change + context:(void*)context { + if ([keyPath isEqualToString:@"knobAlpha"]) { + if (!_suppressSetScrollbarsHidden) { + BOOL visible = [_scrollbarPainter knobAlpha] > 0; + _scrollbar->SetScrollbarsHiddenFromExternalAnimator(!visible); + } + } +} + +@end + // This class is a delegator of ScrollbarPainterController to ScrollableArea // that has the scrollbars of a ScrollbarPainter. @interface BlinkScrollbarPainterControllerDelegate : NSObject { @@ -600,6 +691,154 @@ @end namespace blink { + +MacScrollbarImpl::MacScrollbarImpl( + Scrollbar& scrollbar, + base::scoped_nsobject<ScrollbarPainterController> painter_controller, + scoped_refptr<base::SingleThreadTaskRunner> task_runner, + ScrollbarThemeMac* mac_theme, + std::unique_ptr<MacScrollbarImpl> old_scrollbar) + + : is_horizontal_(scrollbar.Orientation() == kHorizontalScrollbar), + painter_controller_(painter_controller) { + painter_delegate_.reset([[BlinkScrollbarPainterDelegate alloc] + initWithScrollbar:&scrollbar + taskRunner:task_runner]); + + const NSScrollerStyle style = [painter_controller_ scrollerStyle]; + const NSControlSize size = + (scrollbar.CSSScrollbarWidth() == EScrollbarWidth::kThin) + ? NSControlSizeSmall + : NSControlSizeRegular; + + ScrollbarPainter old_painter = nil; + if (old_scrollbar) { + old_painter = old_scrollbar->painter(); + if (is_horizontal_) + DCHECK_EQ(old_painter, [painter_controller_ horizontalScrollerImp]); + else + DCHECK_EQ(old_painter, [painter_controller_ verticalScrollerImp]); + } + + base::scoped_nsobject<ScrollbarPainter> new_painter( + [NSClassFromString(@"NSScrollerImp") scrollerImpWithStyle:style + controlSize:size + horizontal:is_horizontal_ + replacingScrollerImp:old_painter], + base::scoped_policy::RETAIN); + old_scrollbar.reset(); + + if (is_horizontal_) + [painter_controller_ setHorizontalScrollerImp:new_painter]; + else + [painter_controller_ setVerticalScrollerImp:new_painter]; + + [new_painter setDelegate:painter_delegate_]; + observer_.reset([[BlinkScrollbarObserver alloc] + initWithScrollbar:&scrollbar + painter:new_painter]); + + GetScrollbarToAnimatorMap().Set(&scrollbar, this); + + mac_theme->SetNewPainterForScrollbar(scrollbar); +} + +MacScrollbarImpl::~MacScrollbarImpl() { + auto it = GetScrollbarToAnimatorMap().find([observer_ scrollbar]); + DCHECK(it != GetScrollbarToAnimatorMap().end()); + DCHECK_EQ(it->value, this); + + if (is_horizontal_) + DCHECK_EQ([painter_controller_ horizontalScrollerImp], painter()); + else + DCHECK_EQ([painter_controller_ verticalScrollerImp], painter()); + + [painter() setDelegate:nil]; + [painter_delegate_ invalidate]; + painter_delegate_.reset(); + + if (is_horizontal_) + [painter_controller_ setHorizontalScrollerImp:nil]; + else + [painter_controller_ setVerticalScrollerImp:nil]; + observer_.reset(); + + GetScrollbarToAnimatorMap().erase(it); +} + +// static +MacScrollbarImpl* MacScrollbarImpl::GetForScrollbar( + const Scrollbar& scrollbar) { + auto it = GetScrollbarToAnimatorMap().find(&scrollbar); + if (it != GetScrollbarToAnimatorMap().end()) + return it->value; + return nullptr; +} + +void MacScrollbarImpl::SetEnabled(bool enabled) { + ScrollbarPainter painter = [observer_ painter]; + [painter setEnabled:enabled]; +} + +void MacScrollbarImpl::SetOverlayColorTheme(ScrollbarOverlayColorTheme theme) { + ScrollbarPainter painter = [observer_ painter]; + switch (theme) { + case kScrollbarOverlayColorThemeDark: + [painter setKnobStyle:NSScrollerKnobStyleDark]; + break; + case kScrollbarOverlayColorThemeLight: + [painter setKnobStyle:NSScrollerKnobStyleLight]; + break; + } +} + +float MacScrollbarImpl::GetKnobAlpha() { + ScrollbarPainter painter = [observer_ painter]; + return [painter knobAlpha]; +} + +float MacScrollbarImpl::GetTrackAlpha() { + // The following incantations are done to update the state of the + // ScrollbarPainter in ways that are unknown. It is important to leave + // these in place because we use ScrollbarPainter to populate |opacity| + // and because the ScrollAnimator doesn't animate correctly without them. + Scrollbar* scrollbar = [observer_ scrollbar]; + ScrollbarPainter scrollbar_painter = [observer_ painter]; + CGRect frame_rect = CGRect(scrollbar->FrameRect()); + [scrollbar_painter setEnabled:scrollbar->Enabled()]; + [scrollbar_painter setBoundsSize:NSSizeFromCGSize(frame_rect.size)]; + return [scrollbar_painter trackAlpha]; +} + +int MacScrollbarImpl::GetTrackBoxWidth() { + // The following incantations are done to update the state of the + // ScrollbarPainter in ways that are unknown. It is important to leave + // these in place because we use ScrollbarPainter to populate |thumb_size| + // and because the ScrollAnimator doesn't animate correctly without them. + Scrollbar* scrollbar = [observer_ scrollbar]; + ScrollbarPainter scrollbar_painter = [observer_ painter]; + + [scrollbar_painter setEnabled:scrollbar->Enabled()]; + + [scrollbar_painter setDoubleValue:0]; + [scrollbar_painter setKnobProportion:1]; + [observer_ setSuppressSetScrollbarsHidden:YES]; + [scrollbar_painter setKnobAlpha:1]; + + // If this state is not set, then moving the cursor over the scrollbar area + // will only cause the scrollbar to engorge when moved over the top of the + // scrollbar area. + [scrollbar_painter + setBoundsSize:NSSizeFromCGSize(CGSize(scrollbar->FrameRect().size()))]; + [observer_ setSuppressSetScrollbarsHidden:NO]; + + return [scrollbar_painter trackBoxWidth]; +} + +ScrollbarPainter MacScrollbarImpl::painter() { + return [observer_ painter]; +} + MacScrollbarAnimatorImpl::MacScrollbarAnimatorImpl( ScrollableArea* scrollable_area) : task_runner_(scrollable_area->GetCompositorTaskRunner()), @@ -614,23 +853,18 @@ performSelector:@selector(setDelegate:) withObject:scrollbar_painter_controller_delegate_]; [scrollbar_painter_controller_ - setScrollerStyle:ScrollbarThemeMac::RecommendedScrollerStyle()]; + setScrollerStyle:ScrollbarThemeMac::PreferOverlayScrollerStyle() + ? NSScrollerStyleOverlay + : NSScrollerStyleLegacy]; } void MacScrollbarAnimatorImpl::Dispose() { BEGIN_BLOCK_OBJC_EXCEPTIONS; - ScrollbarPainter horizontal_scrollbar_painter = - [scrollbar_painter_controller_ horizontalScrollerImp]; - [horizontal_scrollbar_painter setDelegate:nil]; - ScrollbarPainter vertical_scrollbar_painter = - [scrollbar_painter_controller_ verticalScrollerImp]; - [vertical_scrollbar_painter setDelegate:nil]; - + horizontal_scrollbar_.reset(); + vertical_scrollbar_.reset(); [scrollbar_painter_controller_delegate_ invalidate]; [scrollbar_painter_controller_ setDelegate:nil]; - [horizontal_scrollbar_painter_delegate_ invalidate]; - [vertical_scrollbar_painter_delegate_ invalidate]; END_BLOCK_OBJC_EXCEPTIONS; initial_scrollbar_paint_task_handle_.Cancel(); @@ -687,59 +921,35 @@ } void MacScrollbarAnimatorImpl::DidAddVerticalScrollbar(Scrollbar& scrollbar) { - ScrollbarPainter painter = ScrollbarPainterForScrollbar(scrollbar); - if (!painter) + if (!IsScrollbarRegistered(scrollbar)) return; - DCHECK(!vertical_scrollbar_painter_delegate_); - vertical_scrollbar_painter_delegate_.reset( - [[BlinkScrollbarPainterDelegate alloc] initWithScrollbar:&scrollbar - taskRunner:task_runner_]); - - [painter setDelegate:vertical_scrollbar_painter_delegate_]; - [scrollbar_painter_controller_ setVerticalScrollerImp:painter]; + DCHECK(!vertical_scrollbar_); + vertical_scrollbar_ = std::make_unique<MacScrollbarImpl>( + scrollbar, scrollbar_painter_controller_, task_runner_, + MacOverlayScrollbarTheme(scrollable_area_->GetPageScrollbarTheme()), + nullptr); } void MacScrollbarAnimatorImpl::WillRemoveVerticalScrollbar( Scrollbar& scrollbar) { - ScrollbarPainter painter = ScrollbarPainterForScrollbar(scrollbar); - DCHECK_EQ([scrollbar_painter_controller_ verticalScrollerImp], painter); - - if (!painter) - DCHECK(!vertical_scrollbar_painter_delegate_); - - [painter setDelegate:nil]; - [vertical_scrollbar_painter_delegate_ invalidate]; - vertical_scrollbar_painter_delegate_.reset(); - [scrollbar_painter_controller_ setVerticalScrollerImp:nil]; + vertical_scrollbar_.reset(); } void MacScrollbarAnimatorImpl::DidAddHorizontalScrollbar(Scrollbar& scrollbar) { - ScrollbarPainter painter = ScrollbarPainterForScrollbar(scrollbar); - if (!painter) + if (!IsScrollbarRegistered(scrollbar)) return; - DCHECK(!horizontal_scrollbar_painter_delegate_); - horizontal_scrollbar_painter_delegate_.reset( - [[BlinkScrollbarPainterDelegate alloc] initWithScrollbar:&scrollbar - taskRunner:task_runner_]); - - [painter setDelegate:horizontal_scrollbar_painter_delegate_]; - [scrollbar_painter_controller_ setHorizontalScrollerImp:painter]; + DCHECK(!horizontal_scrollbar_); + horizontal_scrollbar_ = std::make_unique<MacScrollbarImpl>( + scrollbar, scrollbar_painter_controller_, task_runner_, + MacOverlayScrollbarTheme(scrollable_area_->GetPageScrollbarTheme()), + nullptr); } void MacScrollbarAnimatorImpl::WillRemoveHorizontalScrollbar( Scrollbar& scrollbar) { - ScrollbarPainter painter = ScrollbarPainterForScrollbar(scrollbar); - DCHECK_EQ([scrollbar_painter_controller_ horizontalScrollerImp], painter); - - if (!painter) - DCHECK(!horizontal_scrollbar_painter_delegate_); - - [painter setDelegate:nil]; - [horizontal_scrollbar_painter_delegate_ invalidate]; - horizontal_scrollbar_painter_delegate_.reset(); - [scrollbar_painter_controller_ setHorizontalScrollerImp:nil]; + horizontal_scrollbar_.reset(); } bool MacScrollbarAnimatorImpl::SetScrollbarsVisibleForTesting(bool show) { @@ -748,8 +958,13 @@ else [scrollbar_painter_controller_ hideOverlayScrollers]; - [vertical_scrollbar_painter_delegate_ updateVisibilityImmediately:show]; - [horizontal_scrollbar_painter_delegate_ updateVisibilityImmediately:show]; + if (vertical_scrollbar_) { + [vertical_scrollbar_->painter_delegate() updateVisibilityImmediately:show]; + } + if (horizontal_scrollbar_) { + [horizontal_scrollbar_->painter_delegate() + updateVisibilityImmediately:show]; + } return true; } @@ -762,23 +977,12 @@ if (!mac_theme) return; - NSScrollerStyle new_style = [scrollbar_painter_controller_ scrollerStyle]; - if (Scrollbar* vertical_scrollbar = scrollable_area_->VerticalScrollbar()) { vertical_scrollbar->SetNeedsPaintInvalidation(kAllParts); - ScrollbarPainter old_vertical_painter = - [scrollbar_painter_controller_ verticalScrollerImp]; - ScrollbarPainter new_vertical_painter = [NSClassFromString(@"NSScrollerImp") - scrollerImpWithStyle:new_style - controlSize:NSRegularControlSize - horizontal:NO - replacingScrollerImp:old_vertical_painter]; - [old_vertical_painter setDelegate:nil]; - [new_vertical_painter setDelegate:vertical_scrollbar_painter_delegate_]; - [scrollbar_painter_controller_ setVerticalScrollerImp:new_vertical_painter]; - mac_theme->SetNewPainterForScrollbar(*vertical_scrollbar, - new_vertical_painter); + vertical_scrollbar_ = std::make_unique<MacScrollbarImpl>( + *vertical_scrollbar, scrollbar_painter_controller_, task_runner_, + mac_theme, std::move(vertical_scrollbar_)); // The different scrollbar styles have different thicknesses, so we must // re-set the frameRect to the new thickness, and the re-layout below will @@ -793,20 +997,9 @@ scrollable_area_->HorizontalScrollbar()) { horizontal_scrollbar->SetNeedsPaintInvalidation(kAllParts); - ScrollbarPainter old_horizontal_painter = - [scrollbar_painter_controller_ horizontalScrollerImp]; - ScrollbarPainter new_horizontal_painter = - [NSClassFromString(@"NSScrollerImp") - scrollerImpWithStyle:new_style - controlSize:NSRegularControlSize - horizontal:YES - replacingScrollerImp:old_horizontal_painter]; - [old_horizontal_painter setDelegate:nil]; - [new_horizontal_painter setDelegate:horizontal_scrollbar_painter_delegate_]; - [scrollbar_painter_controller_ - setHorizontalScrollerImp:new_horizontal_painter]; - mac_theme->SetNewPainterForScrollbar(*horizontal_scrollbar, - new_horizontal_painter); + horizontal_scrollbar_ = std::make_unique<MacScrollbarImpl>( + *horizontal_scrollbar, scrollbar_painter_controller_, task_runner_, + mac_theme, std::move(horizontal_scrollbar_)); // The different scrollbar styles have different thicknesses, so we must // re-set the @@ -867,9 +1060,19 @@ [scrollbar_painter_controller_ contentAreaScrolled]; } +// static MacScrollbarAnimator* MacScrollbarAnimator::Create( ScrollableArea* scrollable_area) { return MakeGarbageCollected<MacScrollbarAnimatorImpl>( const_cast<ScrollableArea*>(scrollable_area)); } + +// static +MacScrollbar* MacScrollbar::GetForScrollbar(const Scrollbar& scrollbar) { + auto it = GetScrollbarToAnimatorMap().find(&scrollbar); + if (it != GetScrollbarToAnimatorMap().end()) + return it->value; + return nullptr; +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.cc b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.cc new file mode 100644 index 0000000..0f82f19 --- /dev/null +++ b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.cc
@@ -0,0 +1,406 @@ +/* + * Copyright (C) 2008, 2011 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h" + +#include "base/memory/scoped_policy.h" +#include "skia/ext/skia_utils_mac.h" +#include "third_party/blink/public/common/input/web_mouse_event.h" +#include "third_party/blink/public/platform/mac/web_scrollbar_theme.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/web_theme_engine.h" +#include "third_party/blink/renderer/core/scroll/mac_scrollbar_animator.h" +#include "third_party/blink/renderer/platform/graphics/graphics_context.h" +#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h" +#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" +#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" + +namespace blink { + +static float s_initial_button_delay = 0.5f; +static float s_autoscroll_button_delay = 0.05f; +static bool s_prefer_overlay_scroller_style = false; +static bool s_jump_on_track_click = false; + +typedef HeapHashSet<WeakMember<Scrollbar>> ScrollbarSet; + +static ScrollbarSet& GetScrollbarSet() { + DEFINE_STATIC_LOCAL(Persistent<ScrollbarSet>, set, + (MakeGarbageCollected<ScrollbarSet>())); + return *set; +} + +// Values returned by NSScrollerImp's methods for querying sizes of various +// elements. +struct NSScrollerImpValues { + float track_width; + float track_box_width; + float knob_min_length; + float track_overlap_end_inset; + float knob_overlap_end_inset; + float track_end_inset; + float knob_end_inset; +}; +const NSScrollerImpValues& GetScrollbarPainterValues(bool overlay, + EScrollbarWidth width) { + static NSScrollerImpValues overlay_small_values = { + 14.0, 14.0, 26.0, 0.0, 0.0, 0.0, 1.0, + }; + static NSScrollerImpValues overlay_regular_values = { + 16.0, 16.0, 26.0, 0.0, 0.0, 0.0, 1.0, + }; + static NSScrollerImpValues legacy_small_values = { + 11.0, 11.0, 16.0, 0.0, 0.0, 0.0, 2.0, + }; + static NSScrollerImpValues legacy_regular_values = { + 15.0, 15.0, 20.0, 0.0, 0.0, 0.0, 2.0, + }; + if (overlay) { + return (width == EScrollbarWidth::kThin) ? overlay_small_values + : overlay_regular_values; + } else { + return (width == EScrollbarWidth::kThin) ? legacy_small_values + : legacy_regular_values; + } +} +const NSScrollerImpValues& GetScrollbarPainterValues( + const Scrollbar& scrollbar) { + return GetScrollbarPainterValues( + ScrollbarThemeMac::PreferOverlayScrollerStyle(), + scrollbar.CSSScrollbarWidth()); +} + +ScrollbarThemeMac::ScrollbarThemeMac() {} + +ScrollbarTheme& ScrollbarTheme::NativeTheme() { + DEFINE_STATIC_LOCAL(ScrollbarThemeMac, overlay_theme, ()); + return overlay_theme; +} + +void ScrollbarThemeMac::PaintTickmarks(GraphicsContext& context, + const Scrollbar& scrollbar, + const IntRect& rect) { + IntRect tickmark_track_rect = rect; + tickmark_track_rect.set_x(tickmark_track_rect.x() + 1); + tickmark_track_rect.set_width(tickmark_track_rect.width() - 1); + ScrollbarTheme::PaintTickmarks(context, scrollbar, tickmark_track_rect); +} + +bool ScrollbarThemeMac::ShouldCenterOnThumb(const Scrollbar& scrollbar, + const WebMouseEvent& event) { + bool alt_key_pressed = event.GetModifiers() & WebInputEvent::kAltKey; + return (event.button == WebPointerProperties::Button::kLeft) && + (s_jump_on_track_click != alt_key_pressed); +} + +ScrollbarThemeMac::~ScrollbarThemeMac() {} + +base::TimeDelta ScrollbarThemeMac::InitialAutoscrollTimerDelay() { + return base::Seconds(s_initial_button_delay); +} + +base::TimeDelta ScrollbarThemeMac::AutoscrollTimerDelay() { + return base::Seconds(s_autoscroll_button_delay); +} + +bool ScrollbarThemeMac::ShouldDragDocumentInsteadOfThumb( + const Scrollbar&, + const WebMouseEvent& event) { + return (event.GetModifiers() & WebInputEvent::Modifiers::kAltKey) != 0; +} + +ScrollbarPart ScrollbarThemeMac::PartsToInvalidateOnThumbPositionChange( + const Scrollbar& scrollbar, + float old_position, + float new_position) const { + // MacScrollbarAnimatorImpl will invalidate scrollbar parts if necessary. + return kNoPart; +} + +void ScrollbarThemeMac::RegisterScrollbar(Scrollbar& scrollbar) { + GetScrollbarSet().insert(&scrollbar); +} + +bool ScrollbarThemeMac::IsScrollbarRegistered(Scrollbar& scrollbar) const { + return GetScrollbarSet().Contains(&scrollbar); +} + +void ScrollbarThemeMac::SetNewPainterForScrollbar(Scrollbar& scrollbar) { + UpdateEnabledState(scrollbar); + UpdateScrollbarOverlayColorTheme(scrollbar); +} + +WebThemeEngine::ExtraParams GetPaintParams(const Scrollbar& scrollbar, + bool overlay) { + WebThemeEngine::ExtraParams params; + + params.scrollbar_extra.orientation = + WebThemeEngine::ScrollbarOrientation::kVerticalOnRight; + if (scrollbar.Orientation() == kHorizontalScrollbar) { + params.scrollbar_extra.orientation = + WebThemeEngine::ScrollbarOrientation::kHorizontal; + } else if (scrollbar.IsLeftSideVerticalScrollbar()) { + params.scrollbar_extra.orientation = + WebThemeEngine::ScrollbarOrientation::kVerticalOnLeft; + } + + params.scrollbar_extra.scrollbar_theme = + (scrollbar.UsedColorScheme() == mojom::blink::ColorScheme::kDark) + ? mojom::blink::ColorScheme::kDark + : mojom::blink::ColorScheme::kLight; + params.scrollbar_extra.is_overlay = overlay; + + if (overlay) { + params.scrollbar_extra.scrollbar_theme = + (scrollbar.GetScrollbarOverlayColorTheme() == + kScrollbarOverlayColorThemeLight) + ? mojom::blink::ColorScheme::kDark + : mojom::blink::ColorScheme::kLight; + } + + params.scrollbar_extra.is_hovering = + scrollbar.HoveredPart() != ScrollbarPart::kNoPart; + params.scrollbar_extra.scale_from_dip = scrollbar.ScaleFromDIP(); + return params; +} + +void ScrollbarThemeMac::PaintTrack(GraphicsContext& context, + const Scrollbar& scrollbar, + const IntRect& rect) { + GraphicsContextStateSaver state_saver(context); + context.Translate(rect.x(), rect.y()); + + auto* mac_scrollbar = MacScrollbar::GetForScrollbar(scrollbar); + if (!mac_scrollbar) + return; + + // The track opacity will be read from the ScrollbarPainter. + float opacity = mac_scrollbar->GetTrackAlpha(); + if (opacity == 0) + return; + + if (opacity != 1) + context.BeginLayer(opacity); + WebThemeEngine::ExtraParams params = + GetPaintParams(scrollbar, UsesOverlayScrollbars()); + IntRect bounds(0, 0, scrollbar.FrameRect().width(), + scrollbar.FrameRect().height()); + WebThemeEngine::Part track_part = + params.scrollbar_extra.orientation == + WebThemeEngine::ScrollbarOrientation::kHorizontal + ? WebThemeEngine::Part::kPartScrollbarHorizontalTrack + : WebThemeEngine::Part::kPartScrollbarVerticalTrack; + Platform::Current()->ThemeEngine()->Paint( + context.Canvas(), track_part, WebThemeEngine::State::kStateNormal, + ToGfxRect(bounds), ¶ms, params.scrollbar_extra.scrollbar_theme); + if (opacity != 1) + context.EndLayer(); +} + +void ScrollbarThemeMac::PaintScrollCorner( + GraphicsContext& context, + const Scrollbar* vertical_scrollbar, + const DisplayItemClient& item, + const IntRect& rect, + mojom::blink::ColorScheme color_scheme) { + if (!vertical_scrollbar) { + ScrollbarTheme::PaintScrollCorner(context, vertical_scrollbar, item, rect, + color_scheme); + return; + } + if (DrawingRecorder::UseCachedDrawingIfPossible(context, item, + DisplayItem::kScrollCorner)) { + return; + } + DrawingRecorder recorder(context, item, DisplayItem::kScrollCorner, + ToGfxRect(rect)); + + GraphicsContextStateSaver state_saver(context); + context.Translate(rect.x(), rect.y()); + IntRect bounds(0, 0, rect.width(), rect.height()); + WebThemeEngine::ExtraParams params = + GetPaintParams(*vertical_scrollbar, UsesOverlayScrollbars()); + Platform::Current()->ThemeEngine()->Paint( + context.Canvas(), WebThemeEngine::Part::kPartScrollbarCorner, + WebThemeEngine::State::kStateNormal, ToGfxRect(bounds), ¶ms, + params.scrollbar_extra.scrollbar_theme); +} + +void ScrollbarThemeMac::PaintThumbInternal(GraphicsContext& context, + const Scrollbar& scrollbar, + const IntRect& rect, + float opacity) { + if (DrawingRecorder::UseCachedDrawingIfPossible( + context, scrollbar, DisplayItem::kScrollbarThumb)) { + return; + } + DrawingRecorder recorder(context, scrollbar, DisplayItem::kScrollbarThumb, + ToGfxRect(rect)); + + GraphicsContextStateSaver state_saver(context); + context.Translate(rect.x(), rect.y()); + IntRect local_rect(gfx::Point(), rect.size()); + + if (!scrollbar.Enabled()) + return; + + auto* mac_scrollbar = MacScrollbar::GetForScrollbar(scrollbar); + if (!mac_scrollbar) + return; + + // The thumb size will be read from the ScrollbarPainter. + const int thumb_size = + mac_scrollbar->GetTrackBoxWidth() * scrollbar.ScaleFromDIP(); + + WebThemeEngine::ExtraParams params = + GetPaintParams(scrollbar, UsesOverlayScrollbars()); + + // Compute the bounds for the thumb, accounting for lack of engorgement. + IntRect bounds; + switch (params.scrollbar_extra.orientation) { + case WebThemeEngine::ScrollbarOrientation::kVerticalOnRight: + bounds = IntRect(rect.width() - thumb_size, 0, thumb_size, rect.height()); + break; + case WebThemeEngine::ScrollbarOrientation::kVerticalOnLeft: + bounds = IntRect(0, 0, thumb_size, rect.height()); + break; + case WebThemeEngine::ScrollbarOrientation::kHorizontal: + bounds = IntRect(0, rect.height() - thumb_size, rect.width(), thumb_size); + break; + } + + if (opacity != 1.0f) { + FloatRect float_local_rect(local_rect); + context.BeginLayer(opacity, SkBlendMode::kSrcOver, &float_local_rect); + } + + WebThemeEngine::Part thumb_part = + params.scrollbar_extra.orientation == + WebThemeEngine::ScrollbarOrientation::kHorizontal + ? WebThemeEngine::Part::kPartScrollbarHorizontalThumb + : WebThemeEngine::Part::kPartScrollbarVerticalThumb; + Platform::Current()->ThemeEngine()->Paint( + context.Canvas(), thumb_part, WebThemeEngine::State::kStateNormal, + ToGfxRect(bounds), ¶ms, params.scrollbar_extra.scrollbar_theme); + if (opacity != 1.0f) + context.EndLayer(); +} + +int ScrollbarThemeMac::ScrollbarThickness(float scale_from_dip, + EScrollbarWidth scrollbar_width) { + if (scrollbar_width == EScrollbarWidth::kNone) + return 0; + const auto& painter_values = + GetScrollbarPainterValues(UsesOverlayScrollbars(), scrollbar_width); + return painter_values.track_box_width * scale_from_dip; +} + +bool ScrollbarThemeMac::UsesOverlayScrollbars() const { + return PreferOverlayScrollerStyle(); +} + +void ScrollbarThemeMac::UpdateScrollbarOverlayColorTheme( + const Scrollbar& scrollbar) { + if (auto* mac_scrollbar = MacScrollbar::GetForScrollbar(scrollbar)) { + mac_scrollbar->SetOverlayColorTheme( + scrollbar.GetScrollbarOverlayColorTheme()); + } +} + +bool ScrollbarThemeMac::HasThumb(const Scrollbar& scrollbar) { + const auto& painter_values = GetScrollbarPainterValues(scrollbar); + int min_length_for_thumb = + painter_values.knob_min_length + painter_values.track_overlap_end_inset + + painter_values.knob_overlap_end_inset + + 2 * (painter_values.track_end_inset + painter_values.knob_end_inset); + return scrollbar.Enabled() && + (scrollbar.Orientation() == kHorizontalScrollbar + ? scrollbar.Width() + : scrollbar.Height()) >= min_length_for_thumb; +} + +IntRect ScrollbarThemeMac::BackButtonRect(const Scrollbar& scrollbar) { + return IntRect(); +} + +IntRect ScrollbarThemeMac::ForwardButtonRect(const Scrollbar& scrollbar) { + return IntRect(); +} + +IntRect ScrollbarThemeMac::TrackRect(const Scrollbar& scrollbar) { + return scrollbar.FrameRect(); +} + +int ScrollbarThemeMac::MinimumThumbLength(const Scrollbar& scrollbar) { + const auto& painter_values = GetScrollbarPainterValues(scrollbar); + return painter_values.knob_min_length; +} + +void ScrollbarThemeMac::UpdateEnabledState(const Scrollbar& scrollbar) { + if (auto* mac_scrollbar = MacScrollbar::GetForScrollbar(scrollbar)) + return mac_scrollbar->SetEnabled(scrollbar.Enabled()); +} + +float ScrollbarThemeMac::Opacity(const Scrollbar& scrollbar) const { + if (auto* mac_scrollbar = MacScrollbar::GetForScrollbar(scrollbar)) + return mac_scrollbar->GetKnobAlpha(); + return 1.f; +} + +bool ScrollbarThemeMac::JumpOnTrackClick() const { + return s_jump_on_track_click; +} + +// static +void ScrollbarThemeMac::UpdateScrollbarsWithNSDefaults( + absl::optional<float> initial_button_delay, + absl::optional<float> autoscroll_button_delay, + bool prefer_overlay_scroller_style, + bool redraw, + bool jump_on_track_click) { + s_initial_button_delay = + initial_button_delay.value_or(s_initial_button_delay); + s_autoscroll_button_delay = + autoscroll_button_delay.value_or(s_autoscroll_button_delay); + s_prefer_overlay_scroller_style = prefer_overlay_scroller_style; + s_jump_on_track_click = jump_on_track_click; + if (redraw) { + for (const auto& scrollbar : GetScrollbarSet()) { + scrollbar->StyleChanged(); + scrollbar->SetNeedsPaintInvalidation(kAllParts); + } + } +} + +// static +bool ScrollbarThemeMac::PreferOverlayScrollerStyle() { + if (OverlayScrollbarsEnabled()) + return true; + return s_prefer_overlay_scroller_style; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h index b5c6848..de3385f 100644 --- a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h +++ b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h
@@ -26,23 +26,17 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_MAC_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SCROLL_SCROLLBAR_THEME_MAC_H_ -#include <AppKit/AppKit.h> - -#include "third_party/blink/renderer/core/scroll/ns_scroller_imp_details.h" #include "third_party/blink/renderer/core/scroll/scrollbar_theme.h" -typedef id ScrollbarPainter; - namespace blink { -class Pattern; - class CORE_EXPORT ScrollbarThemeMac : public ScrollbarTheme { public: ScrollbarThemeMac(); ~ScrollbarThemeMac() override; void RegisterScrollbar(Scrollbar&) override; + bool IsScrollbarRegistered(Scrollbar&) const; // On Mac, the painting code itself animates the opacity so there's no need // to disable in order to make the scrollbars invisible. In fact, @@ -78,8 +72,7 @@ bool UsesOverlayScrollbars() const override; void UpdateScrollbarOverlayColorTheme(const Scrollbar&) override; - void SetNewPainterForScrollbar(Scrollbar&, ScrollbarPainter); - ScrollbarPainter PainterForScrollbar(const Scrollbar&) const; + void SetNewPainterForScrollbar(Scrollbar&); void PaintThumb(GraphicsContext& context, const Scrollbar& scrollbar, @@ -94,13 +87,13 @@ float Opacity(const Scrollbar&) const override; - static NSScrollerStyle RecommendedScrollerStyle(); + static bool PreferOverlayScrollerStyle(); // See WebScrollbarTheme for parameters description. static void UpdateScrollbarsWithNSDefaults( absl::optional<float> initial_button_delay, absl::optional<float> autoscroll_button_delay, - NSScrollerStyle preferred_scroller_style, + bool prefer_overlay_scroller_style, bool redraw, bool jump_on_track_click); @@ -131,8 +124,6 @@ const Scrollbar&, const IntRect&, float opacity); - - scoped_refptr<Pattern> overhang_pattern_; }; } // namespace blink
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm deleted file mode 100644 index 2e2a75d..0000000 --- a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac.mm +++ /dev/null
@@ -1,549 +0,0 @@ -/* - * Copyright (C) 2008, 2011 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h" - -#include <Carbon/Carbon.h> -#include "base/mac/scoped_nsobject.h" -#include "base/memory/scoped_policy.h" -#include "skia/ext/skia_utils_mac.h" -#include "third_party/blink/public/common/input/web_mouse_event.h" -#include "third_party/blink/public/platform/mac/web_scrollbar_theme.h" -#include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_theme_engine.h" -#include "third_party/blink/renderer/core/scroll/ns_scroller_imp_details.h" -#include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h" -#include "third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h" -#include "third_party/blink/renderer/platform/mac/color_mac.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "third_party/blink/renderer/platform/wtf/hash_set.h" -#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" - -@interface BlinkScrollbarObserver : NSObject { - blink::Scrollbar* _scrollbar; - base::scoped_nsobject<ScrollbarPainter> _scrollbarPainter; - BOOL _suppressSetScrollbarsHidden; - CGFloat _saved_knob_alpha; -} -- (instancetype) - initWithScrollbar:(blink::Scrollbar*)scrollbar - painter:(const base::scoped_nsobject<ScrollbarPainter>&)painter; -@end - -@implementation BlinkScrollbarObserver - -- (instancetype) - initWithScrollbar:(blink::Scrollbar*)scrollbar - painter:(const base::scoped_nsobject<ScrollbarPainter>&)painter { - if (!(self = [super init])) - return nil; - _scrollbar = scrollbar; - _scrollbarPainter = painter; - [_scrollbarPainter addObserver:self - forKeyPath:@"knobAlpha" - options:0 - context:nil]; - return self; -} - -- (id)painter { - return _scrollbarPainter; -} - -- (void)setSuppressSetScrollbarsHidden:(BOOL)value { - _suppressSetScrollbarsHidden = value; - if (value) { - _saved_knob_alpha = [_scrollbarPainter knobAlpha]; - } else { - [_scrollbarPainter setKnobAlpha:_saved_knob_alpha]; - _scrollbar->SetScrollbarsHiddenFromExternalAnimator(_saved_knob_alpha == 0); - } -} - -- (void)dealloc { - [_scrollbarPainter removeObserver:self forKeyPath:@"knobAlpha"]; - [super dealloc]; -} - -- (void)observeValueForKeyPath:(NSString*)keyPath - ofObject:(id)object - change:(NSDictionary*)change - context:(void*)context { - if ([keyPath isEqualToString:@"knobAlpha"]) { - if (!_suppressSetScrollbarsHidden) { - BOOL visible = [_scrollbarPainter knobAlpha] > 0; - _scrollbar->SetScrollbarsHiddenFromExternalAnimator(!visible); - } - } -} - -@end - -namespace blink { - -static float s_initial_button_delay = 0.5f; -static float s_autoscroll_button_delay = 0.05f; -static NSScrollerStyle s_preferred_scroller_style = NSScrollerStyleLegacy; -static bool s_jump_on_track_click = false; - -typedef HeapHashSet<WeakMember<Scrollbar>> ScrollbarSet; - -static ScrollbarSet& GetScrollbarSet() { - DEFINE_STATIC_LOCAL(Persistent<ScrollbarSet>, set, - (MakeGarbageCollected<ScrollbarSet>())); - return *set; -} - -typedef HeapHashMap<WeakMember<Scrollbar>, - base::scoped_nsobject<BlinkScrollbarObserver>> - ScrollbarPainterMap; - -static ScrollbarPainterMap& GetScrollbarPainterMap() { - DEFINE_STATIC_LOCAL(Persistent<ScrollbarPainterMap>, map, - (MakeGarbageCollected<ScrollbarPainterMap>())); - return *map; -} - -static int ScrollbarThicknessInternal(NSControlSize control_size, - NSScrollerStyle scroller_style) { - ScrollbarPainter scrollbar_painter = - [NSClassFromString(@"NSScrollerImp") scrollerImpWithStyle:scroller_style - controlSize:control_size - horizontal:NO - replacingScrollerImp:nil]; - if ([scrollbar_painter respondsToSelector:@selector(setExpanded:)]) { - [scrollbar_painter setExpanded:YES]; - } - return [scrollbar_painter trackBoxWidth]; -} - -static int OverlayScrollbarThickness(NSControlSize control_size) { - static int small_scrollbar_thickness = - ScrollbarThicknessInternal(NSControlSizeSmall, NSScrollerStyleOverlay); - static int regular_scrollbar_thickness = - ScrollbarThicknessInternal(NSControlSizeRegular, NSScrollerStyleOverlay); - - return control_size == NSControlSizeSmall ? small_scrollbar_thickness - : regular_scrollbar_thickness; -} - -static int LegacyScrollbarThickness(NSControlSize control_size) { - static int small_scrollbar_thickness = - ScrollbarThicknessInternal(NSControlSizeSmall, NSScrollerStyleLegacy); - static int regular_scrollbar_thickness = - ScrollbarThicknessInternal(NSControlSizeRegular, NSScrollerStyleLegacy); - - return control_size == NSControlSizeSmall ? small_scrollbar_thickness - : regular_scrollbar_thickness; -} - -ScrollbarThemeMac::ScrollbarThemeMac() { -} - -ScrollbarTheme& ScrollbarTheme::NativeTheme() { - DEFINE_STATIC_LOCAL(ScrollbarThemeMac, overlay_theme, ()); - return overlay_theme; -} - -void ScrollbarThemeMac::PaintTickmarks(GraphicsContext& context, - const Scrollbar& scrollbar, - const IntRect& rect) { - IntRect tickmark_track_rect = rect; - tickmark_track_rect.set_x(tickmark_track_rect.x() + 1); - tickmark_track_rect.set_width(tickmark_track_rect.width() - 1); - ScrollbarTheme::PaintTickmarks(context, scrollbar, tickmark_track_rect); -} - -bool ScrollbarThemeMac::ShouldCenterOnThumb(const Scrollbar& scrollbar, - const WebMouseEvent& event) { - bool alt_key_pressed = event.GetModifiers() & WebInputEvent::kAltKey; - return (event.button == WebPointerProperties::Button::kLeft) && - (s_jump_on_track_click != alt_key_pressed); -} - -ScrollbarThemeMac::~ScrollbarThemeMac() { -} - -base::TimeDelta ScrollbarThemeMac::InitialAutoscrollTimerDelay() { - return base::Seconds(s_initial_button_delay); -} - -base::TimeDelta ScrollbarThemeMac::AutoscrollTimerDelay() { - return base::Seconds(s_autoscroll_button_delay); -} - -bool ScrollbarThemeMac::ShouldDragDocumentInsteadOfThumb( - const Scrollbar&, - const WebMouseEvent& event) { - return (event.GetModifiers() & WebInputEvent::Modifiers::kAltKey) != 0; -} - -ScrollbarPart ScrollbarThemeMac::PartsToInvalidateOnThumbPositionChange( - const Scrollbar& scrollbar, - float old_position, - float new_position) const { - // MacScrollbarAnimatorImpl will invalidate scrollbar parts if necessary. - return kNoPart; -} - -void ScrollbarThemeMac::RegisterScrollbar(Scrollbar& scrollbar) { - GetScrollbarSet().insert(&scrollbar); - - NSControlSize size; - if (scrollbar.CSSScrollbarWidth() == EScrollbarWidth::kThin) - size = NSControlSizeSmall; - else - size = NSControlSizeRegular; - - bool is_horizontal = scrollbar.Orientation() == kHorizontalScrollbar; - base::scoped_nsobject<ScrollbarPainter> scrollbar_painter([[NSClassFromString( - @"NSScrollerImp") scrollerImpWithStyle:RecommendedScrollerStyle() - controlSize:size - horizontal:is_horizontal - replacingScrollerImp:nil] retain]); - base::scoped_nsobject<BlinkScrollbarObserver> observer( - [[BlinkScrollbarObserver alloc] initWithScrollbar:&scrollbar - painter:scrollbar_painter]); - - GetScrollbarPainterMap().insert(&scrollbar, observer); - UpdateEnabledState(scrollbar); - UpdateScrollbarOverlayColorTheme(scrollbar); -} - -void ScrollbarThemeMac::SetNewPainterForScrollbar( - Scrollbar& scrollbar, - ScrollbarPainter new_painter) { - base::scoped_nsobject<ScrollbarPainter> scrollbar_painter( - [new_painter retain]); - base::scoped_nsobject<BlinkScrollbarObserver> observer( - [[BlinkScrollbarObserver alloc] initWithScrollbar:&scrollbar - painter:scrollbar_painter]); - GetScrollbarPainterMap().Set(&scrollbar, observer); - UpdateEnabledState(scrollbar); - UpdateScrollbarOverlayColorTheme(scrollbar); -} - -ScrollbarPainter ScrollbarThemeMac::PainterForScrollbar( - const Scrollbar& scrollbar) const { - auto it = GetScrollbarPainterMap().find(const_cast<Scrollbar*>(&scrollbar)); - return it != GetScrollbarPainterMap().end() ? [it->value painter] : nil; -} - -WebThemeEngine::ExtraParams GetPaintParams(const Scrollbar& scrollbar, - bool overlay) { - WebThemeEngine::ExtraParams params; - - params.scrollbar_extra.orientation = - WebThemeEngine::ScrollbarOrientation::kVerticalOnRight; - if (scrollbar.Orientation() == kHorizontalScrollbar) { - params.scrollbar_extra.orientation = - WebThemeEngine::ScrollbarOrientation::kHorizontal; - } else if (scrollbar.IsLeftSideVerticalScrollbar()) { - params.scrollbar_extra.orientation = - WebThemeEngine::ScrollbarOrientation::kVerticalOnLeft; - } - - params.scrollbar_extra.scrollbar_theme = - (scrollbar.UsedColorScheme() == mojom::blink::ColorScheme::kDark) - ? mojom::blink::ColorScheme::kDark - : mojom::blink::ColorScheme::kLight; - params.scrollbar_extra.is_overlay = overlay; - - if (overlay) { - params.scrollbar_extra.scrollbar_theme = - (scrollbar.GetScrollbarOverlayColorTheme() == - kScrollbarOverlayColorThemeLight) - ? mojom::blink::ColorScheme::kDark - : mojom::blink::ColorScheme::kLight; - } - - params.scrollbar_extra.is_hovering = - scrollbar.HoveredPart() != ScrollbarPart::kNoPart; - params.scrollbar_extra.scale_from_dip = scrollbar.ScaleFromDIP(); - return params; -} - -void ScrollbarThemeMac::PaintTrack(GraphicsContext& context, - const Scrollbar& scrollbar, - const IntRect& rect) { - GraphicsContextStateSaver state_saver(context); - context.Translate(rect.x(), rect.y()); - - // The track opacity will be read from the ScrollbarPainter. - float opacity = 1.f; - - // The following incantations are done to update the state of the - // ScrollbarPainter in ways that are unknown. It is important to leave - // these in place because we use ScrollbarPainter to populate |opacity| - // and because the ScrollAnimator doesn't animate correctly without them. - { - CGRect frame_rect = CGRect(scrollbar.FrameRect()); - ScrollbarPainter scrollbar_painter = PainterForScrollbar(scrollbar); - DCHECK(scrollbar_painter); - [scrollbar_painter setEnabled:scrollbar.Enabled()]; - [scrollbar_painter setBoundsSize:NSSizeFromCGSize(frame_rect.size)]; - opacity = [scrollbar_painter trackAlpha]; - } - - if (opacity == 0) - return; - - if (opacity != 1) - context.BeginLayer(opacity); - WebThemeEngine::ExtraParams params = - GetPaintParams(scrollbar, UsesOverlayScrollbars()); - IntRect bounds(0, 0, scrollbar.FrameRect().width(), - scrollbar.FrameRect().height()); - WebThemeEngine::Part track_part = - params.scrollbar_extra.orientation == - WebThemeEngine::ScrollbarOrientation::kHorizontal - ? WebThemeEngine::Part::kPartScrollbarHorizontalTrack - : WebThemeEngine::Part::kPartScrollbarVerticalTrack; - Platform::Current()->ThemeEngine()->Paint( - context.Canvas(), track_part, WebThemeEngine::State::kStateNormal, - ToGfxRect(bounds), ¶ms, params.scrollbar_extra.scrollbar_theme); - if (opacity != 1) - context.EndLayer(); -} - -void ScrollbarThemeMac::PaintScrollCorner( - GraphicsContext& context, - const Scrollbar* vertical_scrollbar, - const DisplayItemClient& item, - const IntRect& rect, - mojom::blink::ColorScheme color_scheme) { - if (!vertical_scrollbar) { - ScrollbarTheme::PaintScrollCorner(context, vertical_scrollbar, item, rect, - color_scheme); - return; - } - if (DrawingRecorder::UseCachedDrawingIfPossible(context, item, - DisplayItem::kScrollCorner)) { - return; - } - DrawingRecorder recorder(context, item, DisplayItem::kScrollCorner, - ToGfxRect(rect)); - - GraphicsContextStateSaver state_saver(context); - context.Translate(rect.x(), rect.y()); - IntRect bounds(0, 0, rect.width(), rect.height()); - WebThemeEngine::ExtraParams params = - GetPaintParams(*vertical_scrollbar, UsesOverlayScrollbars()); - Platform::Current()->ThemeEngine()->Paint( - context.Canvas(), WebThemeEngine::Part::kPartScrollbarCorner, - WebThemeEngine::State::kStateNormal, ToGfxRect(bounds), ¶ms, - params.scrollbar_extra.scrollbar_theme); -} - -void ScrollbarThemeMac::PaintThumbInternal(GraphicsContext& context, - const Scrollbar& scrollbar, - const IntRect& rect, - float opacity) { - if (DrawingRecorder::UseCachedDrawingIfPossible( - context, scrollbar, DisplayItem::kScrollbarThumb)) { - return; - } - DrawingRecorder recorder(context, scrollbar, DisplayItem::kScrollbarThumb, - ToGfxRect(rect)); - - GraphicsContextStateSaver state_saver(context); - context.Translate(rect.x(), rect.y()); - IntRect local_rect(gfx::Point(), rect.size()); - - // The thumb size will be read from the ScrollbarPainter. - int thumb_size = 0; - - // The following incantations are done to update the state of the - // ScrollbarPainter in ways that are unknown. It is important to leave - // these in place because we use ScrollbarPainter to populate |thumb_size| - // and because the ScrollAnimator doesn't animate correctly without them. - { - base::scoped_nsobject<BlinkScrollbarObserver> observer( - GetScrollbarPainterMap().at(const_cast<Scrollbar*>(&scrollbar)), - base::scoped_policy::RETAIN); - ScrollbarPainter scrollbar_painter = [observer painter]; - [scrollbar_painter setEnabled:scrollbar.Enabled()]; - - [scrollbar_painter setDoubleValue:0]; - [scrollbar_painter setKnobProportion:1]; - [observer setSuppressSetScrollbarsHidden:YES]; - [scrollbar_painter setKnobAlpha:1]; - - // If this state is not set, then moving the cursor over the scrollbar area - // will only cause the scrollbar to engorge when moved over the top of the - // scrollbar area. - [scrollbar_painter - setBoundsSize:NSSizeFromCGSize(CGSize(scrollbar.FrameRect().size()))]; - [observer setSuppressSetScrollbarsHidden:NO]; - - thumb_size = [scrollbar_painter trackBoxWidth] * scrollbar.ScaleFromDIP(); - } - - if (!scrollbar.Enabled()) - return; - - WebThemeEngine::ExtraParams params = - GetPaintParams(scrollbar, UsesOverlayScrollbars()); - - // Compute the bounds for the thumb, accounting for lack of engorgement. - IntRect bounds; - switch (params.scrollbar_extra.orientation) { - case WebThemeEngine::ScrollbarOrientation::kVerticalOnRight: - bounds = IntRect(rect.width() - thumb_size, 0, thumb_size, rect.height()); - break; - case WebThemeEngine::ScrollbarOrientation::kVerticalOnLeft: - bounds = IntRect(0, 0, thumb_size, rect.height()); - break; - case WebThemeEngine::ScrollbarOrientation::kHorizontal: - bounds = IntRect(0, rect.height() - thumb_size, rect.width(), thumb_size); - break; - } - - if (opacity != 1.0f) { - FloatRect float_local_rect(local_rect); - context.BeginLayer(opacity, SkBlendMode::kSrcOver, &float_local_rect); - } - - WebThemeEngine::Part thumb_part = - params.scrollbar_extra.orientation == - WebThemeEngine::ScrollbarOrientation::kHorizontal - ? WebThemeEngine::Part::kPartScrollbarHorizontalThumb - : WebThemeEngine::Part::kPartScrollbarVerticalThumb; - Platform::Current()->ThemeEngine()->Paint( - context.Canvas(), thumb_part, WebThemeEngine::State::kStateNormal, - ToGfxRect(bounds), ¶ms, params.scrollbar_extra.scrollbar_theme); - if (opacity != 1.0f) - context.EndLayer(); -} - -int ScrollbarThemeMac::ScrollbarThickness(float scale_from_dip, - EScrollbarWidth scrollbar_width) { - if (scrollbar_width == EScrollbarWidth::kNone) - return 0; - - NSControlSize control_size = scrollbar_width == EScrollbarWidth::kThin - ? NSControlSizeSmall - : NSControlSizeRegular; - - return RecommendedScrollerStyle() == NSScrollerStyleOverlay - ? OverlayScrollbarThickness(control_size) * scale_from_dip - : LegacyScrollbarThickness(control_size) * scale_from_dip; -} - -bool ScrollbarThemeMac::UsesOverlayScrollbars() const { - return RecommendedScrollerStyle() == NSScrollerStyleOverlay; -} - -void ScrollbarThemeMac::UpdateScrollbarOverlayColorTheme( - const Scrollbar& scrollbar) { - ScrollbarPainter painter = PainterForScrollbar(scrollbar); - DCHECK(painter); - switch (scrollbar.GetScrollbarOverlayColorTheme()) { - case kScrollbarOverlayColorThemeDark: - [painter setKnobStyle:NSScrollerKnobStyleDark]; - break; - case kScrollbarOverlayColorThemeLight: - [painter setKnobStyle:NSScrollerKnobStyleLight]; - break; - } -} - -bool ScrollbarThemeMac::HasThumb(const Scrollbar& scrollbar) { - ScrollbarPainter painter = PainterForScrollbar(scrollbar); - DCHECK(painter); - int min_length_for_thumb = - [painter knobMinLength] + [painter trackOverlapEndInset] + - [painter knobOverlapEndInset] + - 2 * ([painter trackEndInset] + [painter knobEndInset]); - return scrollbar.Enabled() && - (scrollbar.Orientation() == kHorizontalScrollbar - ? scrollbar.Width() - : scrollbar.Height()) >= min_length_for_thumb; -} - -IntRect ScrollbarThemeMac::BackButtonRect(const Scrollbar& scrollbar) { - return IntRect(); -} - -IntRect ScrollbarThemeMac::ForwardButtonRect(const Scrollbar& scrollbar) { - return IntRect(); -} - -IntRect ScrollbarThemeMac::TrackRect(const Scrollbar& scrollbar) { - return scrollbar.FrameRect(); -} - -int ScrollbarThemeMac::MinimumThumbLength(const Scrollbar& scrollbar) { - ScrollbarPainter painter = PainterForScrollbar(scrollbar); - DCHECK(painter); - return [painter knobMinLength]; -} - -void ScrollbarThemeMac::UpdateEnabledState(const Scrollbar& scrollbar) { - ScrollbarPainter painter = PainterForScrollbar(scrollbar); - DCHECK(painter); - [painter setEnabled:scrollbar.Enabled()]; -} - -float ScrollbarThemeMac::Opacity(const Scrollbar& scrollbar) const { - ScrollbarPainter painter = PainterForScrollbar(scrollbar); - DCHECK(painter); - return [painter knobAlpha]; -} - -bool ScrollbarThemeMac::JumpOnTrackClick() const { - return s_jump_on_track_click; -} - -// static -void ScrollbarThemeMac::UpdateScrollbarsWithNSDefaults( - absl::optional<float> initial_button_delay, - absl::optional<float> autoscroll_button_delay, - NSScrollerStyle preferred_scroller_style, - bool redraw, - bool jump_on_track_click) { - s_initial_button_delay = - initial_button_delay.value_or(s_initial_button_delay); - s_autoscroll_button_delay = - autoscroll_button_delay.value_or(s_autoscroll_button_delay); - s_preferred_scroller_style = preferred_scroller_style; - s_jump_on_track_click = jump_on_track_click; - if (redraw) { - for (const auto& scrollbar : GetScrollbarSet()) { - scrollbar->StyleChanged(); - scrollbar->SetNeedsPaintInvalidation(kAllParts); - } - } -} - -// static -NSScrollerStyle ScrollbarThemeMac::RecommendedScrollerStyle() { - if (OverlayScrollbarsEnabled()) - return NSScrollerStyleOverlay; - return s_preferred_scroller_style; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac_test.mm b/third_party/blink/renderer/core/scroll/scrollbar_theme_mac_test.mm deleted file mode 100644 index e0a77ff..0000000 --- a/third_party/blink/renderer/core/scroll/scrollbar_theme_mac_test.mm +++ /dev/null
@@ -1,160 +0,0 @@ -// 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 "third_party/blink/renderer/core/scroll/scrollbar_theme_mac.h" - -#import <objc/runtime.h> - -#include "base/mac/scoped_objc_class_swizzler.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/graphics/scrollbar_theme_settings.h" - -namespace { - -const float kScaleFromDip = 2.0; -const int kRegularTrackBoxWidth = 100; -const int kSmallTrackBoxWidth = 50; -const int kLegacyScrollbarExtraWidth = 10; - -NSScrollerStyle scroller_style; -NSControlSize control_size; - -} // namespace - -@class NSScrollerImp; - -// A class that provides alternate implementations of select NSScrollerImp -// methods. Once these methods are swizzled into place we can catch parameters -// and return the values we want for the tests. -@interface FakeNSScrollerImp : NSObject - -+ (NSScrollerImp*)scrollerImpWithStyle:(NSScrollerStyle)newScrollerStyle - controlSize:(NSControlSize)newControlSize - horizontal:(BOOL)horizontal - replacingScrollerImp:(id)previous; -- (CGFloat)trackBoxWidth; - -@end - -@implementation FakeNSScrollerImp - -+ (std::unique_ptr<base::mac::ScopedObjCClassSwizzler>&)factorySwizzler { - static std::unique_ptr<base::mac::ScopedObjCClassSwizzler> factorySwizzler; - - return factorySwizzler; -} - -+ (std::unique_ptr<base::mac::ScopedObjCClassSwizzler>&)trackBoxWidthSwizzler { - static std::unique_ptr<base::mac::ScopedObjCClassSwizzler> - trackBoxWidthSwizzler; - - return trackBoxWidthSwizzler; -} - -+ (void)setUpSwizzles { - [self factorySwizzler].reset(new base::mac::ScopedObjCClassSwizzler( - NSClassFromString(@"NSScrollerImp"), [FakeNSScrollerImp class], - @selector(scrollerImpWithStyle: - controlSize:horizontal:replacingScrollerImp:))); - - [self trackBoxWidthSwizzler].reset(new base::mac::ScopedObjCClassSwizzler( - NSClassFromString(@"NSScrollerImp"), [FakeNSScrollerImp class], - @selector(trackBoxWidth))); -} - -+ (void)tearDownSwizzles { - [self factorySwizzler].reset(); - [self trackBoxWidthSwizzler].reset(); -} - -+ (NSScrollerImp*)scrollerImpWithStyle:(NSScrollerStyle)newScrollerStyle - controlSize:(NSControlSize)newControlSize - horizontal:(BOOL)horizontal - replacingScrollerImp:(id)previous { - // Capture the incoming scroller style and control size (these parameters - // can't be retrieved from the NSScrollerImp). - scroller_style = newScrollerStyle; - control_size = newControlSize; - - // With the style and size stored call the NSScrollerImp factory - // method as usual. - return [FakeNSScrollerImp factorySwizzler] - ->InvokeOriginal<NSScrollerImp*, NSScrollerStyle, NSControlSize, BOOL, - id>( - NSClassFromString(@"NSScrollerImp"), - @selector(scrollerImpWithStyle: - controlSize:horizontal:replacingScrollerImp:), - newScrollerStyle, newControlSize, horizontal, previous); -} - -- (CGFloat)trackBoxWidth { - // Compute a track box width. |control_size| is the size we were "created" - // with (in the factory above). - int trackBoxWidth = control_size == NSControlSizeSmall - ? kSmallTrackBoxWidth - : kRegularTrackBoxWidth; - - // If the NSScrollerImp was created for legacy scrollbars, make it a little - // wider. - int extraWidth = - scroller_style == NSScrollerStyleLegacy ? kLegacyScrollbarExtraWidth : 0; - - return trackBoxWidth + extraWidth; -} - -@end - -namespace blink { - -class ScrollbarThemeMacTest : public testing::Test { - public: - void SetUp() override { - // Swap out the NSScrollerImp factory and -trackBoxWidth implementations - // for our own. - [FakeNSScrollerImp setUpSwizzles]; - } - - void SetOverlayScrollbarsEnabled(bool flag) { - ScrollbarThemeSettings::SetOverlayScrollbarsEnabled(flag); - } - - void TearDown() override { [FakeNSScrollerImp tearDownSwizzles]; } - - ScrollbarThemeMac scrollbar_theme_mac; -}; - -TEST_F(ScrollbarThemeMacTest, SmallControlSizeLegacy) { - SetOverlayScrollbarsEnabled(false); - - EXPECT_EQ((kSmallTrackBoxWidth + kLegacyScrollbarExtraWidth) * kScaleFromDip, - scrollbar_theme_mac.ScrollbarThickness(kScaleFromDip, - EScrollbarWidth::kThin)); -} - -TEST_F(ScrollbarThemeMacTest, RegularControlSizeLegacy) { - SetOverlayScrollbarsEnabled(false); - - EXPECT_EQ( - (kRegularTrackBoxWidth + kLegacyScrollbarExtraWidth) * kScaleFromDip, - scrollbar_theme_mac.ScrollbarThickness(kScaleFromDip, - EScrollbarWidth::kAuto)); -} - -TEST_F(ScrollbarThemeMacTest, SmallControlSizeOverlay) { - SetOverlayScrollbarsEnabled(true); - - EXPECT_EQ(kSmallTrackBoxWidth * kScaleFromDip, - scrollbar_theme_mac.ScrollbarThickness(kScaleFromDip, - EScrollbarWidth::kThin)); -} - -TEST_F(ScrollbarThemeMacTest, RegularControlSizeOverlay) { - SetOverlayScrollbarsEnabled(true); - - EXPECT_EQ(kRegularTrackBoxWidth * kScaleFromDip, - scrollbar_theme_mac.ScrollbarThickness(kScaleFromDip, - EScrollbarWidth::kAuto)); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/scroll/web_scrollbar_theme.mm b/third_party/blink/renderer/core/scroll/web_scrollbar_theme.mm index 6537e36..4c2022a 100644 --- a/third_party/blink/renderer/core/scroll/web_scrollbar_theme.mm +++ b/third_party/blink/renderer/core/scroll/web_scrollbar_theme.mm
@@ -52,7 +52,7 @@ bool jump_on_track_click) { ScrollbarThemeMac::UpdateScrollbarsWithNSDefaults( initial_button_delay, autoscroll_button_delay, - static_cast<NSScrollerStyle>(preferred_scroller_style), redraw, + preferred_scroller_style == kScrollerStyleOverlay, redraw, jump_on_track_click); }
diff --git a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 index 97fb5f9..8179db2 100644 --- a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 +++ b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
@@ -98,7 +98,7 @@ "GridAutoRepeatRowsType", "-webkit-box-flex", "-webkit-box-ordinal-group", "flex-basis", "flex-shrink", "flex-grow", "flex-direction", "flex-wrap", "-webkit-box-align", - "-webkit-box-pack", "-webkit-box-orient", + "-webkit-box-decoration-break", "-webkit-box-pack", "-webkit-box-orient", "grid-row-start", "grid-row-end", "grid-column-start", "grid-column-end", "column-gap", "column-width", "column-count", "HasAutoColumnCount", "HasAutoColumnWidth", "column-fill", "column-span",
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc index 64a38b40..f2296ab 100644 --- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc +++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder.cc
@@ -94,7 +94,7 @@ media::GpuVideoAcceleratorFactories* const gpu_factories = Platform::Current()->GetGpuFactories(); - if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) { + if (!gpu_factories || !gpu_factories->IsGpuVideoEncodeAcceleratorEnabled()) { DVLOG(2) << "Couldn't initialize GpuVideoAcceleratorFactories"; std::move(callback).Run(); return; @@ -112,7 +112,7 @@ media::GpuVideoAcceleratorFactories* const gpu_factories = Platform::Current()->GetGpuFactories(); - if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) { + if (!gpu_factories || !gpu_factories->IsGpuVideoEncodeAcceleratorEnabled()) { DVLOG(2) << "Couldn't initialize GpuVideoAcceleratorFactories"; return media::VideoEncodeAccelerator::SupportedProfiles(); }
diff --git a/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc b/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc index 668da5b..02a9dcf 100644 --- a/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc +++ b/third_party/blink/renderer/modules/mediastream/processed_local_audio_source.cc
@@ -14,7 +14,6 @@ #include "base/strings/stringprintf.h" #include "build/build_config.h" #include "build/chromecast_buildflags.h" -#include "build/chromeos_buildflags.h" #include "media/audio/audio_source_parameters.h" #include "media/base/channel_layout.h" #include "media/base/sample_rates.h" @@ -108,7 +107,7 @@ // AEC is active. This is currently the default on at least MacOS but is not // allowed for ChromeOS setups. constexpr bool IsIndependentSystemNsAllowed() { -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if defined(OS_CHROMEOS) return false; #else return true;
diff --git a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc index d005bef..9048b0b 100644 --- a/third_party/blink/renderer/modules/webcodecs/video_encoder.cc +++ b/third_party/blink/renderer/modules/webcodecs/video_encoder.cc
@@ -107,7 +107,7 @@ media::VideoCodecProfile profile, const media::VideoEncoder::Options& options, media::GpuVideoAcceleratorFactories* gpu_factories) { - if (!gpu_factories || !gpu_factories->IsGpuVideoAcceleratorEnabled()) + if (!gpu_factories || !gpu_factories->IsGpuVideoEncodeAcceleratorEnabled()) return false; auto supported_profiles =
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc index 66b008dd..c70eabd 100644 --- a/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc +++ b/third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.cc
@@ -966,7 +966,7 @@ const PropertyTreeState& layer_state, const PaintChunkSubset& chunks) { const gfx::Vector2dF layer_offset = layer.offset_to_transform_parent(); - cc::RegionCaptureBounds capture_bounds; + viz::RegionCaptureBounds capture_bounds; for (const PaintChunk& chunk : chunks) { if (!chunk.region_capture_data) continue;
diff --git a/third_party/blink/renderer/platform/media/BUILD.gn b/third_party/blink/renderer/platform/media/BUILD.gn index 7bd727d..24936f57 100644 --- a/third_party/blink/renderer/platform/media/BUILD.gn +++ b/third_party/blink/renderer/platform/media/BUILD.gn
@@ -31,6 +31,7 @@ "new_session_cdm_result_promise.cc", "new_session_cdm_result_promise.h", "power_status_helper.cc", + "power_status_helper.h", "remote_playback_client_wrapper_impl.cc", "resource_multi_buffer_data_provider.cc", "resource_multi_buffer_data_provider.h", @@ -58,26 +59,28 @@ configs += [ "//third_party/blink/renderer/platform:blink_platform_implementation" ] - deps = [ + public_deps = [ "//base", - "//build:chromeos_buildflags", - "//cc", - "//components/viz/common", "//media", - "//media:media_buildflags", - "//media:shared_memory_support", "//media/mojo/mojom", "//mojo/public/cpp/bindings", - "//net", - "//services/device/public/mojom", - "//services/network/public/cpp", + "//services/device/public/mojom:mojom_blink", "//third_party/blink/public:blink", - "//third_party/blink/public/common", - "//third_party/blink/public/mojom:mojom_platform", "//third_party/blink/renderer/platform:platform_export", "//ui/gfx/geometry", "//url", ] + deps = [ + "//build:chromeos_buildflags", + "//cc", + "//components/viz/common", + "//media:media_buildflags", + "//media:shared_memory_support", + "//net", + "//services/network/public/cpp", + "//third_party/blink/public/common", + "//third_party/blink/public/mojom:mojom_platform", + ] if (media_use_ffmpeg || !is_android) { sources += [ @@ -99,6 +102,8 @@ visibility = [ "//third_party/blink/renderer/platform:*" ] testonly = true + data = [ "//media/test/data/" ] + # TODO(https://crbug.com/1198341): enable this config once the code is ported # to Blink code conventions. #configs += [ "//third_party/blink/renderer/platform:blink_platform_config" ] @@ -126,7 +131,6 @@ "//media/mojo/mojom", "//mojo/public/cpp/bindings", "//net", - "//services/device/public/mojom", "//testing/gmock", "//testing/gtest", "//third_party/blink/public:blink", @@ -165,13 +169,12 @@ "testing/test_response_generator.cc", "testing/test_response_generator.h", ] - deps = [ + public_deps = [ "//base", - "//net", "//testing/gmock", "//third_party/blink/public:blink_headers", "//third_party/blink/public/platform/media", "//url", ] - data = [ "//media/test/data/" ] + deps = [ "//net" ] }
diff --git a/third_party/blink/renderer/platform/media/key_system_config_selector.cc b/third_party/blink/renderer/platform/media/key_system_config_selector.cc index 3a505cc..53da867 100644 --- a/third_party/blink/renderer/platform/media/key_system_config_selector.cc +++ b/third_party/blink/renderer/platform/media/key_system_config_selector.cc
@@ -999,7 +999,7 @@ // agent, reject promise with a NotSupportedError. String comparison // is case-sensitive. if (!key_system.ContainsOnlyASCII()) { - std::move(cb).Run(Status::kUnsupportedKeySystem, nullptr, nullptr); + std::move(cb).Run(Status::kUnsupportedKeySystem, "", nullptr, nullptr); return; } @@ -1007,7 +1007,7 @@ std::string key_system_ascii = key_system.Ascii(); if (!key_systems_->IsSupportedKeySystem(key_system_ascii)) { - std::move(cb).Run(Status::kUnsupportedKeySystem, nullptr, nullptr); + std::move(cb).Run(Status::kUnsupportedKeySystem, "", nullptr, nullptr); return; } @@ -1029,7 +1029,7 @@ // Therefore, always support Clear Key key system and only check settings for // other key systems. if (!is_encrypted_media_enabled && !media::IsClearKey(key_system_ascii)) { - std::move(cb).Run(Status::kUnsupportedKeySystem, nullptr, nullptr); + std::move(cb).Run(Status::kUnsupportedKeySystem, "", nullptr, nullptr); return; } @@ -1090,14 +1090,20 @@ EmeFeatureRequirement::kRequired); cdm_config.use_hw_secure_codecs = config_state.AreHwSecureCodecsRequired(); + + std::string key_system = request->key_system; + if (key_systems_->ShouldUseBaseKeySystemName(key_system)) + key_system = key_systems_->GetBaseKeySystemName(key_system); + std::move(request->cb) - .Run(Status::kSupported, &accumulated_configuration, &cdm_config); + .Run(Status::kSupported, key_system, &accumulated_configuration, + &cdm_config); return; } } // 6.4. Reject promise with a NotSupportedError. - std::move(request->cb).Run(Status::kUnsupportedConfigs, nullptr, nullptr); + std::move(request->cb).Run(Status::kUnsupportedConfigs, "", nullptr, nullptr); } void KeySystemConfigSelector::OnPermissionResult(
diff --git a/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc b/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc index 0b8394f..addfde8b 100644 --- a/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc +++ b/third_party/blink/renderer/platform/media/key_system_config_selector_unittest.cc
@@ -37,6 +37,7 @@ // strings are for testing purpose only. const char kClearKeyKeySystem[] = "org.w3.clearkey"; const char kSupportedKeySystem[] = "keysystem.test.supported"; +const char kSupportedSubKeySystem[] = "keysystem.test.supported.sub"; const char kUnsupportedKeySystem[] = "keysystem.test.unsupported"; // Robustness strings for kSupportedKeySystem. @@ -199,10 +200,23 @@ void UpdateIfNeeded() override { ++update_count; } + std::string GetBaseKeySystemName( + const std::string& key_system) const override { + DCHECK(IsSupportedKeySystem(key_system)); + return key_system == kSupportedSubKeySystem ? kSupportedKeySystem + : key_system; + } + bool IsSupportedKeySystem(const std::string& key_system) const override { // Based on EME spec, Clear Key key system is always supported. - return key_system == kSupportedKeySystem || - key_system == kClearKeyKeySystem; + return key_system == kClearKeyKeySystem || + key_system == kSupportedKeySystem || + key_system == kSupportedSubKeySystem; + } + + bool ShouldUseBaseKeySystemName( + const std::string& key_system) const override { + return key_system == kSupportedSubKeySystem; } bool CanUseAesDecryptor(const std::string& key_system) const override { @@ -460,10 +474,12 @@ } void OnConfigSelected(KeySystemConfigSelector::Status status, + const std::string& key_system, WebMediaKeySystemConfiguration* config, media::CdmConfig* cdm_config) { if (status == KeySystemConfigSelector::Status::kSupported) { succeeded_count_++; + returned_key_system_ = key_system; config_ = *config; cdm_config_ = *cdm_config; } else { @@ -479,7 +495,8 @@ WebString key_system_ = WebString::FromUTF8(kSupportedKeySystem); std::vector<WebMediaKeySystemConfiguration> configs_; - // Holds the selected configuration and CdmConfig. + // Holds the selected key system, configuration and CdmConfig. + std::string returned_key_system_; WebMediaKeySystemConfiguration config_; media::CdmConfig cdm_config_; @@ -590,6 +607,14 @@ key_system_ = kClearKeyKeySystem; configs_.push_back(UsableConfiguration()); SelectConfigReturnsConfig(); + DCHECK_EQ(returned_key_system_, kClearKeyKeySystem); +} + +TEST_F(KeySystemConfigSelectorTest, KeySystem_SubKeySystem) { + key_system_ = kSupportedSubKeySystem; + configs_.push_back(UsableConfiguration()); + SelectConfigReturnsConfig(); + DCHECK_EQ(returned_key_system_, kSupportedKeySystem); } // --- Disable EncryptedMedia ---
diff --git a/third_party/blink/renderer/platform/media/power_status_helper.cc b/third_party/blink/renderer/platform/media/power_status_helper.cc index fa16c8e0..b8b59f4 100644 --- a/third_party/blink/renderer/platform/media/power_status_helper.cc +++ b/third_party/blink/renderer/platform/media/power_status_helper.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/public/platform/media/power_status_helper.h" +#include "third_party/blink/renderer/platform/media/power_status_helper.h" #include <utility> @@ -10,13 +10,11 @@ #include "base/check_op.h" #include "base/metrics/histogram_macros.h" #include "media/base/pipeline_metadata.h" -#include "services/device/public/mojom/battery_status.mojom.h" +#include "services/device/public/mojom/battery_status.mojom-blink.h" namespace blink { namespace { -using ::device::mojom::BatteryStatusPtr; - static constexpr const char* kBatteryDeltaHistogram = "Media.PlaybackPower.BatteryDelta"; static constexpr const char* kElapsedTimeHistogram = @@ -207,7 +205,7 @@ } void PowerStatusHelper::OnBatteryStatus( - device::mojom::BatteryStatusPtr battery_status) { + device::mojom::blink::BatteryStatusPtr battery_status) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); QueryNextStatus();
diff --git a/third_party/blink/public/platform/media/power_status_helper.h b/third_party/blink/renderer/platform/media/power_status_helper.h similarity index 90% rename from third_party/blink/public/platform/media/power_status_helper.h rename to third_party/blink/renderer/platform/media/power_status_helper.h index 2e09926..4707b255 100644 --- a/third_party/blink/public/platform/media/power_status_helper.h +++ b/third_party/blink/renderer/platform/media/power_status_helper.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MEDIA_POWER_STATUS_HELPER_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MEDIA_POWER_STATUS_HELPER_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_POWER_STATUS_HELPER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_POWER_STATUS_HELPER_H_ #include "base/callback.h" #include "base/sequence_checker.h" @@ -11,7 +11,7 @@ #include "media/base/video_codecs.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/remote.h" -#include "services/device/public/mojom/battery_monitor.mojom.h" +#include "services/device/public/mojom/battery_monitor.mojom-blink.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/platform/web_common.h" #include "ui/gfx/geometry/size.h" @@ -26,7 +26,7 @@ class BLINK_PLATFORM_EXPORT PowerStatusHelper { public: using CreateBatteryMonitorCB = base::RepeatingCallback< - mojo::PendingRemote<device::mojom::BatteryMonitor>()>; + mojo::PendingRemote<device::mojom::blink::BatteryMonitor>()>; // Bits used to construct UMA buckets. // These values are persisted to logs. Entries should not be renumbered and @@ -106,7 +106,7 @@ void OnAnyStateChange(); // Handle updates about the current battery status. - void OnBatteryStatus(device::mojom::BatteryStatusPtr battery_status); + void OnBatteryStatus(device::mojom::blink::BatteryStatusPtr battery_status); // Start monitoring if we haven't already. Any outstanding callbacks will be // cancelled if monitoring was already in progress. @@ -141,11 +141,11 @@ // experiment, according to the MediaPowerExperimentManager? bool experiment_state_ = false; - mojo::Remote<device::mojom::BatteryMonitor> battery_monitor_; + mojo::Remote<device::mojom::blink::BatteryMonitor> battery_monitor_; SEQUENCE_CHECKER(sequence_checker_); }; } // namespace blink -#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MEDIA_POWER_STATUS_HELPER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_MEDIA_POWER_STATUS_HELPER_H_
diff --git a/third_party/blink/renderer/platform/media/power_status_helper_unittest.cc b/third_party/blink/renderer/platform/media/power_status_helper_unittest.cc index d6a77658..81bf0ab 100644 --- a/third_party/blink/renderer/platform/media/power_status_helper_unittest.cc +++ b/third_party/blink/renderer/platform/media/power_status_helper_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "third_party/blink/public/platform/media/power_status_helper.h" +#include "third_party/blink/renderer/platform/media/power_status_helper.h" #include <memory> #include <tuple> @@ -14,7 +14,7 @@ #include "base/test/mock_callback.h" #include "base/test/task_environment.h" #include "media/base/pipeline_metadata.h" -#include "services/device/public/mojom/battery_status.mojom.h" +#include "services/device/public/mojom/battery_status.mojom-blink.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -26,7 +26,7 @@ class PowerStatusHelperTest : public testing::Test { public: - class MockBatteryMonitor : public device::mojom::BatteryMonitor { + class MockBatteryMonitor : public device::mojom::blink::BatteryMonitor { public: MOCK_METHOD0(DidGetBatteryMonitor, void()); MOCK_METHOD0(DidQueryNextStatus, void()); @@ -38,7 +38,7 @@ ProvidePowerUpdate(0, 0); } - // device::mojom::BatteryMonitor + // device::mojom::blink::BatteryMonitor void QueryNextStatus(QueryNextStatusCallback callback) override { DidQueryNextStatus(); callback_ = std::move(callback); @@ -46,7 +46,8 @@ // Would be nice to use a MockCallback for this, but a move-only return type // doesn't seem to work. - mojo::PendingRemote<device::mojom::BatteryMonitor> GetBatteryMonitor() { + mojo::PendingRemote<device::mojom::blink::BatteryMonitor> + GetBatteryMonitor() { DidGetBatteryMonitor(); switch (remote_type_) { case RemoteType::kConnected: @@ -60,7 +61,7 @@ return pending; } case RemoteType::kEmpty: - return mojo::PendingRemote<device::mojom::BatteryMonitor>(); + return mojo::PendingRemote<device::mojom::blink::BatteryMonitor>(); } } @@ -74,15 +75,16 @@ // Provide a battery update via |callback_|. void ProvidePowerUpdate(bool is_charging, float current_level) { EXPECT_TRUE(callback_); - device::mojom::BatteryStatusPtr status = - device::mojom::BatteryStatus::New(is_charging, 0, /* charging time */ - 0, /* discharging time */ - current_level); + device::mojom::blink::BatteryStatusPtr status = + device::mojom::blink::BatteryStatus::New(is_charging, + /*charging_time=*/0, + /*discharging_time=*/0, + current_level); std::move(callback_).Run(std::move(status)); base::RunLoop().RunUntilIdle(); } - mojo::Receiver<device::mojom::BatteryMonitor> receiver_{this}; + mojo::Receiver<device::mojom::blink::BatteryMonitor> receiver_{this}; // If false, then GetBatteryMonitor will not return a monitor. enum class RemoteType {
diff --git a/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc b/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc index a2602ab..2dc7b39 100644 --- a/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc +++ b/third_party/blink/renderer/platform/media/web_encrypted_media_client_impl.cc
@@ -132,6 +132,7 @@ void WebEncryptedMediaClientImpl::OnConfigSelected( WebEncryptedMediaRequest request, KeySystemConfigSelector::Status status, + const std::string& key_system, WebMediaKeySystemConfiguration* accumulated_configuration, media::CdmConfig* cdm_config) { // Update encrypted_media_supported_types_browsertest.cc if updating these @@ -151,6 +152,8 @@ break; // Handled below. } + // Use the requested key system to match what's reported in + // RequestMediaKeySystemAccess(). DCHECK_EQ(status, KeySystemConfigSelector::Status::kSupported); GetReporter(request.KeySystem())->ReportSupported(); @@ -165,9 +168,10 @@ return; } + // Use the returned key system which should be used for CDM creation. request.RequestSucceeded(WebContentDecryptionModuleAccessImpl::Create( - request.KeySystem(), origin, *accumulated_configuration, *cdm_config, - weak_factory_.GetWeakPtr())); + WebString::FromUTF8(key_system), origin, *accumulated_configuration, + *cdm_config, weak_factory_.GetWeakPtr())); } WebEncryptedMediaClientImpl::Reporter* WebEncryptedMediaClientImpl::GetReporter(
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc index 3cfdbf9..cfe965c 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
@@ -14,9 +14,11 @@ #include "base/bind.h" #include "base/callback.h" #include "base/callback_helpers.h" +#include "base/check.h" #include "base/command_line.h" #include "base/debug/alias.h" #include "base/debug/crash_logging.h" +#include "base/feature_list.h" #include "base/location.h" #include "base/memory/weak_ptr.h" #include "base/metrics/histogram_functions.h" @@ -54,11 +56,13 @@ #include "media/learning/mojo/public/cpp/mojo_learning_task_controller.h" #include "media/media_buildflags.h" #include "media/remoting/remoting_constants.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "net/base/data_url.h" +#include "services/device/public/mojom/battery_monitor.mojom-blink.h" #include "third_party/blink/public/common/media/display_type.h" #include "third_party/blink/public/common/media/watch_time_reporter.h" -#include "third_party/blink/public/platform/media/power_status_helper.h" +#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" #include "third_party/blink/public/platform/media/url_index.h" #include "third_party/blink/public/platform/web_encrypted_media_types.h" #include "third_party/blink/public/platform/web_fullscreen_video_status.h" @@ -79,6 +83,7 @@ #include "third_party/blink/public/web/web_frame.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_view.h" +#include "third_party/blink/renderer/platform/media/power_status_helper.h" #include "third_party/blink/renderer/platform/media/text_track_impl.h" #include "third_party/blink/renderer/platform/media/video_decode_stats_reporter.h" #include "third_party/blink/renderer/platform/media/web_content_decryption_module_impl.h" @@ -340,6 +345,7 @@ std::unique_ptr<media::RendererFactorySelector> renderer_factory_selector, UrlIndex* url_index, std::unique_ptr<VideoFrameCompositor> compositor, + scoped_refptr<ThreadSafeBrowserInterfaceBrokerProxy> remote_interfaces, std::unique_ptr<WebMediaPlayerParams> params) : frame_(frame), main_task_runner_(frame->GetTaskRunner(TaskType::kMediaElementEvent)), @@ -378,14 +384,30 @@ base::BindRepeating(&WebMediaPlayerImpl::GetCurrentTimeInternal, base::Unretained(this))), will_play_helper_(nullptr), - demuxer_override_(params->TakeDemuxerOverride()), - power_status_helper_(params->TakePowerStatusHelper()) { + demuxer_override_(params->TakeDemuxerOverride()) { DVLOG(1) << __func__; DCHECK(adjust_allocated_memory_cb_); DCHECK(renderer_factory_selector_); DCHECK(client_); DCHECK(delegate_); + if (base::FeatureList::IsEnabled(media::kMediaPowerExperiment)) { + // The battery monitor is only available through the blink provider. + DCHECK(remote_interfaces); + auto battery_monitor_cb = base::BindRepeating( + [](scoped_refptr<ThreadSafeBrowserInterfaceBrokerProxy> + remote_interfaces) { + mojo::PendingRemote<device::mojom::blink::BatteryMonitor> + battery_monitor; + remote_interfaces->GetInterface( + battery_monitor.InitWithNewPipeAndPassReceiver()); + return battery_monitor; + }, + remote_interfaces); + power_status_helper_ = + std::make_unique<PowerStatusHelper>(std::move(battery_monitor_cb)); + } + weak_this_ = weak_factory_.GetWeakPtr(); // Using base::Unretained(this) is safe because the `pipeline` is owned by
diff --git a/third_party/blink/renderer/platform/media/web_media_player_params.cc b/third_party/blink/renderer/platform/media/web_media_player_params.cc index c628d14..e24ddf6 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_params.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_params.cc
@@ -34,8 +34,7 @@ bool is_background_suspend_enabled, bool is_background_video_playback_enabled, bool is_background_video_track_optimization_supported, - std::unique_ptr<media::Demuxer> demuxer_override, - std::unique_ptr<PowerStatusHelper> power_status_helper) + std::unique_ptr<media::Demuxer> demuxer_override) : defer_load_cb_(defer_load_cb), audio_renderer_sink_(audio_renderer_sink), media_log_(std::move(media_log)), @@ -58,8 +57,7 @@ is_background_video_playback_enabled), is_background_video_track_optimization_supported_( is_background_video_track_optimization_supported), - demuxer_override_(std::move(demuxer_override)), - power_status_helper_(std::move(power_status_helper)) {} + demuxer_override_(std::move(demuxer_override)) {} WebMediaPlayerParams::~WebMediaPlayerParams() = default;
diff --git a/third_party/blink/renderer/platform/peerconnection/video_codec_factory.cc b/third_party/blink/renderer/platform/peerconnection/video_codec_factory.cc index 05ce23b..98f67092 100644 --- a/third_party/blink/renderer/platform/peerconnection/video_codec_factory.cc +++ b/third_party/blink/renderer/platform/peerconnection/video_codec_factory.cc
@@ -84,15 +84,6 @@ std::unique_ptr<webrtc::VideoEncoderFactory> hardware_encoder_factory) : hardware_encoder_factory_(std::move(hardware_encoder_factory)) {} - webrtc::VideoEncoderFactory::CodecInfo QueryVideoEncoder( - const webrtc::SdpVideoFormat& format) const override { - const webrtc::VideoEncoderFactory* factory = - IsFormatSupported(hardware_encoder_factory_.get(), format) - ? hardware_encoder_factory_.get() - : &software_encoder_factory_; - return factory->QueryVideoEncoder(format); - } - std::unique_ptr<webrtc::VideoEncoder> CreateVideoEncoder( const webrtc::SdpVideoFormat& format) override { const bool supported_in_software = @@ -212,7 +203,7 @@ media::GpuVideoAcceleratorFactories* gpu_factories) { std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory; - if (gpu_factories && gpu_factories->IsGpuVideoAcceleratorEnabled() && + if (gpu_factories && gpu_factories->IsGpuVideoEncodeAcceleratorEnabled() && Platform::Current()->IsWebRtcHWEncodingEnabled()) { encoder_factory = std::make_unique<RTCVideoEncoderFactory>(gpu_factories); } @@ -231,9 +222,10 @@ media::DecoderFactory* media_decoder_factory, scoped_refptr<base::SequencedTaskRunner> media_task_runner, const gfx::ColorSpace& render_color_space) { - const bool use_hw_decoding = gpu_factories != nullptr && - gpu_factories->IsGpuVideoAcceleratorEnabled() && - Platform::Current()->IsWebRtcHWDecodingEnabled(); + const bool use_hw_decoding = + gpu_factories != nullptr && + gpu_factories->IsGpuVideoDecodeAcceleratorEnabled() && + Platform::Current()->IsWebRtcHWDecodingEnabled(); // If RTCVideoDecoderStreamAdapter is used then RTCVideoDecoderFactory can // support both SW and HW decoding, and should therefore always be
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials b/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials index 622f6a86..2630503 100644 --- a/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials +++ b/third_party/blink/web_tests/FlagExpectations/disable-site-isolation-trials
@@ -41,3 +41,6 @@ # Fix to unblock wpt-importer crbug.com/1209223 external/wpt/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-security-check-multi-globals.sub.html [ Failure ] crbug.com/1209223 external/wpt/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-security-check-same-origin-domain.sub.html [ Failure ] + +# ====== New tests from wpt-importer added here ====== +crbug.com/626703 wpt_internal/webid/get-argument-validation.https.html [ Timeout ] \ No newline at end of file
diff --git a/third_party/blink/web_tests/FlagExpectations/skia-vulkan-swiftshader b/third_party/blink/web_tests/FlagExpectations/skia-vulkan-swiftshader index e098bc4..8b879b5 100644 --- a/third_party/blink/web_tests/FlagExpectations/skia-vulkan-swiftshader +++ b/third_party/blink/web_tests/FlagExpectations/skia-vulkan-swiftshader
@@ -66,3 +66,4 @@ crbug.com/1266821 transforms/transformed-caret.html [ Failure ] crbug.com/1266821 transforms/transformed-document-element.html [ Failure ] crbug.com/1266821 virtual/android/fullscreen/video-controls-timeline.html [ Failure ] +crbug.com/1268259 images/color-profile-image-canvas-pattern.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 5adbee5..33fa8bdd 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -3427,7 +3427,6 @@ crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCDtlsTransport-state.html [ Timeout ] crbug.com/626703 [ Mac11 ] external/wpt/webrtc/RTCDtlsTransport-state.html [ Timeout ] crbug.com/626703 [ Mac10.14 ] external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https.html [ Timeout ] -crbug.com/626703 [ Mac11 ] external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https.html [ Timeout ] crbug.com/626703 [ Mac11-arm64 ] external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https.html [ Failure Pass Timeout ] crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html [ Timeout ] crbug.com/626703 [ Mac11 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-simulcast.https.html [ Timeout ] @@ -6080,7 +6079,6 @@ crbug.com/961059 fast/workers/worker-shared-asm-buffer.html [ Skip ] # Temporarily disabled to unblock https://crrev.com/c/2979697 -crbug.com/1222114 http/tests/devtools/console/console-call-getter-on-proto.js [ Failure Pass ] crbug.com/1222114 http/tests/devtools/console/console-dir.js [ Failure Pass ] crbug.com/1222114 http/tests/devtools/console/console-dir-es6.js [ Failure Pass ] crbug.com/1222114 http/tests/devtools/console/console-format.js [ Failure Pass ] @@ -7264,7 +7262,6 @@ crbug.com/1267736 [ Win ] http/tests/devtools/bindings/jssourcemap-bindings-overlapping-sources.js [ Failure Pass ] # Sheriff 2021-11-09 -crbug.com/1268259 [ Linux ] images/color-profile-image-canvas-pattern.html [ Failure ] crbug.com/1268265 [ Mac10.14 ] virtual/prerender/external/wpt/speculation-rules/prerender/local-storage.html [ Failure ] crbug.com/1268518 [ Linux ] external/wpt/web-animations/interfaces/Animation/onfinish.html [ Failure Pass ] crbug.com/1268518 [ Mac10.12 ] external/wpt/web-animations/interfaces/Animation/onfinish.html [ Failure Pass ] @@ -7273,10 +7270,15 @@ # Sheriff 2021-11-10 crbug.com/1268963 [ Linux ] virtual/plz-dedicated-worker/external/wpt/resource-timing/object-not-found-after-TAO-cross-origin-redirect.html [ Failure Pass ] -crbug.com/1270500 http/tests/devtools/sources/debugger/async-callstack-network-initiator.js [ Failure Pass ] -crbug.com/1268947 virtual/shared_array_buffer_on_desktop/http/tests/devtools/sources/debugger/async-callstack-network-initiator.js [ Failure Pass ] # Sheriff 2021-11-12 crbug.com/1268594 [ Linux ] css3/filters/composited-layer-bounds-after-sw-blur-animation.html [ Failure Pass ] crbug.com/1268594 [ Mac ] css3/filters/composited-layer-bounds-after-sw-blur-animation.html [ Failure Pass ] crbug.com/1268594 [ Win ] css3/filters/composited-layer-bounds-after-sw-blur-animation.html [ Failure Pass ] + +# Temporarily disable to update DevTools Application Panel +crbug.com/1271044 http/tests/devtools/application-panel/resources-panel-iframe-idb.js [ Pass Failure ] +crbug.com/1271044 http/tests/devtools/application-panel/resources-panel-on-navigation.js [ Pass Failure ] +crbug.com/1271044 http/tests/devtools/application-panel/resources-panel-resource-preview.js [ Pass Failure ] +crbug.com/1271044 http/tests/devtools/application-panel/resources-panel-selection-on-reload.js [ Pass Failure ] +crbug.com/1271044 http/tests/devtools/application-panel/resources-panel-websql.js [ Pass Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json index 86beaf2..a666dd3c 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -2366,6 +2366,13 @@ null, {} ] + ], + "nested-details-crash.html": [ + "f3e821a950588d6b374c4338c5ab89e0f8d9f0d0", + [ + null, + {} + ] ] }, "the-dialog-element": { @@ -78744,7 +78751,7 @@ ] ], "grid-item-fragmentation-020.html": [ - "1c9f6f67f2617e265045800af5bb5745946ffead", + "f0636c4982d409758d8f18fb2d9849d505a3d844", [ null, [ @@ -78846,6 +78853,58 @@ ], {} ] + ], + "grid-item-fragmentation-028.html": [ + "1718fa2081aca900de1a4ddc3f50751714d86928", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-item-fragmentation-029.html": [ + "380fba879cd622e940d50389de758d95599496f5", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-item-fragmentation-030.html": [ + "a3e05d0956be2380774638a370d1bcdb2076ea37", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "grid-item-fragmentation-031.html": [ + "1a339ab22c9711f8e68ee0b37c2753ccdea14f71", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] ] }, "ink-overflow-002.html": [ @@ -124765,6 +124824,19 @@ {} ] ], + "clip-path-fixed-scroll.html": [ + "2b6e09b0e8391bd1f73b1be0b33dcb36cab3d895", + [ + null, + [ + [ + "/css/css-masking/clip-path/clip-path-fixed-scroll-ref.html", + "==" + ] + ], + {} + ] + ], "clip-path-inline-001.html": [ "76018614baab3fc3123f9c3d41053effcb64c224", [ @@ -168166,6 +168238,19 @@ ] ] }, + "paint-order-with-transform-change.html": [ + "c3f280d880f87680bdf6ef19834266669ea7ce40", + [ + null, + [ + [ + "/css/css-transforms/paint-order-with-transform-change-ref.html", + "==" + ] + ], + {} + ] + ], "patternTransform": { "svg-patternTransform-001.html": [ "70a208c00168009947249eea1748d756b8c00ba4", @@ -204321,6 +204406,19 @@ {} ] ], + "table-cell-nowrap-with-fixed-width.html": [ + "65962ac2734c5573f172b7303d95a20d33534905", + [ + null, + [ + [ + "/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width-ref.html", + "==" + ] + ], + {} + ] + ], "table-cell-width-s.html": [ "0fe0e2c25ae6ec60133df3142bb9cf4d0d91ba33", [ @@ -248542,6 +248640,10 @@ "b860304f04fe22498eb5b43d9de00d7e261353bb", [] ], + "clip-path-fixed-scroll-ref.html": [ + "86aad95935b2da0de4fc8c18149200f8fdf2aa15", + [] + ], "clip-path-inset-round-percent-ref.html": [ "597481d7dbe99afb764ad5f1e5603c5dd0240bee", [] @@ -257967,6 +258069,10 @@ ] } }, + "paint-order-with-transform-change-ref.html": [ + "fcead1ea7769eb137bd3780b94c383d53054ea72", + [] + ], "parsing": { "transform-box-computed-expected.txt": [ "913e45cc787a6998589bde3856fc190e89e7de73", @@ -273631,7 +273737,7 @@ [] ], "META.yml": [ - "57cb2cd5f08824e128626381b74170e0583fce61", + "f9acc8b9cf34d3db9af188198bb753f7f107c667", [] ], "OWNERS": [ @@ -273665,6 +273771,10 @@ "idlharness.window-expected.txt": [ "906d5c6d455cdcb9e3e0b8cc72a6194d7182aad1", [] + ], + "not-fully-active.https-expected.txt": [ + "e7e61a12814e7644f2fecf486f254fcfce3bfd94", + [] ] }, "generic-sensor": { @@ -282977,6 +283087,10 @@ "c8d6a20726fd84900f192b34206954eeec57f61d", [] ], + "table-cell-nowrap-with-fixed-width-ref.html": [ + "5b2ea91fe5fa635c221adc8801605f3b14fb66c7", + [] + ], "table-cell-width-ref.html": [ "b5ba0443f3cfacef82352ee792bc4963c582099d", [] @@ -285739,10 +285853,6 @@ "085a9b59d2aeea11b84cd8cdf27c086ecd007e68", [] ], - "dialog-inert.tentative-expected.txt": [ - "9dd4bfe5af3042eb46c4496dd556e64e61229dd2", - [] - ], "dialogs-with-no-backdrop-ref.html": [ "4b31dc7062e697496f4edfaf98a70c0e794c6245", [] @@ -289905,12 +290015,6 @@ [] ] }, - "inert": { - "inert-computed-style-expected.txt": [ - "416c46a8e77416c0518b9e3af15c5b27ccce770d", - [] - ] - }, "infrastructure": { "DIR_METADATA": [ "b19504342dfe64050a6372808f15f3e792a79218", @@ -296308,6 +296412,10 @@ [] ] }, + "table-cell-nowrap-minimum-width-calculation-expected.txt": [ + "057781ccfd41fa9d3e0c650cc13156b120d78a00", + [] + ], "text-decoration-doesnt-propagate-into-tables": { "quirks-ref.html": [ "a72475f40cec7a84702fdb03aad81198e0e7cdca", @@ -307886,7 +307994,7 @@ [] ], "rtp-payloadtypes-expected.txt": [ - "01137479f933ad7649b9aa7029d4643bab92494f", + "c8cd341e51f0274ff19000a16c3ac8c693c79e49", [] ], "vp8-fmtp-expected.txt": [ @@ -359764,7 +359872,7 @@ ] ], "table-quirks.html": [ - "83794d17ae11a31ef169b1765b0f4b22ed060849", + "af2a516c0e8a39d21496bd4698e14e86891ccae3", [ null, {} @@ -403924,6 +404032,13 @@ "timeout": "long" } ] + ], + "not-fully-active.https.html": [ + "500afef3d2deb29c087de0bb708904ace81798c5", + [ + null, + {} + ] ] }, "generic-sensor": { @@ -461969,7 +462084,7 @@ ] ], "payment-instruments.https.html": [ - "3ab3c09a8165cd8cf9f4776931c84a48e095452b", + "53751eb2f2e8782187260a429c27299c712de538", [ null, {} @@ -512946,7 +513061,7 @@ ] ], "rtp-payloadtypes.html": [ - "aa464f8656fe9a090374e4346c43600cf0b497ae", + "af7656d131ea45779334ef43a52d6e0b343a6721", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-fixed-scroll-ref.html b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-fixed-scroll-ref.html new file mode 100644 index 0000000..86aad95 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-fixed-scroll-ref.html
@@ -0,0 +1,6 @@ +<!doctype html> +<div style="height: 100vh"></div> +<div style="width: 200px; height: 200px; background: green"></div> +<script> + window.scrollTo(0, 1000); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-fixed-scroll.html b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-fixed-scroll.html new file mode 100644 index 0000000..2b6e09b0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-masking/clip-path/clip-path-fixed-scroll.html
@@ -0,0 +1,20 @@ +<!doctype html> +<html class="reftest-wait"> +<title>CSS Test: clip-path above position: fixed scrolled</title> +<link rel="help" href="https://crbug.com/1267676"> +<link rel="help" href="https://drafts.fxtf.org/css-masking/#the-clip-path"> +<link rel="match" href="clip-path-fixed-scroll-ref.html"> +<script src="/common/rendering-utils.js"></script> +<script src="/common/reftest-wait.js"></script> +<div style="height: 100vh"></div> +<div style="width: 200px; height: 200px; clip-path: inset(0 0 0 0)"> + <div style="position: fixed; top: 0; left: 0; width: 2000px; height: 2000px; background: green"></div> +</div> +<script> +waitForAtLeastOneFrame().then(() => { + scrollTo(0, 1000); + takeScreenshot(); +}); +</script> +</html> +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-tables/tentative/table-quirks.html b/third_party/blink/web_tests/external/wpt/css/css-tables/tentative/table-quirks.html index 83794d1..af2a516 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-tables/tentative/table-quirks.html +++ b/third_party/blink/web_tests/external/wpt/css/css-tables/tentative/table-quirks.html
@@ -43,7 +43,7 @@ <p class="error">Chrome Legacy, Edge, Safari fail, only FF gets it correct.<b>Proposal: deprecate the quirk</b></p> <table> <tr> - <td nowrap style="width:50px;font: 20px/1 Ahem" data-expected-width=160>nowrap nowrap nowrap nowrap</td> + <td nowrap style="width:50px;font: 20px/1 Ahem" data-expected-width=580>nowrap nowrap nowrap nowrap</td> </tr> </table>
diff --git a/third_party/blink/web_tests/external/wpt/gamepad/META.yml b/third_party/blink/web_tests/external/wpt/gamepad/META.yml index 57cb2cd..f9acc8b9 100644 --- a/third_party/blink/web_tests/external/wpt/gamepad/META.yml +++ b/third_party/blink/web_tests/external/wpt/gamepad/META.yml
@@ -1,4 +1,5 @@ spec: https://w3c.github.io/gamepad/ suggested_reviewers: - marcoscaceres - - JamesHollyer + - nondebug + - reillyeon
diff --git a/third_party/blink/web_tests/external/wpt/gamepad/not-fully-active.https-expected.txt b/third_party/blink/web_tests/external/wpt/gamepad/not-fully-active.https-expected.txt new file mode 100644 index 0000000..e7e61a1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/gamepad/not-fully-active.https-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL calling getGamepads() in a non-fully-active document assert_true: getGamepads should return an array expected true got false +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/gamepad/not-fully-active.https.html b/third_party/blink/web_tests/external/wpt/gamepad/not-fully-active.https.html new file mode 100644 index 0000000..500afef --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/gamepad/not-fully-active.https.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<meta charset="utf-8" /> +<title>Gamepad tests for non-fully-active document</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<body> +<script> + promise_test(async () => { + const iframe = document.createElement('iframe'); + iframe.srcdoc = `<h1>test</h1>` + await new Promise(resolve => { + iframe.onload = resolve; + document.body.appendChild(iframe); + }); + const navigator = iframe.contentWindow.navigator; + iframe.remove(); + const gamepads = navigator.getGamepads(); + assert_true(Array.isArray(gamepads), 'getGamepads should return an array'); + assert_equals(gamepads.length, 0, "No gamepads should be available"); + }, "calling getGamepads() in a non-fully-active document"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width-ref.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width-ref.html new file mode 100644 index 0000000..5b2ea91 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width-ref.html
@@ -0,0 +1,2 @@ +<!DOCTYPE html> +<div style="width: 100px; height: 100px; background: green;"></div>
diff --git a/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width.html b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width.html new file mode 100644 index 0000000..65962ac2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<link rel="help" href="https://html.spec.whatwg.org/#tables-2"> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=821915"> +<link rel="match" href="table-cell-nowrap-with-fixed-width-ref.html"> +<title>A td element with the nowrap attribute should unconditionally apply white-space:nowrap</title> +<style> +table { border-spacing: 0; } +td { width: 10px; padding: 0; } +div { display: inline-block; background: green; width: 50px; height: 100px; } +</style> +<table> + <td nowrap> + <div></div><div></div> + </td> +</table>
diff --git a/third_party/blink/web_tests/external/wpt/quirks/table-cell-nowrap-minimum-width-calculation-expected.txt b/third_party/blink/web_tests/external/wpt/quirks/table-cell-nowrap-minimum-width-calculation-expected.txt new file mode 100644 index 0000000..057781c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/quirks/table-cell-nowrap-minimum-width-calculation-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL The table cell nowrap minimum width calculation quirk, basic assert_equals: quirks mode expected "10px" but got "2px" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/003-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/003-expected.png new file mode 100644 index 0000000..a220dd7 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/003-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/021-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/021-expected.png new file mode 100644 index 0000000..c84a81fc --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/021-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/rowspan-paint-order-vertical-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/rowspan-paint-order-vertical-expected.png new file mode 100644 index 0000000..96564e8 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/fast/table/rowspan-paint-order-vertical-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/tables/mozilla/bugs/bug57828-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/tables/mozilla/bugs/bug57828-expected.png new file mode 100644 index 0000000..e51e612 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/tables/mozilla/bugs/bug57828-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/tables/mozilla/bugs/bug78162-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/tables/mozilla/bugs/bug78162-expected.png new file mode 100644 index 0000000..abf922a --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/tables/mozilla/bugs/bug78162-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/tables/mozilla/bugs/bug92143-expected.png b/third_party/blink/web_tests/flag-specific/composite-after-paint/tables/mozilla/bugs/bug92143-expected.png new file mode 100644 index 0000000..30b7ee0a --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/tables/mozilla/bugs/bug92143-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/quirks/table-cell-nowrap-minimum-width-calculation-expected.txt b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/quirks/table-cell-nowrap-minimum-width-calculation-expected.txt index 8e83b57a..057781c 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/quirks/table-cell-nowrap-minimum-width-calculation-expected.txt +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/external/wpt/quirks/table-cell-nowrap-minimum-width-calculation-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL The table cell nowrap minimum width calculation quirk, basic assert_equals: quirks mode expected "10px" but got "8px" +FAIL The table cell nowrap minimum width calculation quirk, basic assert_equals: quirks mode expected "10px" but got "2px" Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/003-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/003-expected.png index ab68d481..f925da37 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/003-expected.png +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/003-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/021-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/021-expected.png new file mode 100644 index 0000000..c84a81fc --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/021-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/rowspan-paint-order-vertical-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/rowspan-paint-order-vertical-expected.png new file mode 100644 index 0000000..fd949c9 --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/fast/table/rowspan-paint-order-vertical-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/tables/mozilla/bugs/bug57828-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/tables/mozilla/bugs/bug57828-expected.png index 6cd5bd5..c74285b 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/tables/mozilla/bugs/bug57828-expected.png +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/tables/mozilla/bugs/bug57828-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/tables/mozilla/bugs/bug78162-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/tables/mozilla/bugs/bug78162-expected.png index b0fca92..abf922a 100644 --- a/third_party/blink/web_tests/flag-specific/disable-layout-ng/tables/mozilla/bugs/bug78162-expected.png +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/tables/mozilla/bugs/bug78162-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/tables/mozilla/bugs/bug92143-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/tables/mozilla/bugs/bug92143-expected.png new file mode 100644 index 0000000..30b7ee0a --- /dev/null +++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/tables/mozilla/bugs/bug92143-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/fast/table/021-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/fast/table/021-expected.png index 66447d9..d22aa456 100644 --- a/third_party/blink/web_tests/flag-specific/highdpi/fast/table/021-expected.png +++ b/third_party/blink/web_tests/flag-specific/highdpi/fast/table/021-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/devtools/console/console-call-getter-on-proto-expected.txt b/third_party/blink/web_tests/http/tests/devtools/console/console-call-getter-on-proto-expected.txt index f113e7c..0247c4ff 100644 --- a/third_party/blink/web_tests/http/tests/devtools/console/console-call-getter-on-proto-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/console/console-call-getter-on-proto-expected.txt
@@ -2,8 +2,10 @@ console-call-getter-on-proto.js:27 B {value: 239} value: 239 + foo: 239 [[Prototype]]: A constructor: ƒ () + foo: 239 [[Prototype]]: Object constructor: ƒ () foo: 239
diff --git a/third_party/blink/web_tests/http/tests/devtools/file-system-project.js b/third_party/blink/web_tests/http/tests/devtools/file-system-project.js index 394efd2..8d5334c 100644 --- a/third_party/blink/web_tests/http/tests/devtools/file-system-project.js +++ b/third_party/blink/web_tests/http/tests/devtools/file-system-project.js
@@ -75,8 +75,8 @@ TestRunner.runTestSuite([ function testFileSystems(next) { TestRunner.addResult('Adding first file system.'); - var fs1 = new BindingsTestRunner.TestFileSystem('file:///var/www'); - var fs2 = new BindingsTestRunner.TestFileSystem('file:///foo/bar'); + var fs1 = new BindingsTestRunner.TestFileSystem('/var/www'); + var fs2 = new BindingsTestRunner.TestFileSystem('/foo/bar'); TestRunner.addResult('Adding second file system.'); TestRunner.addResult('Adding files to file systems.'); @@ -125,7 +125,7 @@ }, function testDefaultExcludes(next) { - createFileSystem('file:///var/www', dumpExcludes); + createFileSystem('/var/www', dumpExcludes); function dumpExcludes(fs) { TestRunner.addResult(''); @@ -138,7 +138,7 @@ function testExcludesSettings(next) { Common.settings.createLocalSetting('workspaceExcludedFolders', {}).set({'file:///var/www2': ['/html/']}); - createFileSystem('file:///var/www2', dumpExcludes); + createFileSystem('/var/www2', dumpExcludes); function dumpExcludes(fs) { TestRunner.addResult(''); @@ -150,7 +150,7 @@ }, function testExcludesViaDelegate(next) { - createFileSystem('file:///var/www3', dumpExcludes); + createFileSystem('/var/www3', dumpExcludes); function dumpExcludes(fs) { fileSystemUISourceCodes()[0].project().excludeFolder('file:///var/www3/html2/'); @@ -163,7 +163,7 @@ }, function testFileAddedExternally(next) { - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www4'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www4'); var dir = fs.root.mkdir('html'); dir.addFile('foo.js', ''); fs.reportCreated(dumpFileSystem); @@ -185,7 +185,7 @@ }, function testGitFolders(next) { - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www3'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www3'); var project1 = fs.root.mkdir('project_1'); project1.mkdir('.git').addFile('foo.git'); var project2 = fs.root.mkdir('project_2'); @@ -208,7 +208,7 @@ }, function testUISourceCodeMetadata(next) { - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www3'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www3'); var file = fs.root.mkdir('test').addFile('hello.js', '123456'); fs.reportCreated(function() {}); SourcesTestRunner.waitForScriptSource('hello.js', onUISourceCode); @@ -239,7 +239,7 @@ }, function testFileRename(next) { - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www3'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www3'); var file = fs.root.mkdir('test').addFile('hello.js', '123456'); fs.reportCreated(function() {}); SourcesTestRunner.waitForScriptSource('hello.js', onUISourceCode);
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-absolute-paths.js b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-absolute-paths.js index 5fde2f60..f4c90cc 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-absolute-paths.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-absolute-paths.js
@@ -14,7 +14,7 @@ 'file:///usr/local/node/app.js': app_js, }); - var fs = new BindingsTestRunner.TestFileSystem('file:///usr/local/node'); + var fs = new BindingsTestRunner.TestFileSystem('/usr/local/node'); BindingsTestRunner.addFiles(fs, { 'app.js': app_js, });
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-committed-network-sourcecode.js b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-committed-network-sourcecode.js index a4edacd..d2776f5e 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-committed-network-sourcecode.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-committed-network-sourcecode.js
@@ -14,7 +14,7 @@ content = content.replace(/foo/g, 'bar'); networkUISourceCode.addRevision(content); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFooJSFile(fs); fs.reportCreated(function() {});
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-dirty-filesystem-sourcecode.js b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-dirty-filesystem-sourcecode.js index 5d31da94..d2ab22f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-dirty-filesystem-sourcecode.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-dirty-filesystem-sourcecode.js
@@ -8,7 +8,7 @@ BindingsTestRunner.overrideNetworkModificationTime( {'http://127.0.0.1:8000/devtools/persistence/resources/foo.js': null}); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFooJSFile(fs); fs.reportCreated(function() {}); var fsUISourceCode = await TestRunner.waitForUISourceCode('foo.js', Workspace.projectTypes.FileSystem);
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-dirty-network-sourcecode.js b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-dirty-network-sourcecode.js index 71a4726..a33c366 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-dirty-network-sourcecode.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-bind-dirty-network-sourcecode.js
@@ -13,7 +13,7 @@ content = content.replace(/foo/g, 'bar'); networkUISourceCode.setWorkingCopy(content); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFooJSFile(fs); fs.reportCreated(function() {});
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-dynamic-uisourcecodes.js b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-dynamic-uisourcecodes.js index f2bdb86d..d3a26393 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-dynamic-uisourcecodes.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-dynamic-uisourcecodes.js
@@ -9,7 +9,7 @@ var foo_js = {content: 'console.log(\'foo.js!\');', time: new Date('December 1, 1989')}; var automappingTest = new BindingsTestRunner.AutomappingTest(new Workspace.Workspace()); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); fs.reportCreated(onFileSystemCreated); function onFileSystemCreated() {
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-git-folders.js b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-git-folders.js index 4029109..d7a5426 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-git-folders.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-git-folders.js
@@ -20,7 +20,7 @@ 'http://example.com/logo.png': logo2 }); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFiles(fs, { 'code/proj1/.git/HEAD': {content: 'ref: refs/heads/master', time: new Date('May 12, 2007')}, 'code/proj1/reset.css': reset_css,
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-rename-files.js b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-rename-files.js index baceaa6..926589f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-rename-files.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-rename-files.js
@@ -17,7 +17,7 @@ 'http://example.com/path/foo.js': foo_js, }); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFiles(fs, { 'scripts/foo.js': foo_js, });
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sane.js b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sane.js index 734951f..9e710c1 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sane.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sane.js
@@ -44,7 +44,7 @@ 'http://example.com/sources/module.json': sources_module_json, }); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFiles(fs, { 'index.html': index_html, 'scripts/foo.js': foo_js,
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sourcemap-nameclash.js b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sourcemap-nameclash.js index 81b4e6a..3f25a17 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sourcemap-nameclash.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sourcemap-nameclash.js
@@ -17,7 +17,7 @@ Promise.all([getResourceContent('out.js'), getResourceContent('out.js? [sm]')]).then(onResourceContents); function onResourceContents(contents) { - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFiles(fs, { 'out.js': {content: contents[0], time: new Date('December 1, 1989')}, 'src/out.js': {content: contents[1], time: new Date('December 1, 1989')}
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sourcemap.js b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sourcemap.js index 779691c..b5e94e1 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sourcemap.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-sourcemap.js
@@ -16,7 +16,7 @@ Promise.all([getResourceContent('s.css'), getResourceContent('s.scss')]).then(onResourceContents); function onResourceContents(contents) { - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFiles(fs, { 'dist/s.css': {content: contents[0], time: new Date('December 1, 1989')}, 'src/s.scss': {content: contents[1], time: new Date('December 1, 1989')}
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-urlencoded-paths.js b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-urlencoded-paths.js index e760b80d..5f2079a5 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-urlencoded-paths.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/automapping-urlencoded-paths.js
@@ -15,7 +15,7 @@ 'file:///usr/local/node/script%25201.js': app_js, }); - var fs = new BindingsTestRunner.TestFileSystem('file:///usr/local/node'); + var fs = new BindingsTestRunner.TestFileSystem('/usr/local/node'); BindingsTestRunner.addFiles(fs, { 'script 1.js': app_js, 'script%201.js': app_js,
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/ensure-filesystem-create-files-doesnt-emit-change-first.js b/third_party/blink/web_tests/http/tests/devtools/persistence/ensure-filesystem-create-files-doesnt-emit-change-first.js index fcbb9b7f..7dc799e 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/ensure-filesystem-create-files-doesnt-emit-change-first.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/ensure-filesystem-create-files-doesnt-emit-change-first.js
@@ -6,7 +6,7 @@ TestRunner.addResult(`Verify that fs.createFile is creating UISourceCode atomically with content`); await TestRunner.loadTestModule('bindings_test_runner'); - var folderLocation = 'file:///var/test'; + var folderLocation = '/var/test'; await (new BindingsTestRunner.TestFileSystem(folderLocation)).reportCreatedPromise(); Workspace.workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded, async event => { @@ -17,6 +17,6 @@ TestRunner.completeTest(); }); - var fsWorkspaceBinding = Workspace.workspace.project(folderLocation); + var fsWorkspaceBinding = await Workspace.workspace.project('file://' + folderLocation); fsWorkspaceBinding.createFile('', 'test.txt', 'file content'); -})() \ No newline at end of file +})()
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-conflicting-paths.js b/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-conflicting-paths.js index 59a23796..08614cac9 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-conflicting-paths.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-conflicting-paths.js
@@ -6,9 +6,9 @@ TestRunner.addResult(`Verifies that uiSourceCode.delete actually deltes file from IsolatedFileSystem.\n`); await TestRunner.loadTestModule('bindings_test_runner'); - var fs1 = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs1 = new BindingsTestRunner.TestFileSystem('/var/www'); var file1 = fs1.addFile('foo.js', 'foo.js', 0); - var fs2 = new BindingsTestRunner.TestFileSystem('file:///var/www_suffix'); + var fs2 = new BindingsTestRunner.TestFileSystem('/var/www_suffix'); var file2 = fs2.addFile('bar.js', 'bar.js', 0); await new Promise(x => fs1.reportCreated(x)); await new Promise(x => fs2.reportCreated(x));
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-delete-file.js b/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-delete-file.js index 7c9b82b4..f32e3c1 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-delete-file.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-delete-file.js
@@ -6,7 +6,7 @@ TestRunner.addResult(`Verifies that uiSourceCode.delete actually deltes file from IsolatedFileSystem.\n`); await TestRunner.loadTestModule('bindings_test_runner'); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFiles(fs, { 'script.js': {content: 'testme'}, 'bar.js': {content: 'another'}, @@ -15,9 +15,9 @@ TestRunner.waitForUISourceCode('script.js').then(onUISourceCode); function onUISourceCode(uiSourceCode) { - TestRunner.addResult('BEFORE:\n' + fs.dumpAsText()); + TestRunner.addResult('BEFORE:\n' + 'file://' + fs.dumpAsText()); uiSourceCode.remove(); - TestRunner.addResult('\nAFTER:\n' + fs.dumpAsText()); + TestRunner.addResult('\nAFTER:\n' + 'file://' + fs.dumpAsText()); TestRunner.completeTest(); } })();
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-ignores-files-on-changed.js b/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-ignores-files-on-changed.js index 8aa077ce..286f7d2 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-ignores-files-on-changed.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/filesystem-ignores-files-on-changed.js
@@ -7,7 +7,7 @@ await TestRunner.loadTestModule('bindings_test_runner'); TestRunner.addResult('Creating filesystem'); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); await fs.reportCreatedPromise(); Persistence.isolatedFileSystemManager.addEventListener( @@ -41,4 +41,4 @@ friendlyFile.setContent('content2'); TestRunner.completeTest(); -})(); \ No newline at end of file +})();
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/navigator-create-file-copy.js b/third_party/blink/web_tests/http/tests/devtools/persistence/navigator-create-file-copy.js index 00fa9af3..9fc1587 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/navigator-create-file-copy.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/navigator-create-file-copy.js
@@ -8,7 +8,7 @@ await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFiles(fs, { 'script.js': {content: 'testme'}, }); @@ -17,9 +17,9 @@ var sourcesNavigator = new Sources.NetworkNavigatorView(); sourcesNavigator.show(UI.inspectorView.element); - TestRunner.addResult('BEFORE:\n' + fs.dumpAsText()); + TestRunner.addResult('BEFORE:\n' + 'file://' + fs.dumpAsText()); sourcesNavigator.handleContextMenuCreate(uiSourceCode.project(), '', uiSourceCode); await TestRunner.waitForUISourceCode('NewFile'); - TestRunner.addResult('\nAFTER:\n' + fs.dumpAsText()); + TestRunner.addResult('\nAFTER:\n' + 'file://' + fs.dumpAsText()); TestRunner.completeTest(); })();
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-do-not-overwrite-css.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-do-not-overwrite-css.js index c0d33a9..13f4d294 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-do-not-overwrite-css.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-do-not-overwrite-css.js
@@ -26,7 +26,7 @@ .then(onCSSContent); function onCSSContent({ content, error, isEncoded }) { - fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFiles(fs, { 'simple.css': {content: content}, });
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-go-to-file-dialog.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-go-to-file-dialog.js index cbe1cb558..c483f32 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-go-to-file-dialog.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-go-to-file-dialog.js
@@ -10,7 +10,7 @@ await TestRunner.addScriptTag('resources/foo.js'); var testMapping = BindingsTestRunner.initializeTestMapping(); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFooJSFile(fs); fs.reportCreated(function() {});
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-move-breakpoints-on-reload.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-move-breakpoints-on-reload.js index 857b6336..ab3e95e2 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-move-breakpoints-on-reload.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-move-breakpoints-on-reload.js
@@ -16,7 +16,7 @@ `); var testMapping = BindingsTestRunner.initializeTestMapping(); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFooJSFile(fs); TestRunner.runTestSuite([
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-move-breakpoints.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-move-breakpoints.js index c7cc5d4..bd39fc9e 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-move-breakpoints.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-move-breakpoints.js
@@ -10,7 +10,7 @@ await TestRunner.showPanel('sources'); var testMapping = BindingsTestRunner.initializeTestMapping(); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); var fsEntry = BindingsTestRunner.addFooJSFile(fs); TestRunner.runTestSuite([
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-navigator-unique-names.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-navigator-unique-names.js index 6d09ecd..d8e2e11 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-navigator-unique-names.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-navigator-unique-names.js
@@ -9,15 +9,15 @@ var filesNavigator = new Sources.FilesNavigatorView(); filesNavigator.show(UI.inspectorView.element); - var fs1 = new BindingsTestRunner.TestFileSystem('file:///home/workspace/good/foo/bar'); + var fs1 = new BindingsTestRunner.TestFileSystem('/home/workspace/good/foo/bar'); fs1.addFile('1.js', ''); fs1.reportCreated(function() { }); - var fs2 = new BindingsTestRunner.TestFileSystem('file:///home/workspace/bad/foo/bar'); + var fs2 = new BindingsTestRunner.TestFileSystem('/home/workspace/bad/foo/bar'); fs2.addFile('2.js', ''); fs2.reportCreated(function(){ }); - var fs3 = new BindingsTestRunner.TestFileSystem('file:///home/workspace/ugly/bar'); + var fs3 = new BindingsTestRunner.TestFileSystem('/home/workspace/ugly/bar'); fs3.addFile('3.js', ''); fs3.reportCreated(function(){ });
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-search-across-all-files.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-search-across-all-files.js index b5452239..8c2a6ae 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-search-across-all-files.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-search-across-all-files.js
@@ -10,7 +10,7 @@ await TestRunner.addScriptTag('resources/foo.js'); var testMapping = BindingsTestRunner.initializeTestMapping(); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); var fsEntry = BindingsTestRunner.addFooJSFile(fs); var scope = new Sources.SourcesSearchScope(); fs.reportCreated(function() {});
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-switch-editor-tab.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-switch-editor-tab.js index 4f482ac..f7459f8 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-switch-editor-tab.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-switch-editor-tab.js
@@ -25,7 +25,7 @@ }, function addMapping(next) { - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); BindingsTestRunner.addFooJSFile(fs); fs.reportCreated(function() {}); testMapping.addBinding('foo.js');
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-sync-content-nodejs.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-sync-content-nodejs.js index dd1b73b..81a9119 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-sync-content-nodejs.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-sync-content-nodejs.js
@@ -24,7 +24,7 @@ await SourcesTestRunner.addScriptUISourceCode('http://127.0.0.1:8000/nodejs.js', nodeContent); // Add filesystem UISourceCode and mapping. - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); var fsEntry = fs.root.addFile('nodejs.js', fsContent); fs.reportCreated(function() {});
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-sync-content.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-sync-content.js index e52796b..8c86759 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-sync-content.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-sync-content.js
@@ -9,7 +9,7 @@ await TestRunner.addScriptTag('resources/foo.js'); var testMapping = BindingsTestRunner.initializeTestMapping(); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); var fsEntry = BindingsTestRunner.addFooJSFile(fs); var networkCode, fileSystemCode;
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-keeps-selected-tab.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-keeps-selected-tab.js index 3769ca5..bdae09a 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-keeps-selected-tab.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-keeps-selected-tab.js
@@ -10,7 +10,7 @@ await TestRunner.showPanel('sources'); var testMapping = BindingsTestRunner.initializeTestMapping(); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); var fsEntry = BindingsTestRunner.addFooJSFile(fs); fs.root.addFile('bar.js', 'window.bar = ()=>\'bar\';'); await fs.reportCreatedPromise();
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-opens-filesystem-uisourcecode.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-opens-filesystem-uisourcecode.js index 61b8398a..193e279 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-opens-filesystem-uisourcecode.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-opens-filesystem-uisourcecode.js
@@ -12,7 +12,7 @@ await TestRunner.showPanel('sources'); var testMapping = BindingsTestRunner.initializeTestMapping(); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); var fsEntry = BindingsTestRunner.addFooJSFile(fs); fs.reportCreated(function() {}); testMapping.addBinding('foo.js');
diff --git a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-tabs-order.js b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-tabs-order.js index 9caf6cf4..8fd3871 100644 --- a/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-tabs-order.js +++ b/third_party/blink/web_tests/http/tests/devtools/persistence/persistence-tabbed-editor-tabs-order.js
@@ -11,7 +11,7 @@ await TestRunner.navigatePromise(TestRunner.url('resources/persistence-tabbed-editor-tab-order.html')); var testMapping = BindingsTestRunner.initializeTestMapping(); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); var folder = fs.root.mkdir('devtools').mkdir('persistence').mkdir('resources'); folder.addFile('foo.js', '\n\nwindow.foo = ()=>\'foo\';'); folder.addFile('bar.js', 'window.bar = () => "bar";');
diff --git a/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-in-files.js b/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-in-files.js index 3adc59d6..f49d40b 100644 --- a/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-in-files.js +++ b/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-in-files.js
@@ -19,7 +19,7 @@ var scope = new Sources.SourcesSearchScope(); var names = ['search.html', 'search.js', 'search.css']; - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); var promises = []; for (var name of names)
diff --git a/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-many-projects.js b/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-many-projects.js index 97d8918..9e49fb1 100644 --- a/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-many-projects.js +++ b/third_party/blink/web_tests/http/tests/devtools/search/sources-search-scope-many-projects.js
@@ -18,7 +18,7 @@ } var scope = new Sources.SourcesSearchScope(); - var fs = new BindingsTestRunner.TestFileSystem('file:///var/www'); + var fs = new BindingsTestRunner.TestFileSystem('/var/www'); var names = ['search.html', 'search.js', 'search.css']; var resources = {}; var jsFileSystemUISourceCode;
diff --git a/third_party/blink/web_tests/http/tests/devtools/workspace-view-file-system-header.js b/third_party/blink/web_tests/http/tests/devtools/workspace-view-file-system-header.js index ecaf92b..184440b 100644 --- a/third_party/blink/web_tests/http/tests/devtools/workspace-view-file-system-header.js +++ b/third_party/blink/web_tests/http/tests/devtools/workspace-view-file-system-header.js
@@ -5,8 +5,7 @@ (async function() { TestRunner.addResult('Tests workspace view file system headers\n'); await TestRunner.loadTestModule('bindings_test_runner'); - - const fs = new BindingsTestRunner.TestFileSystem('file:///this/is/a/test'); + const fs = new BindingsTestRunner.TestFileSystem('/this/is/a/test'); await fs.reportCreatedPromise(); await UI.viewManager.showView('workspace'); @@ -17,6 +16,5 @@ TestRunner.addResult(`File system name: ${fsName}`); TestRunner.addResult(`File system path: ${fsPath}`); - TestRunner.completeTest(); })();
diff --git a/third_party/blink/web_tests/platform/linux/fast/table/003-expected.png b/third_party/blink/web_tests/platform/linux/fast/table/003-expected.png index ab9e610a..a220dd7 100644 --- a/third_party/blink/web_tests/platform/linux/fast/table/003-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/table/003-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/table/021-expected.png b/third_party/blink/web_tests/platform/linux/fast/table/021-expected.png index 02ad512..c84a81fc 100644 --- a/third_party/blink/web_tests/platform/linux/fast/table/021-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/table/021-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/fast/table/rowspan-paint-order-vertical-expected.png b/third_party/blink/web_tests/platform/linux/fast/table/rowspan-paint-order-vertical-expected.png index 4134cf7..96564e8 100644 --- a/third_party/blink/web_tests/platform/linux/fast/table/rowspan-paint-order-vertical-expected.png +++ b/third_party/blink/web_tests/platform/linux/fast/table/rowspan-paint-order-vertical-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug57828-expected.png b/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug57828-expected.png index 17487999..e51e612 100644 --- a/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug57828-expected.png +++ b/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug57828-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug78162-expected.png b/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug78162-expected.png index 2156a1e..abf922a 100644 --- a/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug78162-expected.png +++ b/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug78162-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug92143-expected.png b/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug92143-expected.png index ad55873..30b7ee0a 100644 --- a/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug92143-expected.png +++ b/third_party/blink/web_tests/platform/linux/tables/mozilla/bugs/bug92143-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https-expected.txt new file mode 100644 index 0000000..6240f63 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.13/external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +PASS PeerConnection passthrough MediaRecorder receives VP8 after onstart with a video stream. +PASS PeerConnection passthrough MediaRecorder receives VP8 after onstart with a audio/video stream. +PASS PeerConnection passthrough MediaRecorder receives VP9 after onstart with a video stream. +PASS PeerConnection passthrough MediaRecorder receives VP9 after onstart with a audio/video stream. +FAIL PeerConnection passthrough MediaRecorder should be prepared to handle the codec switching from VP8 to VP9 assert_unreached: MediaRecorder should be prepared to handle codec switches Reached unreachable code +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https-expected.txt new file mode 100644 index 0000000..1e93b7a --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.14/external/wpt/mediacapture-record/passthrough/MediaRecorder-passthrough.https-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +PASS PeerConnection passthrough MediaRecorder receives VP8 after onstart with a video stream. +PASS PeerConnection passthrough MediaRecorder receives VP8 after onstart with a audio/video stream. +PASS PeerConnection passthrough MediaRecorder receives VP9 after onstart with a video stream. +PASS PeerConnection passthrough MediaRecorder receives VP9 after onstart with a audio/video stream. +PASS PeerConnection passthrough MediaRecorder should be prepared to handle the codec switching from VP8 to VP9 +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac/fast/table/003-expected.png b/third_party/blink/web_tests/platform/mac/fast/table/003-expected.png index 44113e6..b16ba19 100644 --- a/third_party/blink/web_tests/platform/mac/fast/table/003-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/table/003-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/table/021-expected.png b/third_party/blink/web_tests/platform/mac/fast/table/021-expected.png index 0f439bb..3e5ff89 100644 --- a/third_party/blink/web_tests/platform/mac/fast/table/021-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/table/021-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/table/rowspan-paint-order-vertical-expected.png b/third_party/blink/web_tests/platform/mac/fast/table/rowspan-paint-order-vertical-expected.png index c0113ec..093982b 100644 --- a/third_party/blink/web_tests/platform/mac/fast/table/rowspan-paint-order-vertical-expected.png +++ b/third_party/blink/web_tests/platform/mac/fast/table/rowspan-paint-order-vertical-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug57828-expected.png b/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug57828-expected.png index 42aa3f30..32989fc 100644 --- a/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug57828-expected.png +++ b/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug57828-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug78162-expected.png b/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug78162-expected.png index 45cacd6..ab597c7b 100644 --- a/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug78162-expected.png +++ b/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug78162-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug92143-expected.png b/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug92143-expected.png index 34bd3af3..fabbf7c 100644 --- a/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug92143-expected.png +++ b/third_party/blink/web_tests/platform/mac/tables/mozilla/bugs/bug92143-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/table/003-expected.png b/third_party/blink/web_tests/platform/win/fast/table/003-expected.png index dc52d1c..6e74807 100644 --- a/third_party/blink/web_tests/platform/win/fast/table/003-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/table/003-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/table/021-expected.png b/third_party/blink/web_tests/platform/win/fast/table/021-expected.png index 0b1c7d7..4cacf053 100644 --- a/third_party/blink/web_tests/platform/win/fast/table/021-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/table/021-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/fast/table/rowspan-paint-order-vertical-expected.png b/third_party/blink/web_tests/platform/win/fast/table/rowspan-paint-order-vertical-expected.png index a7f2bd3..e82302b 100644 --- a/third_party/blink/web_tests/platform/win/fast/table/rowspan-paint-order-vertical-expected.png +++ b/third_party/blink/web_tests/platform/win/fast/table/rowspan-paint-order-vertical-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug57828-expected.png b/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug57828-expected.png index a62250b..55b9114d 100644 --- a/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug57828-expected.png +++ b/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug57828-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug78162-expected.png b/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug78162-expected.png index 3647a68..8106149c 100644 --- a/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug78162-expected.png +++ b/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug78162-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug92143-expected.png b/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug92143-expected.png index 8b82eee..eff9df1 100644 --- a/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug92143-expected.png +++ b/third_party/blink/web_tests/platform/win/tables/mozilla/bugs/bug92143-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/webgpu/internal_cts_test_splits.pyl b/third_party/blink/web_tests/webgpu/internal_cts_test_splits.pyl index 9311c2d7..4bfd98c 100644 --- a/third_party/blink/web_tests/webgpu/internal_cts_test_splits.pyl +++ b/third_party/blink/web_tests/webgpu/internal_cts_test_splits.pyl
@@ -207,6 +207,7 @@ 'wpt_internal/webgpu/cts.https.html?q=webgpu:api,operation,vertex_state,correctness:vertex_buffer_used_multiple_times_overlapped:format="uint8x2";*', 'wpt_internal/webgpu/cts.https.html?q=webgpu:api,validation,image_copy,texture_related:format:method="WriteTexture";*', + 'wpt_internal/webgpu/cts.https.html?q=webgpu:api,validation,image_copy,texture_related:origin_alignment:method="WriteTexture";*', 'wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,zero_init:compute,zero_init:storageClass="workgroup";workgroupSize=[1,1,1];batch__=0;*', 'wpt_internal/webgpu/cts.https.html?q=webgpu:shader,execution,zero_init:compute,zero_init:storageClass="workgroup";workgroupSize=[1,32,1];batch__=0;*',
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-break/webkit-box-decoration-break-ref.html b/third_party/blink/web_tests/wpt_internal/css/css-break/webkit-box-decoration-break-ref.html new file mode 100644 index 0000000..fa4bd21f --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/css/css-break/webkit-box-decoration-break-ref.html
@@ -0,0 +1,5 @@ +<!doctype html> +<title>CSS Test Reference</title> +<style>span { border: 1px solid green }</style> +<div><span>These lines of text</span><br> +<span>should have closed borders.</span></div>
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-break/webkit-box-decoration-break.html b/third_party/blink/web_tests/wpt_internal/css/css-break/webkit-box-decoration-break.html new file mode 100644 index 0000000..b978186f --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/css/css-break/webkit-box-decoration-break.html
@@ -0,0 +1,12 @@ +<!doctype html> +<title>Layout and paint invalidation for -webkit-box-decoration-break change.</title> +<link rel="match" href="webkit-box-decoration-break-ref.html"> +<style> + span { border: 1px solid green; } + span.clone { -webkit-box-decoration-break: clone } +</style> +<div><span>These lines of text<br>should have closed borders.</span></div> +<script> + document.body.offsetTop; + document.querySelector("span").className = "clone"; +</script>
diff --git a/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html b/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html index 82dc914..12360b1d 100644 --- a/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html +++ b/third_party/blink/web_tests/wpt_internal/webgpu/cts.https.html
@@ -1779,7 +1779,9 @@ <meta name=variant content='?q=webgpu:api,validation,image_copy,texture_related:format:method="WriteTexture";*'> <meta name=variant content='?q=webgpu:api,validation,image_copy,texture_related:format:method="CopyB2T";*'> <meta name=variant content='?q=webgpu:api,validation,image_copy,texture_related:format:method="CopyT2B";*'> -<meta name=variant content='?q=webgpu:api,validation,image_copy,texture_related:origin_alignment:*'> +<meta name=variant content='?q=webgpu:api,validation,image_copy,texture_related:origin_alignment:method="WriteTexture";*'> +<meta name=variant content='?q=webgpu:api,validation,image_copy,texture_related:origin_alignment:method="CopyB2T";*'> +<meta name=variant content='?q=webgpu:api,validation,image_copy,texture_related:origin_alignment:method="CopyT2B";*'> <meta name=variant content='?q=webgpu:api,validation,image_copy,texture_related:1d:*'> <meta name=variant content='?q=webgpu:api,validation,image_copy,texture_related:size_alignment:*'> <meta name=variant content='?q=webgpu:api,validation,image_copy,texture_related:copy_rectangle:*'>
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium index f1168ef..7ebff1f 100644 --- a/third_party/crashpad/README.chromium +++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@ Short Name: crashpad URL: https://crashpad.chromium.org/ Version: unknown -Revision: 8342e6bd613a5b2e44eca1d74288e3115ccef139 +Revision: ab9a87fb5463e5d1579e16bacb1f79d0dd71119b License: Apache 2.0 License File: crashpad/LICENSE Security Critical: yes
diff --git a/third_party/crashpad/crashpad/.gitignore b/third_party/crashpad/crashpad/.gitignore index 27c9f8d..b739477 100644 --- a/third_party/crashpad/crashpad/.gitignore +++ b/third_party/crashpad/crashpad/.gitignore
@@ -19,6 +19,7 @@ *.xcodeproj *~ .*.sw? +.cache .DS_Store .gdb_history .gdbinit
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS index 8ecd52e3..c1edb80c 100644 --- a/third_party/crashpad/crashpad/DEPS +++ b/third_party/crashpad/crashpad/DEPS
@@ -39,7 +39,7 @@ '7bde79cc274d06451bf65ae82c012a5d3e476b5a', 'crashpad/third_party/mini_chromium/mini_chromium': Var('chromium_git') + '/chromium/mini_chromium@' + - '461b416dbe5f40a060ee08764b4986a949da6e6e', + '0e22eed71eec97dacbe80822a14c5cd0b580d793', 'crashpad/third_party/libfuzzer/src': Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' + 'fda403cf93ecb8792cb1d061564d89a6553ca020',
diff --git a/third_party/crashpad/crashpad/client/BUILD.gn b/third_party/crashpad/crashpad/client/BUILD.gn index b60e904..1a83efa2 100644 --- a/third_party/crashpad/crashpad/client/BUILD.gn +++ b/third_party/crashpad/crashpad/client/BUILD.gn
@@ -170,6 +170,7 @@ sources += [ "crashpad_client_ios_test.mm", "ios_handler/exception_processor_test.mm", + "ios_handler/in_process_handler_test.cc", "ios_handler/in_process_intermediate_dump_handler_test.cc", ] }
diff --git a/third_party/crashpad/crashpad/client/crash_report_database.cc b/third_party/crashpad/crashpad/client/crash_report_database.cc index 68393333..5c8156e 100644 --- a/third_party/crashpad/crashpad/client/crash_report_database.cc +++ b/third_party/crashpad/crashpad/client/crash_report_database.cc
@@ -14,10 +14,29 @@ #include "client/crash_report_database.h" +#include <sys/stat.h> + +#include "base/logging.h" +#include "base/strings/utf_string_conversions.h" #include "build/build_config.h" +#include "util/file/directory_reader.h" +#include "util/file/filesystem.h" namespace crashpad { +namespace { +constexpr base::FilePath::CharType kAttachmentsDirectory[] = + FILE_PATH_LITERAL("attachments"); + +bool AttachmentNameIsOK(const std::string& name) { + for (const char c : name) { + if (c != '_' && c != '-' && c != '.' && !isalnum(c)) + return false; + } + return true; +} +} // namespace + CrashReportDatabase::Report::Report() : uuid(), file_path(), @@ -73,6 +92,60 @@ return reader_.get(); } +FileWriter* CrashReportDatabase::NewReport::AddAttachment( + const std::string& name) { + if (!AttachmentNameIsOK(name)) { + LOG(ERROR) << "invalid name for attachment " << name; + return nullptr; + } + base::FilePath report_attachments_dir = database_->AttachmentsPath(uuid_); + if (!LoggingCreateDirectory( + report_attachments_dir, FilePermissions::kOwnerOnly, true)) { + return nullptr; + } +#if defined(OS_WIN) + const std::wstring name_string = base::UTF8ToWide(name); +#else + const std::string name_string = name; +#endif + base::FilePath attachment_path = report_attachments_dir.Append(name_string); + auto writer = std::make_unique<FileWriter>(); + if (!writer->Open(attachment_path, + FileWriteMode::kCreateOrFail, + FilePermissions::kOwnerOnly)) { + return nullptr; + } + attachment_writers_.emplace_back(std::move(writer)); + attachment_removers_.emplace_back(ScopedRemoveFile(attachment_path)); + return attachment_writers_.back().get(); +} + +void CrashReportDatabase::UploadReport::InitializeAttachments() { + base::FilePath report_attachments_dir = database_->AttachmentsPath(uuid); + DirectoryReader dir_reader; + if (!dir_reader.Open(report_attachments_dir)) { + return; + } + + base::FilePath filename; + DirectoryReader::Result dir_result; + while ((dir_result = dir_reader.NextFile(&filename)) == + DirectoryReader::Result::kSuccess) { + const base::FilePath filepath(report_attachments_dir.Append(filename)); + std::unique_ptr<FileReader> file_reader(std::make_unique<FileReader>()); + if (!file_reader->Open(filepath)) { + continue; + } + attachment_readers_.emplace_back(std::move(file_reader)); +#if defined(OS_WIN) + const std::string name_string = base::WideToUTF8(filename.value()); +#else + const std::string name_string = filename.value(); +#endif + attachment_map_[name_string] = attachment_readers_.back().get(); + } +} + CrashReportDatabase::UploadReport::UploadReport() : Report(), reader_(std::make_unique<FileReader>()), @@ -103,4 +176,40 @@ return RecordUploadAttempt(report, true, id); } +base::FilePath CrashReportDatabase::AttachmentsPath(const UUID& uuid) { +#if defined(OS_WIN) + const std::wstring uuid_string = uuid.ToWString(); +#else + const std::string uuid_string = uuid.ToString(); +#endif + + return DatabasePath().Append(kAttachmentsDirectory).Append(uuid_string); +} + +base::FilePath CrashReportDatabase::AttachmentsRootPath() { + return DatabasePath().Append(kAttachmentsDirectory); +} + +void CrashReportDatabase::RemoveAttachmentsByUUID(const UUID& uuid) { + base::FilePath report_attachment_dir = AttachmentsPath(uuid); + if (!IsDirectory(report_attachment_dir, /*allow_symlinks=*/false)) { + return; + } + DirectoryReader reader; + if (!reader.Open(report_attachment_dir)) { + return; + } + + base::FilePath filename; + DirectoryReader::Result result; + while ((result = reader.NextFile(&filename)) == + DirectoryReader::Result::kSuccess) { + const base::FilePath attachment_path( + report_attachment_dir.Append(filename)); + LoggingRemoveFile(attachment_path); + } + + LoggingRemoveDirectory(report_attachment_dir); +} + } // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/crash_report_database.h b/third_party/crashpad/crashpad/client/crash_report_database.h index 19f1bf7..fea49853 100644 --- a/third_party/crashpad/crashpad/client/crash_report_database.h +++ b/third_party/crashpad/crashpad/client/crash_report_database.h
@@ -129,8 +129,6 @@ //! \brief Adds an attachment to the report. //! - //! \note This function is not yet implemented on macOS. - //! //! \param[in] name The key and name for the attachment, which will be //! included in the http upload. The attachment will not appear in the //! minidump report. \a name should only use characters from the set @@ -174,8 +172,6 @@ //! \brief Obtains a mapping of names to file readers for any attachments //! for the report. - //! - //! This is not implemented on macOS. std::map<std::string, FileReader*> GetAttachments() const { return attachment_map_; } @@ -400,9 +396,11 @@ virtual OperationStatus RequestUpload(const UUID& uuid) = 0; //! \brief Cleans the database of expired lockfiles, metadata without report - //! files, and report files without metadata. + //! files, report files without metadata, and attachments without report + //! files. //! - //! This method does nothing on the macOS implementations of the database. + //! As the macOS implementation does not use lock or metadata files, the + //! cleaning is limited to attachments without report files. //! //! \param[in] lockfile_ttl The number of seconds at which lockfiles or new //! report files are considered expired. @@ -412,6 +410,30 @@ protected: CrashReportDatabase() {} + //! \brief The path to the database passed to Initialize. + //! + //! \return The filepath of the database; + virtual base::FilePath DatabasePath() = 0; + + //! \brief Build a filepath for the root attachments directory. + //! + //! \return The filepath to the attachments directory. + base::FilePath AttachmentsRootPath(); + + //! \brief Build a filepath for the directory for the report to hold + //! attachments. + //! + //! \param[in] uuid The unique identifier for the crash report record. + //! + //! \return The filepath to the report attachments directory. + base::FilePath AttachmentsPath(const UUID& uuid); + + //! \brief Attempts to remove any attachments associated with the given + //! report UUID. There may not be any, so failing is not an error. + //! + //! \param[in] uuid The unique identifier for the crash report record. + void RemoveAttachmentsByUUID(const UUID& uuid); + private: //! \brief Adjusts a crash report record’s metadata to account for an upload //! attempt, and updates the last upload attempt time as returned by
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_generic.cc b/third_party/crashpad/crashpad/client/crash_report_database_generic.cc index 7af1399..f5dfa89 100644 --- a/third_party/crashpad/crashpad/client/crash_report_database_generic.cc +++ b/third_party/crashpad/crashpad/client/crash_report_database_generic.cc
@@ -45,14 +45,6 @@ return uuid; } -bool AttachmentNameIsOK(const std::string& name) { - for (const char c : name) { - if (c != '_' && c != '-' && c != '.' && !isalnum(c)) - return false; - } - return true; -} - using OperationStatus = CrashReportDatabase::OperationStatus; constexpr base::FilePath::CharType kSettings[] = @@ -70,8 +62,6 @@ FILE_PATH_LITERAL("pending"); constexpr base::FilePath::CharType kCompletedDirectory[] = FILE_PATH_LITERAL("completed"); -constexpr base::FilePath::CharType kAttachmentsDirectory[] = - FILE_PATH_LITERAL("attachments"); constexpr const base::FilePath::CharType* kReportDirectories[] = { kNewDirectory, @@ -164,35 +154,6 @@ private: ScopedRemoveFile lock_file_; }; - -off_t GetFileSize(const base::FilePath& filepath) { - struct stat statbuf; - if (stat(filepath.value().c_str(), &statbuf) == 0) { - return statbuf.st_size; - } - PLOG(ERROR) << "stat " << filepath.value(); - return 0; -} - -void AddAttachmentSize(const base::FilePath& attachments_dir, uint64_t* size) { - // Early return if the attachment directory does not exist. - if (!IsDirectory(attachments_dir, /*allow_symlinks=*/false)) { - return; - } - DirectoryReader reader; - if (!reader.Open(attachments_dir)) { - return; - } - base::FilePath attachment_filename; - DirectoryReader::Result result; - while ((result = reader.NextFile(&attachment_filename)) == - DirectoryReader::Result::kSuccess) { - const base::FilePath attachment_filepath( - attachments_dir.Append(attachment_filename)); - *size += GetFileSize(attachment_filepath); - } -} - } // namespace class CrashReportDatabaseGeneric : public CrashReportDatabase { @@ -225,9 +186,7 @@ OperationStatus DeleteReport(const UUID& uuid) override; OperationStatus RequestUpload(const UUID& uuid) override; int CleanDatabase(time_t lockfile_ttl) override; - - // Build a filepath for the directory for the report to hold attachments. - base::FilePath AttachmentsPath(const UUID& uuid); + base::FilePath DatabasePath() override; private: struct LockfileUploadReport : public UploadReport { @@ -286,10 +245,6 @@ // Cleans any attachments that have no associated report in any state. void CleanOrphanedAttachments(); - // Attempt to remove any attachments associated with the given report UUID. - // There may not be any, so failing is not an error. - void RemoveAttachmentsByUUID(const UUID& uuid); - // Reads the metadata for a report from path and returns it in report. bool ReadMetadata(const base::FilePath& path, Report* report); @@ -307,62 +262,6 @@ InitializationStateDcheck initialized_; }; -FileWriter* CrashReportDatabase::NewReport::AddAttachment( - const std::string& name) { - if (!AttachmentNameIsOK(name)) { - LOG(ERROR) << "invalid name for attachment " << name; - return nullptr; - } - - base::FilePath attachments_dir = - static_cast<CrashReportDatabaseGeneric*>(database_)->AttachmentsPath( - uuid_); - if (!LoggingCreateDirectory( - attachments_dir, FilePermissions::kOwnerOnly, true)) { - return nullptr; - } - - base::FilePath path = attachments_dir.Append(name); - - auto writer = std::make_unique<FileWriter>(); - if (!writer->Open( - path, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly)) { - LOG(ERROR) << "could not open " << path.value(); - return nullptr; - } - attachment_writers_.emplace_back(std::move(writer)); - attachment_removers_.emplace_back(ScopedRemoveFile(path)); - return attachment_writers_.back().get(); -} - -void CrashReportDatabase::UploadReport::InitializeAttachments() { - base::FilePath attachments_dir = - static_cast<CrashReportDatabaseGeneric*>(database_)->AttachmentsPath( - uuid); - if (!IsDirectory(attachments_dir, /*allow_symlinks=*/false)) { - return; - } - DirectoryReader directory_reader; - if (!directory_reader.Open(attachments_dir)) { - return; - } - - base::FilePath filename; - DirectoryReader::Result dir_result; - while ((dir_result = directory_reader.NextFile(&filename)) == - DirectoryReader::Result::kSuccess) { - const base::FilePath filepath(attachments_dir.Append(filename)); - std::unique_ptr<FileReader> file_reader(std::make_unique<FileReader>()); - if (!file_reader->Open(filepath)) { - LOG(ERROR) << "attachment " << filepath.value() - << " couldn't be opened, skipping"; - continue; - } - attachment_readers_.emplace_back(std::move(file_reader)); - attachment_map_[filename.value()] = attachment_readers_.back().get(); - } -} - CrashReportDatabaseGeneric::CrashReportDatabaseGeneric() = default; CrashReportDatabaseGeneric::~CrashReportDatabaseGeneric() = default; @@ -385,9 +284,8 @@ } } - if (!LoggingCreateDirectory(base_dir_.Append(kAttachmentsDirectory), - FilePermissions::kOwnerOnly, - true)) { + if (!LoggingCreateDirectory( + AttachmentsRootPath(), FilePermissions::kOwnerOnly, true)) { return false; } @@ -413,6 +311,10 @@ return database->Initialize(path, false) ? std::move(database) : nullptr; } +base::FilePath CrashReportDatabaseGeneric::DatabasePath() { + return base_dir_; +} + Settings* CrashReportDatabaseGeneric::GetSettings() { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return &settings_; @@ -699,7 +601,7 @@ DCHECK_NE(state, kSearchable); #if defined(OS_WIN) - const std::wstring uuid_string = uuid.ToString16(); + const std::wstring uuid_string = uuid.ToWString(); #else const std::string uuid_string = uuid.ToString(); #endif @@ -708,16 +610,6 @@ .Append(uuid_string + kCrashReportExtension); } -base::FilePath CrashReportDatabaseGeneric::AttachmentsPath(const UUID& uuid) { -#if defined(OS_WIN) - const std::wstring uuid_string = uuid.ToString16(); -#else - const std::string uuid_string = uuid.ToString(); -#endif - - return base_dir_.Append(kAttachmentsDirectory).Append(uuid_string); -} - OperationStatus CrashReportDatabaseGeneric::LocateAndLockReport( const UUID& uuid, ReportState desired_state, @@ -878,7 +770,7 @@ } void CrashReportDatabaseGeneric::CleanOrphanedAttachments() { - base::FilePath root_attachments_dir(base_dir_.Append(kAttachmentsDirectory)); + base::FilePath root_attachments_dir(AttachmentsRootPath()); DirectoryReader reader; if (!reader.Open(root_attachments_dir)) { return; @@ -888,8 +780,9 @@ DirectoryReader::Result result; while ((result = reader.NextFile(&filename)) == DirectoryReader::Result::kSuccess) { - const base::FilePath path(root_attachments_dir.Append(filename)); - if (IsDirectory(path, false)) { + const base::FilePath report_attachment_dir( + root_attachments_dir.Append(filename)); + if (IsDirectory(report_attachment_dir, false)) { UUID uuid; if (!uuid.InitializeFromString(filename.value())) { LOG(ERROR) << "unexpected attachment dir name " << filename.value(); @@ -919,27 +812,6 @@ } } -void CrashReportDatabaseGeneric::RemoveAttachmentsByUUID(const UUID& uuid) { - base::FilePath attachments_dir = AttachmentsPath(uuid); - if (!IsDirectory(attachments_dir, /*allow_symlinks=*/false)) { - return; - } - DirectoryReader reader; - if (!reader.Open(attachments_dir)) { - return; - } - - base::FilePath filename; - DirectoryReader::Result result; - while ((result = reader.NextFile(&filename)) == - DirectoryReader::Result::kSuccess) { - const base::FilePath filepath(attachments_dir.Append(filename)); - LoggingRemoveFile(filepath); - } - - LoggingRemoveDirectory(attachments_dir); -} - bool CrashReportDatabaseGeneric::ReadMetadata(const base::FilePath& path, Report* report) { const base::FilePath metadata_path( @@ -974,7 +846,7 @@ // Seed the total size with the main report size and then add the sizes of any // potential attachments. uint64_t total_size = GetFileSize(path); - AddAttachmentSize(AttachmentsPath(uuid), &total_size); + total_size += GetDirectorySize(AttachmentsPath(uuid)); report->uuid = uuid; report->upload_attempts = metadata.upload_attempts;
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_mac.mm b/third_party/crashpad/crashpad/client/crash_report_database_mac.mm index fb7dedc4..d1c0a3ed 100644 --- a/third_party/crashpad/crashpad/client/crash_report_database_mac.mm +++ b/third_party/crashpad/crashpad/client/crash_report_database_mac.mm
@@ -35,7 +35,9 @@ #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" #include "client/settings.h" +#include "util/file/directory_reader.h" #include "util/file/file_io.h" +#include "util/file/filesystem.h" #include "util/mac/xattr.h" #include "util/misc/initialization_state_dcheck.h" #include "util/misc/metrics.h" @@ -153,6 +155,8 @@ Metrics::CrashSkippedReason reason) override; OperationStatus DeleteReport(const UUID& uuid) override; OperationStatus RequestUpload(const UUID& uuid) override; + int CleanDatabase(time_t lockfile_ttl) override; + base::FilePath DatabasePath() override; private: // CrashReportDatabase: @@ -244,21 +248,15 @@ const base::FilePath& report_path, base::FilePath* out_path); + // Cleans any attachments that have no associated report in any state. + void CleanOrphanedAttachments(); + base::FilePath base_dir_; Settings settings_; bool xattr_new_names_; InitializationStateDcheck initialized_; }; -FileWriter* CrashReportDatabase::NewReport::AddAttachment( - const std::string& name) { - // Attachments aren't implemented in the Mac database yet. - return nullptr; -} - -void CrashReportDatabase::UploadReport::InitializeAttachments() { - // Attachments aren't implemented in the Mac database yet. -} CrashReportDatabaseMac::CrashReportDatabaseMac(const base::FilePath& path) : CrashReportDatabase(), @@ -288,6 +286,10 @@ return false; } + if (!CreateOrEnsureDirectoryExists(AttachmentsRootPath())) { + return false; + } + if (!settings_.Initialize(base_dir_.Append(kSettings))) return false; @@ -315,6 +317,10 @@ return true; } +base::FilePath CrashReportDatabaseMac::DatabasePath() { + return base_dir_; +} + Settings* CrashReportDatabaseMac::GetSettings() { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return &settings_; @@ -381,6 +387,14 @@ } ignore_result(report->file_remover_.release()); + // Close all the attachments and disarm their removers too. + for (auto& writer : report->attachment_writers_) { + writer->Close(); + } + for (auto& remover : report->attachment_removers_) { + ignore_result(remover.release()); + } + Metrics::CrashReportPending(Metrics::PendingReportReason::kNewlyCreated); Metrics::CrashReportSize(size); @@ -444,7 +458,7 @@ if (!ReadReportMetadataLocked(upload_report->file_path, upload_report.get())) return kDatabaseError; - if (!upload_report->reader_->Open(upload_report->file_path)) { + if (!upload_report->Initialize(upload_report->file_path, this)) { return kFileSystemError; } @@ -544,6 +558,8 @@ return kFileSystemError; } + RemoveAttachmentsByUUID(uuid); + return kNoError; } @@ -628,6 +644,34 @@ return kNoError; } +int CrashReportDatabaseMac::CleanDatabase(time_t lockfile_ttl) { + int removed = 0; + time_t now = time(nullptr); + + DirectoryReader reader; + const base::FilePath new_dir(base_dir_.Append(kWriteDirectory)); + if (reader.Open(new_dir)) { + base::FilePath filename; + DirectoryReader::Result result; + while ((result = reader.NextFile(&filename)) == + DirectoryReader::Result::kSuccess) { + const base::FilePath filepath(new_dir.Append(filename)); + timespec filetime; + if (!FileModificationTime(filepath, &filetime)) { + continue; + } + if (filetime.tv_sec <= now - lockfile_ttl) { + if (LoggingRemoveFile(filepath)) { + ++removed; + } + } + } + } + + CleanOrphanedAttachments(); + return removed; +} + // static base::ScopedFD CrashReportDatabaseMac::ObtainReportLock( const base::FilePath& path) { @@ -685,13 +729,11 @@ return false; } - // There are no attachments on Mac so the total size is the main report size. - struct stat statbuf; - if (stat(path.value().c_str(), &statbuf) != 0) { - PLOG(ERROR) << "stat " << path.value(); - return false; - } - report->total_size = statbuf.st_size; + // Seed the total size with the main report size and then add the sizes of any + // potential attachments. + uint64_t total_size = GetFileSize(path); + total_size += GetDirectorySize(AttachmentsPath(report->uuid)); + report->total_size = total_size; return true; } @@ -758,6 +800,47 @@ return kNoError; } +void CrashReportDatabaseMac::CleanOrphanedAttachments() { + base::FilePath root_attachments_dir(AttachmentsRootPath()); + DirectoryReader reader; + if (!reader.Open(root_attachments_dir)) { + return; + } + + base::FilePath filename; + DirectoryReader::Result result; + while ((result = reader.NextFile(&filename)) == + DirectoryReader::Result::kSuccess) { + const base::FilePath report_attachment_dir( + root_attachments_dir.Append(filename)); + if (IsDirectory(report_attachment_dir, false)) { + UUID uuid; + if (!uuid.InitializeFromString(filename.value())) { + LOG(ERROR) << "unexpected attachment dir name " << filename.value(); + continue; + } + + // Check to see if the report is being created in "new". + base::FilePath new_dir_path = + base_dir_.Append(kWriteDirectory) + .Append(uuid.ToString() + "." + kCrashReportFileExtension); + if (IsRegularFile(new_dir_path)) { + continue; + } + + // Check to see if the report is in "pending" or "completed". + base::FilePath local_path = + LocateCrashReport(uuid, kReportStatePending | kReportStateCompleted); + if (!local_path.empty()) { + continue; + } + + // Couldn't find a report, assume these attachments are orphaned. + RemoveAttachmentsByUUID(uuid); + } + } +} + std::unique_ptr<CrashReportDatabase> InitializeInternal( const base::FilePath& path, bool may_create) {
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_test.cc b/third_party/crashpad/crashpad/client/crash_report_database_test.cc index 9d3f1fc..357702b0 100644 --- a/third_party/crashpad/crashpad/client/crash_report_database_test.cc +++ b/third_party/crashpad/crashpad/client/crash_report_database_test.cc
@@ -675,10 +675,6 @@ } TEST_F(CrashReportDatabaseTest, Attachments) { -#if defined(OS_APPLE) || defined(OS_WIN) - // Attachments aren't supported on Mac and Windows yet. - GTEST_SKIP(); -#else std::unique_ptr<CrashReportDatabase::NewReport> new_report; ASSERT_EQ(db()->PrepareNewCrashReport(&new_report), CrashReportDatabase::kNoError); @@ -717,16 +713,9 @@ char result_buffer[sizeof(test_data)]; result_attachments["some_file"]->Read(result_buffer, sizeof(result_buffer)); EXPECT_EQ(memcmp(test_data, result_buffer, sizeof(test_data)), 0); -#endif } TEST_F(CrashReportDatabaseTest, OrphanedAttachments) { -#if defined(OS_APPLE) || defined(OS_WIN) - // Attachments aren't supported on Mac and Windows yet. - GTEST_SKIP(); -#else - // TODO: This is using paths that are specific to the generic implementation - // and will need to be generalized for Mac and Windows. std::unique_ptr<CrashReportDatabase::NewReport> new_report; ASSERT_EQ(db()->PrepareNewCrashReport(&new_report), CrashReportDatabase::kNoError); @@ -748,25 +737,43 @@ ASSERT_TRUE(LoggingRemoveFile(report.file_path)); +#if !defined(OS_APPLE) && !defined(OS_WIN) + // CrashReportDatabaseMac stores metadata in xattrs and does not have .meta + // files. + // CrashReportDatabaseWin stores metadata in a global metadata file and not + // per report. ASSERT_TRUE(LoggingRemoveFile(base::FilePath( report.file_path.RemoveFinalExtension().value() + ".meta"))); +#endif ASSERT_EQ(db()->LookUpCrashReport(uuid, &report), CrashReportDatabase::kReportNotFound); +#if defined(OS_WIN) + const std::wstring uuid_string = uuid.ToWString(); +#else + const std::string uuid_string = uuid.ToString(); +#endif base::FilePath report_attachments_dir( - path().Append("attachments").Append(uuid.ToString())); - base::FilePath file_path1(report_attachments_dir.Append("file1")); - base::FilePath file_path2(report_attachments_dir.Append("file2")); + path().Append(FILE_PATH_LITERAL("attachments")).Append(uuid_string)); + base::FilePath file_path1( + report_attachments_dir.Append(FILE_PATH_LITERAL("file1"))); + base::FilePath file_path2( + report_attachments_dir.Append(FILE_PATH_LITERAL("file2"))); EXPECT_TRUE(FileExists(file_path1)); EXPECT_TRUE(FileExists(file_path1)); +#if defined(OS_WIN) + // On Windows, reports removed from metadata are counted, even if the file + // is not on the disk. + EXPECT_EQ(db()->CleanDatabase(0), 1); +#else EXPECT_EQ(db()->CleanDatabase(0), 0); +#endif EXPECT_FALSE(FileExists(file_path1)); EXPECT_FALSE(FileExists(file_path2)); EXPECT_FALSE(FileExists(report_attachments_dir)); -#endif } // This test uses knowledge of the database format to break it, so it only @@ -860,10 +867,6 @@ } TEST_F(CrashReportDatabaseTest, GetReportSize_RightSizeWithAttachments) { -#if defined(OS_APPLE) || defined(OS_WIN) - // Attachments aren't supported on Mac and Windows yet. - return; -#else std::unique_ptr<CrashReportDatabase::NewReport> new_report; ASSERT_EQ(db()->PrepareNewCrashReport(&new_report), CrashReportDatabase::kNoError); @@ -895,7 +898,6 @@ EXPECT_EQ(report.total_size, sizeof(main_report_data) + sizeof(attachment_1_data) + sizeof(attachment_2_data)); -#endif } } // namespace
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_win.cc b/third_party/crashpad/crashpad/client/crash_report_database_win.cc index f4ccbeb..65feaa4 100644 --- a/third_party/crashpad/crashpad/client/crash_report_database_win.cc +++ b/third_party/crashpad/crashpad/client/crash_report_database_win.cc
@@ -48,8 +48,6 @@ constexpr uint32_t kMetadataFileHeaderMagic = 'CPAD'; constexpr uint32_t kMetadataFileVersion = 1; -constexpr base::FilePath::CharType kAttachmentsDirectory[] = L"attachments"; - using OperationStatus = CrashReportDatabase::OperationStatus; // Helpers --------------------------------------------------------------------- @@ -216,8 +214,10 @@ //! handle. ~Metadata(); - static std::unique_ptr<Metadata> Create(const base::FilePath& metadata_file, - const base::FilePath& report_dir); + static std::unique_ptr<Metadata> Create( + const base::FilePath& metadata_file, + const base::FilePath& report_dir, + const base::FilePath& attachments_dir); //! \brief Adds a new report to the set. //! @@ -280,7 +280,9 @@ int CleanDatabase(); private: - Metadata(FileHandle handle, const base::FilePath& report_dir); + Metadata(FileHandle handle, + const base::FilePath& report_dir, + const base::FilePath& attachments_dir); bool Rewind(); @@ -298,6 +300,7 @@ ScopedFileHandle handle_; const base::FilePath report_dir_; + const base::FilePath attachments_dir_; bool dirty_; //! \brief `true` when a Write() is required on destruction. std::vector<ReportDisk> reports_; }; @@ -312,8 +315,10 @@ } // static -std::unique_ptr<Metadata> Metadata::Create(const base::FilePath& metadata_file, - const base::FilePath& report_dir) { +std::unique_ptr<Metadata> Metadata::Create( + const base::FilePath& metadata_file, + const base::FilePath& report_dir, + const base::FilePath& attachments_dir) { // It is important that dwShareMode be non-zero so that concurrent access to // this file results in a successful open. This allows us to get to LockFileEx // which then blocks to guard access. @@ -338,7 +343,8 @@ return std::unique_ptr<Metadata>(); } - std::unique_ptr<Metadata> metadata(new Metadata(handle, report_dir)); + std::unique_ptr<Metadata> metadata( + new Metadata(handle, report_dir, attachments_dir)); // If Read() fails, for whatever reason (corruption, etc.) metadata will not // have been modified and will be in a clean empty state. We continue on and // return an empty database to hopefully recover. This means that existing @@ -427,9 +433,14 @@ return removed; } -Metadata::Metadata(FileHandle handle, const base::FilePath& report_dir) - : handle_(handle), report_dir_(report_dir), dirty_(false), reports_() { -} +Metadata::Metadata(FileHandle handle, + const base::FilePath& report_dir, + const base::FilePath& attachments_dir) + : handle_(handle), + report_dir_(report_dir), + attachments_dir_(attachments_dir), + dirty_(false), + reports_() {} bool Metadata::Rewind() { FileOffset result = LoggingSeekFile(handle_.get(), 0, SEEK_SET); @@ -488,15 +499,10 @@ } ReportDisk report_disk(record, report_dir_, string_table); - // There are no attachments on Windows so the total size is the main - // report size. - struct _stati64 statbuf; - if (_wstat64(report_disk.file_path.value().c_str(), &statbuf) == 0) { - report_disk.total_size = statbuf.st_size; - } else { - LOG(ERROR) << "failed to stat report"; - } - + report_disk.total_size = GetFileSize(report_disk.file_path); + base::FilePath report_attachment_dir = + attachments_dir_.Append(report_disk.uuid.ToWString()); + report_disk.total_size += GetDirectorySize(report_attachment_dir); reports.push_back(report_disk); } } @@ -643,12 +649,7 @@ OperationStatus DeleteReport(const UUID& uuid) override; OperationStatus RequestUpload(const UUID& uuid) override; int CleanDatabase(time_t lockfile_ttl) override; - - // Build a filepath for the root attachments directory. - base::FilePath AttachmentsRootPath(); - - // Build a filepath for the directory for the report to hold attachments. - base::FilePath AttachmentsPath(const UUID& uuid); + base::FilePath DatabasePath() override; private: // CrashReportDatabase: @@ -659,10 +660,6 @@ // Cleans any attachments that have no associated report. void CleanOrphanedAttachments(); - // Attempt to remove any attachments associated with the given report UUID. - // There may not be any, so failing is not an error. - void RemoveAttachmentsByUUID(const UUID& uuid); - std::unique_ptr<Metadata> AcquireMetadata(); base::FilePath base_dir_; @@ -670,68 +667,6 @@ InitializationStateDcheck initialized_; }; -base::FilePath CrashReportDatabaseWin::AttachmentsRootPath() { - return base_dir_.Append(kAttachmentsDirectory); -} - -base::FilePath CrashReportDatabaseWin::AttachmentsPath(const UUID& uuid) { - const std::wstring uuid_string = uuid.ToWString(); - return base_dir_.Append(kAttachmentsDirectory).Append(uuid_string); -} - -FileWriter* CrashReportDatabase::NewReport::AddAttachment( - const std::string& name) { - auto database_win = static_cast<CrashReportDatabaseWin*>(database_); - base::FilePath attachments_root_dir = database_win->AttachmentsRootPath(); - base::FilePath attachments_dir = database_win->AttachmentsPath(uuid_); - if (!LoggingCreateDirectory( - attachments_root_dir, FilePermissions::kOwnerOnly, true) || - !LoggingCreateDirectory( - attachments_dir, FilePermissions::kOwnerOnly, true)) { - return nullptr; - } - - base::FilePath path = attachments_dir.Append(base::UTF8ToWide(name)); - - auto writer = std::make_unique<FileWriter>(); - if (!writer->Open( - path, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly)) { - LOG(ERROR) << "could not open " << path.value().c_str(); - return nullptr; - } - attachment_writers_.emplace_back(std::move(writer)); - attachment_removers_.emplace_back(ScopedRemoveFile(path)); - return attachment_writers_.back().get(); -} - -void CrashReportDatabase::UploadReport::InitializeAttachments() { - base::FilePath attachments_dir = - static_cast<CrashReportDatabaseWin*>(database_)->AttachmentsPath(uuid); - if (!IsDirectory(attachments_dir, /*allow_symlinks=*/false)) { - return; - } - DirectoryReader dir_reader; - if (!dir_reader.Open(attachments_dir)) { - return; - } - - base::FilePath filename; - DirectoryReader::Result dir_result; - while ((dir_result = dir_reader.NextFile(&filename)) == - DirectoryReader::Result::kSuccess) { - const base::FilePath filepath(attachments_dir.Append(filename)); - std::unique_ptr<FileReader> file_reader(std::make_unique<FileReader>()); - if (!file_reader->Open(filepath)) { - LOG(ERROR) << "attachment " << filepath.value().c_str() - << " couldn't be opened, skipping"; - continue; - } - attachment_readers_.emplace_back(std::move(file_reader)); - attachment_map_[base::WideToUTF8(filename.value())] = - attachment_readers_.back().get(); - } -} - CrashReportDatabaseWin::CrashReportDatabaseWin(const base::FilePath& path) : CrashReportDatabase(), base_dir_(path), settings_(), initialized_() {} @@ -753,6 +688,9 @@ if (!CreateDirectoryIfNecessary(base_dir_.Append(kReportsDirectory))) return false; + if (!CreateDirectoryIfNecessary(AttachmentsRootPath())) + return false; + if (!settings_.Initialize(base_dir_.Append(kSettings))) return false; @@ -760,6 +698,10 @@ return true; } +base::FilePath CrashReportDatabaseWin::DatabasePath() { + return base_dir_; +} + Settings* CrashReportDatabaseWin::GetSettings() { INITIALIZATION_STATE_DCHECK_VALID(initialized_); return &settings_; @@ -934,27 +876,6 @@ return kNoError; } -void CrashReportDatabaseWin::RemoveAttachmentsByUUID(const UUID& uuid) { - base::FilePath attachments_dir = AttachmentsPath(uuid); - if (!IsDirectory(attachments_dir, /*allow_symlinks=*/false)) { - return; - } - DirectoryReader reader; - if (!reader.Open(attachments_dir)) { - return; - } - - base::FilePath filename; - DirectoryReader::Result result; - while ((result = reader.NextFile(&filename)) == - DirectoryReader::Result::kSuccess) { - const base::FilePath filepath(attachments_dir.Append(filename)); - LoggingRemoveFile(filepath); - } - - LoggingRemoveDirectory(attachments_dir); -} - OperationStatus CrashReportDatabaseWin::SkipReportUpload( const UUID& uuid, Metrics::CrashSkippedReason reason) { @@ -977,7 +898,9 @@ std::unique_ptr<Metadata> CrashReportDatabaseWin::AcquireMetadata() { base::FilePath metadata_file = base_dir_.Append(kMetadataFileName); - return Metadata::Create(metadata_file, base_dir_.Append(kReportsDirectory)); + return Metadata::Create(metadata_file, + base_dir_.Append(kReportsDirectory), + AttachmentsRootPath()); } std::unique_ptr<CrashReportDatabase> InitializeInternal( @@ -1073,7 +996,7 @@ } void CrashReportDatabaseWin::CleanOrphanedAttachments() { - base::FilePath root_attachments_dir(base_dir_.Append(kAttachmentsDirectory)); + base::FilePath root_attachments_dir = AttachmentsRootPath(); DirectoryReader reader; if (!reader.Open(root_attachments_dir)) { return;
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_linux_test.cc b/third_party/crashpad/crashpad/client/crashpad_client_linux_test.cc index a17589a..a3ddc31 100644 --- a/third_party/crashpad/crashpad/client/crashpad_client_linux_test.cc +++ b/third_party/crashpad/crashpad/client/crashpad_client_linux_test.cc
@@ -147,6 +147,26 @@ 0); } +void ValidateExtraMemory(const ProcessSnapshotMinidump& minidump) { + // Verify that if we have an exception, then the code around the instruction + // pointer is included in the extra memory. + const ExceptionSnapshot* exception = minidump.Exception(); + if (exception == nullptr) + return; + uint64_t pc = exception->Context()->InstructionPointer(); + std::vector<const MemorySnapshot*> snippets = minidump.ExtraMemory(); + bool pc_found = false; + for (const MemorySnapshot* snippet : snippets) { + uint64_t start = snippet->Address(); + uint64_t end = start + snippet->Size(); + if (pc >= start && pc < end) { + pc_found = true; + break; + } + } + EXPECT_TRUE(pc_found); +} + void ValidateDump(const CrashReportDatabase::UploadReport* report) { ProcessSnapshotMinidump minidump_snapshot; ASSERT_TRUE(minidump_snapshot.Initialize(report->Reader())); @@ -164,6 +184,8 @@ #endif ValidateAttachment(report); + ValidateExtraMemory(minidump_snapshot); + for (const ModuleSnapshot* module : minidump_snapshot.Modules()) { for (const AnnotationSnapshot& annotation : module->AnnotationObjects()) { if (static_cast<Annotation::Type>(annotation.type) !=
diff --git a/third_party/crashpad/crashpad/client/ios_handler/exception_processor.mm b/third_party/crashpad/crashpad/client/ios_handler/exception_processor.mm index c54dd589..ce1f268 100644 --- a/third_party/crashpad/crashpad/client/ios_handler/exception_processor.mm +++ b/third_party/crashpad/crashpad/client/ios_handler/exception_processor.mm
@@ -377,6 +377,24 @@ return HANDLE_UNCAUGHT_NSEXCEPTION(exception, sinkhole); } } + + // Another set of iOS redacted sinkholes appear in CoreAutoLayout. + // However, this is often called by client code, so it's unsafe to simply + // handle an uncaught nsexception here. Instead, skip the frame and + // continue searching for either a handler that belongs to us, or another + // sinkhole. See: + // -[NSISEngine + // performModifications:withUnsatisfiableConstraintsHandler:]: + // -[NSISEngine withBehaviors:performModifications:] + // +[NSLayoutConstraintParser + // constraintsWithVisualFormat:options:metrics:views:]: + static constexpr const char* kCoreAutoLayoutSinkhole = + "/System/Library/PrivateFrameworks/CoreAutoLayout.framework/" + "CoreAutoLayout"; + if (ModulePathMatchesSinkhole(dl_info.dli_fname, + kCoreAutoLayoutSinkhole)) { + continue; + } } // Some <redacted> sinkholes are harder to find. _UIGestureEnvironmentUpdate
diff --git a/third_party/crashpad/crashpad/client/ios_handler/in_process_handler.cc b/third_party/crashpad/crashpad/client/ios_handler/in_process_handler.cc index 6e440bef..d57b5f2 100644 --- a/third_party/crashpad/crashpad/client/ios_handler/in_process_handler.cc +++ b/third_party/crashpad/crashpad/client/ios_handler/in_process_handler.cc
@@ -54,7 +54,10 @@ InProcessHandler::InProcessHandler() = default; InProcessHandler::~InProcessHandler() { - upload_thread_->Stop(); + if (upload_thread_started_ && upload_thread_) { + upload_thread_->Stop(); + } + prune_thread_->Stop(); } bool InProcessHandler::Initialize( @@ -225,13 +228,23 @@ } base::FilePath file; DirectoryReader::Result result; + + // Because the intermediate dump directory is expected to be shared, + // mitigate any spamming by limiting this to |kMaxPendingFiles|. + constexpr size_t kMaxPendingFiles = 20; + + // Track other application bundles separately, so they don't spam our + // intermediate dumps into never getting processed. + std::vector<base::FilePath> other_files; + while ((result = reader.NextFile(&file)) == DirectoryReader::Result::kSuccess) { // Don't try to process files marked as 'locked' from a different bundle id. - if (file.value().compare(0, + bool bundle_match = + file.value().compare(0, bundle_identifier_and_seperator_.size(), - bundle_identifier_and_seperator_) != 0 && - file.FinalExtension() == kLockedExtension) { + bundle_identifier_and_seperator_) == 0; + if (!bundle_match && file.FinalExtension() == kLockedExtension) { continue; } @@ -242,8 +255,19 @@ // Otherwise, include any other unlocked, or locked files matching // |bundle_identifier_and_seperator_|. - files.push_back(file); + if (bundle_match) { + files.push_back(file); + if (files.size() >= kMaxPendingFiles) + return files; + } else { + other_files.push_back(file); + } } + + auto end_iterator = + other_files.begin() + + std::min(kMaxPendingFiles - files.size(), other_files.size()); + files.insert(files.end(), other_files.begin(), end_iterator); return files; }
diff --git a/third_party/crashpad/crashpad/client/ios_handler/in_process_handler.h b/third_party/crashpad/crashpad/client/ios_handler/in_process_handler.h index 888337b..e586219 100644 --- a/third_party/crashpad/crashpad/client/ios_handler/in_process_handler.h +++ b/third_party/crashpad/crashpad/client/ios_handler/in_process_handler.h
@@ -180,7 +180,11 @@ } void SaveSnapshot(ProcessSnapshotIOSIntermediateDump& process_snapshot); + + // Process a maximum of 20 pending intermediate dumps. Dumps named with our + // bundle id get first priority to prevent spamming. std::vector<base::FilePath> PendingFiles(); + bool OpenNewFile(); void PostReportCleanup();
diff --git a/third_party/crashpad/crashpad/client/ios_handler/in_process_handler_test.cc b/third_party/crashpad/crashpad/client/ios_handler/in_process_handler_test.cc new file mode 100644 index 0000000..13dd366d --- /dev/null +++ b/third_party/crashpad/crashpad/client/ios_handler/in_process_handler_test.cc
@@ -0,0 +1,150 @@ +// Copyright 2021 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "client/ios_handler/in_process_handler.h" + +#include "gtest/gtest.h" +#include "test/scoped_temp_dir.h" +#include "test/test_paths.h" +#include "util/file/directory_reader.h" +#include "util/file/filesystem.h" + +namespace crashpad { +namespace test { +namespace { + +bool CreateFile(const base::FilePath& file) { + ScopedFileHandle fd(LoggingOpenFileForWrite( + file, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly)); + EXPECT_TRUE(fd.is_valid()); + return fd.is_valid(); +} + +class InProcessHandlerTest : public testing::Test { + protected: + // testing::Test: + + void SetUp() override { + ASSERT_TRUE( + in_process_handler_.Initialize(temp_dir_.path(), "", {}, system_data_)); + pending_dir_ = temp_dir_.path().Append("pending-serialized-ios-dump"); + bundle_identifier_and_seperator_ = system_data_.BundleIdentifier() + "@"; + } + + const auto& path() const { return pending_dir_; } + auto& handler() { return in_process_handler_; } + + void CreateFiles(int files, int other_files) { + base::FilePath::StringType file_prepend = + FILE_PATH_LITERAL(bundle_identifier_and_seperator_); + base::FilePath::StringType file_name = FILE_PATH_LITERAL("file"); + for (int i = 0; i < files; i++) { + std::string i_str = std::to_string(i); + base::FilePath file(file_prepend + file_name + i_str); + CreateFile(path().Append(file)); + } + + for (int i = 0; i < other_files; i++) { + std::string i_str = std::to_string(i); + base::FilePath file(file_name + i_str); + CreateFile(path().Append(file)); + } + } + + void VerifyRemainingFileCount(int expected_files_count, + int expected_other_files_count) { + DirectoryReader reader; + ASSERT_TRUE(reader.Open(path())); + DirectoryReader::Result result; + base::FilePath filename; + int files_count = 0; + int other_files_count = 0; + while ((result = reader.NextFile(&filename)) == + DirectoryReader::Result::kSuccess) { + bool bundle_match = + filename.value().compare(0, + bundle_identifier_and_seperator_.size(), + bundle_identifier_and_seperator_) == 0; + if (bundle_match) { + files_count++; + } else { + other_files_count++; + } + } + EXPECT_EQ(expected_files_count, files_count); + EXPECT_EQ(expected_other_files_count, other_files_count); + } + + void ClearFiles() { + DirectoryReader reader; + ASSERT_TRUE(reader.Open(path())); + DirectoryReader::Result result; + base::FilePath filename; + while ((result = reader.NextFile(&filename)) == + DirectoryReader::Result::kSuccess) { + LoggingRemoveFile(path().Append(filename)); + } + } + + private: + ScopedTempDir temp_dir_; + base::FilePath pending_dir_; + std::string bundle_identifier_and_seperator_; + internal::IOSSystemDataCollector system_data_; + internal::InProcessHandler in_process_handler_; +}; + +TEST_F(InProcessHandlerTest, TestPendingFileLimit) { + // Clear this first to blow away the pending file held by InProcessHandler. + ClearFiles(); + + // Only process other app files. + CreateFiles(0, 20); + handler().ProcessIntermediateDumps({}); + VerifyRemainingFileCount(0, 0); + ClearFiles(); + + // Only process our app files. + CreateFiles(20, 20); + handler().ProcessIntermediateDumps({}); + VerifyRemainingFileCount(0, 20); + ClearFiles(); + + // Process all of our files and 10 remaining. + CreateFiles(10, 30); + handler().ProcessIntermediateDumps({}); + VerifyRemainingFileCount(0, 20); + ClearFiles(); + + // Process 20 our files, leaving 10 remaining, and all other files remaining. + CreateFiles(30, 10); + handler().ProcessIntermediateDumps({}); + VerifyRemainingFileCount(10, 10); + ClearFiles(); + + CreateFiles(0, 0); + handler().ProcessIntermediateDumps({}); + VerifyRemainingFileCount(0, 0); + ClearFiles(); + + CreateFiles(10, 0); + handler().ProcessIntermediateDumps({}); + VerifyRemainingFileCount(0, 0); + ClearFiles(); + +} + +} // namespace +} // namespace test +} // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/prune_crash_reports_test.cc b/third_party/crashpad/crashpad/client/prune_crash_reports_test.cc index b989d2f..cce26aa 100644 --- a/third_party/crashpad/crashpad/client/prune_crash_reports_test.cc +++ b/third_party/crashpad/crashpad/client/prune_crash_reports_test.cc
@@ -69,6 +69,7 @@ (override)); MOCK_METHOD(OperationStatus, DeleteReport, (const UUID&), (override)); MOCK_METHOD(OperationStatus, RequestUpload, (const UUID&), (override)); + MOCK_METHOD(base::FilePath, DatabasePath, (), (override)); // Google Mock doesn't support mocking methods with non-copyable types such as // unique_ptr.
diff --git a/third_party/crashpad/crashpad/snapshot/BUILD.gn b/third_party/crashpad/crashpad/snapshot/BUILD.gn index fc2246a..225d3446 100644 --- a/third_party/crashpad/crashpad/snapshot/BUILD.gn +++ b/third_party/crashpad/crashpad/snapshot/BUILD.gn
@@ -128,6 +128,8 @@ if (crashpad_is_linux || crashpad_is_android) { sources += [ + "linux/capture_memory_delegate_linux.cc", + "linux/capture_memory_delegate_linux.h", "linux/cpu_context_linux.cc", "linux/cpu_context_linux.h", "linux/debug_rendezvous.cc",
diff --git a/third_party/crashpad/crashpad/snapshot/linux/capture_memory_delegate_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/capture_memory_delegate_linux.cc new file mode 100644 index 0000000..4f15874 --- /dev/null +++ b/third_party/crashpad/crashpad/snapshot/linux/capture_memory_delegate_linux.cc
@@ -0,0 +1,77 @@ +// Copyright 2021 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "snapshot/linux/capture_memory_delegate_linux.h" + +#include <utility> + +#include "base/numerics/safe_conversions.h" +#include "snapshot/memory_snapshot_generic.h" + +namespace crashpad { +namespace internal { + +CaptureMemoryDelegateLinux::CaptureMemoryDelegateLinux( + ProcessReaderLinux* process_reader, + const ProcessReaderLinux::Thread* thread_opt, + std::vector<std::unique_ptr<MemorySnapshotGeneric>>* snapshots, + uint32_t* budget_remaining) + : stack_(thread_opt ? thread_opt->stack_region_address : 0, + thread_opt ? thread_opt->stack_region_size : 0), + process_reader_(process_reader), + snapshots_(snapshots), + budget_remaining_(budget_remaining) {} + +bool CaptureMemoryDelegateLinux::Is64Bit() const { + return process_reader_->Is64Bit(); +} + +bool CaptureMemoryDelegateLinux::ReadMemory(uint64_t at, + uint64_t num_bytes, + void* into) const { + return process_reader_->Memory()->Read( + at, base::checked_cast<size_t>(num_bytes), into); +} + +std::vector<CheckedRange<uint64_t>> +CaptureMemoryDelegateLinux::GetReadableRanges( + const CheckedRange<uint64_t, uint64_t>& range) const { + return process_reader_->GetMemoryMap()->GetReadableRanges(range); +} + +void CaptureMemoryDelegateLinux::AddNewMemorySnapshot( + const CheckedRange<uint64_t, uint64_t>& range) { + // Don't bother storing this memory if it points back into the stack. + if (stack_.ContainsRange(range)) + return; + if (range.size() == 0) + return; + if (budget_remaining_ && *budget_remaining_ == 0) + return; + snapshots_->push_back(std::make_unique<internal::MemorySnapshotGeneric>()); + internal::MemorySnapshotGeneric* snapshot = snapshots_->back().get(); + snapshot->Initialize(process_reader_->Memory(), range.base(), range.size()); + if (budget_remaining_) { + if (!base::IsValueInRangeForNumericType<int64_t>(range.size())) { + *budget_remaining_ = 0; + } else { + int64_t temp = *budget_remaining_; + temp -= range.size(); + *budget_remaining_ = base::saturated_cast<uint32_t>(temp); + } + } +} + +} // namespace internal +} // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/linux/capture_memory_delegate_linux.h b/third_party/crashpad/crashpad/snapshot/linux/capture_memory_delegate_linux.h new file mode 100644 index 0000000..c0250b55 --- /dev/null +++ b/third_party/crashpad/crashpad/snapshot/linux/capture_memory_delegate_linux.h
@@ -0,0 +1,70 @@ +// Copyright 2021 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CRASHPAD_SNAPSHOT_LINUX_CAPTURE_MEMORY_DELEGATE_LINUX_H_ +#define CRASHPAD_SNAPSHOT_LINUX_CAPTURE_MEMORY_DELEGATE_LINUX_H_ + +#include "snapshot/capture_memory.h" + +#include <stdint.h> + +#include <memory> +#include <vector> + +#include "snapshot/linux/process_reader_linux.h" +#include "util/numeric/checked_range.h" + +namespace crashpad { +namespace internal { + +class MemorySnapshotGeneric; + +class CaptureMemoryDelegateLinux : public CaptureMemory::Delegate { + public: + //! \brief A MemoryCaptureDelegate for Linux. + //! + //! \param[in] process_reader A ProcessReaderLinux for the target process. + //! \param[in] thread_opt The thread being inspected. Memory ranges + //! overlapping this thread's stack will be ignored on the assumption + //! that they're already captured elsewhere. May be nullptr. + //! \param[in] snapshots A vector of MemorySnapshotGeneric to which the + //! captured memory will be added. + //! \param[in] budget_remaining If non-null, a pointer to the remaining number + //! of bytes to capture. If this is `0`, no further memory will be + //! captured. + CaptureMemoryDelegateLinux( + ProcessReaderLinux* process_reader, + const ProcessReaderLinux::Thread* thread_opt, + std::vector<std::unique_ptr<MemorySnapshotGeneric>>* snapshots, + uint32_t* budget_remaining); + + // MemoryCaptureDelegate: + bool Is64Bit() const override; + bool ReadMemory(uint64_t at, uint64_t num_bytes, void* into) const override; + std::vector<CheckedRange<uint64_t>> GetReadableRanges( + const CheckedRange<uint64_t, uint64_t>& range) const override; + void AddNewMemorySnapshot( + const CheckedRange<uint64_t, uint64_t>& range) override; + + private: + CheckedRange<uint64_t, uint64_t> stack_; + ProcessReaderLinux* process_reader_; // weak + std::vector<std::unique_ptr<MemorySnapshotGeneric>>* snapshots_; // weak + uint32_t* budget_remaining_; +}; + +} // namespace internal +} // namespace crashpad + +#endif // CRASHPAD_SNAPSHOT_LINUX_CAPTURE_MEMORY_DELEGATE_LINUX_H_
diff --git a/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc index cd40b3b..42d0eb0 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc +++ b/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc
@@ -17,6 +17,7 @@ #include <signal.h> #include "base/logging.h" +#include "snapshot/linux/capture_memory_delegate_linux.h" #include "snapshot/linux/cpu_context_linux.h" #include "snapshot/linux/process_reader_linux.h" #include "snapshot/linux/signal_context.h" @@ -332,6 +333,18 @@ INITIALIZATION_STATE_SET_INITIALIZING(initialized_); thread_id_ = thread_id; + const ProcessReaderLinux::Thread* thread = nullptr; + for (const auto& loop_thread : process_reader->Threads()) { + if (thread_id == loop_thread.tid) { + thread = &loop_thread; + break; + } + } + if (!thread) { + // This is allowed until {ProcessReaderLinux::InitializeThreads()} is + // improved to support target threads in the same thread group. + LOG(WARNING) << "thread ID " << thread_id << " not found in process"; + } if (process_reader->Is64Bit()) { if (!ReadContext<ContextTraits64>(process_reader, context_address) || @@ -345,6 +358,10 @@ } } + CaptureMemoryDelegateLinux capture_memory_delegate( + process_reader, thread, &extra_memory_, nullptr); + CaptureMemory::PointedToByContext(context_, &capture_memory_delegate); + INITIALIZATION_STATE_SET_VALID(initialized_); return true; } @@ -462,7 +479,12 @@ std::vector<const MemorySnapshot*> ExceptionSnapshotLinux::ExtraMemory() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return std::vector<const MemorySnapshot*>(); + std::vector<const MemorySnapshot*> result; + result.reserve(extra_memory_.size()); + for (const auto& em : extra_memory_) { + result.push_back(em.get()); + } + return result; } } // namespace internal
diff --git a/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.h b/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.h index c722ac7..1719f0b 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.h +++ b/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.h
@@ -25,6 +25,7 @@ #include "snapshot/exception_snapshot.h" #include "snapshot/linux/process_reader_linux.h" #include "snapshot/memory_snapshot.h" +#include "snapshot/memory_snapshot_generic.h" #include "util/linux/address_types.h" #include "util/misc/initialization_state_dcheck.h" @@ -91,6 +92,7 @@ } context_union_; CPUContext context_; std::vector<uint64_t> codes_; + std::vector<std::unique_ptr<internal::MemorySnapshotGeneric>> extra_memory_; uint64_t thread_id_; uint64_t exception_address_; uint32_t signal_number_;
diff --git a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc index 35f870e..53499b36 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc +++ b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc
@@ -41,6 +41,8 @@ system_.Initialize(&process_reader_, &snapshot_time_); + GetCrashpadOptionsInternal((&options_)); + InitializeThreads(); InitializeModules(); InitializeAnnotations(); @@ -100,7 +102,7 @@ auto exc_thread_snapshot = std::make_unique<internal::ThreadSnapshotLinux>(); - if (!exc_thread_snapshot->Initialize(&process_reader_, thread)) { + if (!exc_thread_snapshot->Initialize(&process_reader_, thread, nullptr)) { return false; } @@ -124,7 +126,11 @@ void ProcessSnapshotLinux::GetCrashpadOptions( CrashpadInfoClientOptions* options) { INITIALIZATION_STATE_DCHECK_VALID(initialized_); + *options = options_; +} +void ProcessSnapshotLinux::GetCrashpadOptionsInternal( + CrashpadInfoClientOptions* options) { CrashpadInfoClientOptions local_options; for (const auto& module : modules_) { @@ -262,10 +268,17 @@ void ProcessSnapshotLinux::InitializeThreads() { const std::vector<ProcessReaderLinux::Thread>& process_reader_threads = process_reader_.Threads(); + uint32_t* budget_remaining_pointer = nullptr; + uint32_t budget_remaining = options_.indirectly_referenced_memory_cap; + if (options_.gather_indirectly_referenced_memory == TriState::kEnabled) { + budget_remaining_pointer = &budget_remaining; + } for (const ProcessReaderLinux::Thread& process_reader_thread : process_reader_threads) { auto thread = std::make_unique<internal::ThreadSnapshotLinux>(); - if (thread->Initialize(&process_reader_, process_reader_thread)) { + if (thread->Initialize(&process_reader_, + process_reader_thread, + budget_remaining_pointer)) { threads_.push_back(std::move(thread)); } }
diff --git a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h index 62517bbf..285ee5d 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h +++ b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h
@@ -139,6 +139,9 @@ void InitializeModules(); void InitializeAnnotations(); + // Initializes options_ on behalf of Initialize(). + void GetCrashpadOptionsInternal(CrashpadInfoClientOptions* options); + std::map<std::string, std::string> annotations_simple_map_; timeval snapshot_time_; UUID report_id_; @@ -149,6 +152,7 @@ internal::SystemSnapshotLinux system_; ProcessReaderLinux process_reader_; ProcessMemoryRange memory_range_; + CrashpadInfoClientOptions options_; InitializationStateDcheck initialized_; };
diff --git a/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux_test.cc b/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux_test.cc index f3013b5..f5d26a1 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux_test.cc +++ b/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux_test.cc
@@ -47,7 +47,9 @@ uint64_t current_hz, max_hz; system.CPUFrequency(¤t_hz, &max_hz); - EXPECT_GE(max_hz, current_hz); + // For short-term loads, modern CPUs can boost single-core frequency beyond + // the advertised base clock. Let's assume this is no more than a factor 2. + EXPECT_GE(max_hz * 2, current_hz); int major, minor, bugfix; std::string build;
diff --git a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc index e3e2beb..f279e0ad 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc +++ b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc
@@ -17,6 +17,7 @@ #include <sched.h> #include "base/logging.h" +#include "snapshot/linux/capture_memory_delegate_linux.h" #include "snapshot/linux/cpu_context_linux.h" #include "util/misc/reinterpret_bytes.h" @@ -138,8 +139,10 @@ ThreadSnapshotLinux::~ThreadSnapshotLinux() {} -bool ThreadSnapshotLinux::Initialize(ProcessReaderLinux* process_reader, - const ProcessReaderLinux::Thread& thread) { +bool ThreadSnapshotLinux::Initialize( + ProcessReaderLinux* process_reader, + const ProcessReaderLinux::Thread& thread, + uint32_t* gather_indirectly_referenced_memory_bytes_remaining) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); #if defined(ARCH_CPU_X86_FAMILY) @@ -205,6 +208,13 @@ thread.static_priority, thread.sched_policy, thread.nice_value) : -1; + CaptureMemoryDelegateLinux capture_memory_delegate( + process_reader, + &thread, + &pointed_to_memory_, + gather_indirectly_referenced_memory_bytes_remaining); + CaptureMemory::PointedToByContext(context_, &capture_memory_delegate); + INITIALIZATION_STATE_SET_VALID(initialized_); return true; } @@ -240,7 +250,13 @@ } std::vector<const MemorySnapshot*> ThreadSnapshotLinux::ExtraMemory() const { - return std::vector<const MemorySnapshot*>(); + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + std::vector<const MemorySnapshot*> result; + result.reserve(pointed_to_memory_.size()); + for (const auto& pointed_to_memory : pointed_to_memory_) { + result.push_back(pointed_to_memory.get()); + } + return result; } } // namespace internal
diff --git a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h index 17a6668..40cd7e7 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h +++ b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h
@@ -47,8 +47,10 @@ //! //! \return `true` if the snapshot could be created, `false` otherwise with //! a message logged. - bool Initialize(ProcessReaderLinux* process_reader, - const ProcessReaderLinux::Thread& thread); + bool Initialize( + ProcessReaderLinux* process_reader, + const ProcessReaderLinux::Thread& thread, + uint32_t* gather_indirectly_referenced_memory_bytes_remaining); // ThreadSnapshot: @@ -81,6 +83,7 @@ pid_t thread_id_; int priority_; InitializationStateDcheck initialized_; + std::vector<std::unique_ptr<MemorySnapshotGeneric>> pointed_to_memory_; }; } // namespace internal
diff --git a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc index 4f85b77..db7e595 100644 --- a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc +++ b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc
@@ -117,8 +117,9 @@ if (!InitializeCrashpadInfo() || !InitializeMiscInfo() || !InitializeModules() || !InitializeSystemSnapshot() || - !InitializeMemoryInfo() || !InitializeThreads() || - !InitializeCustomMinidumpStreams() || !InitializeExceptionSnapshot()) { + !InitializeMemoryInfo() || !InitializeExtraMemory() || + !InitializeThreads() || !InitializeCustomMinidumpStreams() || + !InitializeExceptionSnapshot()) { return false; } @@ -234,8 +235,11 @@ std::vector<const MemorySnapshot*> ProcessSnapshotMinidump::ExtraMemory() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 - return std::vector<const MemorySnapshot*>(); + std::vector<const MemorySnapshot*> chunks; + for (const auto& chunk : extra_memory_) { + chunks.push_back(chunk.get()); + } + return chunks; } const ProcessMemory* ProcessSnapshotMinidump::Memory() const { @@ -502,6 +506,50 @@ return true; } +bool ProcessSnapshotMinidump::InitializeExtraMemory() { + const auto& stream_it = stream_map_.find(kMinidumpStreamTypeMemoryList); + if (stream_it == stream_map_.end()) { + return true; + } + + if (stream_it->second->DataSize < sizeof(MINIDUMP_MEMORY_LIST)) { + LOG(ERROR) << "memory_list size mismatch"; + return false; + } + + if (!file_reader_->SeekSet(stream_it->second->Rva)) { + return false; + } + + // MSVC won't let us stack-allocate a MINIDUMP_MEMORY_LIST because of its + // trailing zero-element array. Luckily we're only interested in its other + // field anyway: a uint32_t indicating the number of memory descriptors that + // follow. + static_assert( + sizeof(MINIDUMP_MEMORY_LIST) == 4, + "MINIDUMP_MEMORY_LIST's only actual field should be an uint32_t"); + uint32_t num_ranges; + if (!file_reader_->ReadExactly(&num_ranges, sizeof(num_ranges))) { + return false; + } + + // We have to manually keep track of the locations of the entries in the + // contiguous list of MINIDUMP_MEMORY_DESCRIPTORs, because the Initialize() + // function jumps around the file to find the contents of each snapshot. + FileOffset location = file_reader_->SeekGet(); + for (uint32_t i = 0; i < num_ranges; i++) { + extra_memory_.emplace_back( + std::make_unique<internal::MemorySnapshotMinidump>()); + if (!extra_memory_.back()->Initialize(file_reader_, + static_cast<RVA>(location))) { + return false; + } + location += sizeof(MINIDUMP_MEMORY_DESCRIPTOR); + } + + return true; +} + bool ProcessSnapshotMinidump::InitializeThreads() { const auto& stream_it = stream_map_.find(kMinidumpStreamTypeThreadList); if (stream_it == stream_map_.end()) {
diff --git a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h index f76956d..18fbc7c 100644 --- a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h +++ b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h
@@ -116,6 +116,10 @@ // Initialize(). bool InitializeMemoryInfo(); + // Initializes data carried in a MINIDUMP_MEMORY_LIST stream on behalf of + // Initialize(). + bool InitializeExtraMemory(); + // Initializes data carried in a MINIDUMP_SYSTEM_INFO stream on behalf of // Initialize(). bool InitializeSystemSnapshot(); @@ -147,6 +151,7 @@ std::vector<std::unique_ptr<internal::MemoryMapRegionSnapshotMinidump>> mem_regions_; std::vector<const MemoryMapRegionSnapshot*> mem_regions_exposed_; + std::vector<std::unique_ptr<internal::MemorySnapshotMinidump>> extra_memory_; std::vector<std::unique_ptr<MinidumpStream>> custom_streams_; MinidumpCrashpadInfo crashpad_info_; internal::SystemSnapshotMinidump system_snapshot_;
diff --git a/third_party/crashpad/crashpad/test/ios/crash_type_xctest.mm b/third_party/crashpad/crashpad/test/ios/crash_type_xctest.mm index c931796..529ca13e 100644 --- a/third_party/crashpad/crashpad/test/ios/crash_type_xctest.mm +++ b/third_party/crashpad/crashpad/test/ios/crash_type_xctest.mm
@@ -179,6 +179,16 @@ XCTAssertEqual([rootObject_ pendingReportCount], 0); } +- (void)testCrashCoreAutoLayoutSinkhole { + [rootObject_ crashCoreAutoLayoutSinkhole]; + [self verifyCrashReportException:crashpad::kMachExceptionFromNSException]; + NSDictionary* dict = [rootObject_ getAnnotations]; + XCTAssertTrue([[dict[@"objects"][0] valueForKeyPath:@"exceptionReason"] + containsString:@"Unable to activate constraint with anchors"]); + XCTAssertTrue([[dict[@"objects"][1] valueForKeyPath:@"exceptionName"] + isEqualToString:@"NSGenericException"]); +} + - (void)testRecursion { [rootObject_ crashRecursion]; [self verifyCrashReportException:SIGHUP];
diff --git a/third_party/crashpad/crashpad/test/ios/host/cptest_application_delegate.mm b/third_party/crashpad/crashpad/test/ios/host/cptest_application_delegate.mm index 6ff8378..44a7d88 100644 --- a/third_party/crashpad/crashpad/test/ios/host/cptest_application_delegate.mm +++ b/third_party/crashpad/crashpad/test/ios/host/cptest_application_delegate.mm
@@ -289,6 +289,18 @@ } } +- (void)crashCoreAutoLayoutSinkhole { + // EDO has its own sinkhole, so dispatch this away. + dispatch_async(dispatch_get_main_queue(), ^{ + UIView* unattachedView = [[UIView alloc] init]; + UIWindow* window = [UIApplication sharedApplication].windows[0]; + [NSLayoutConstraint activateConstraints:@[ + [window.rootViewController.view.bottomAnchor + constraintEqualToAnchor:unattachedView.bottomAnchor], + ]]; + }); +} + - (void)crashRecursion { recurse(0); }
diff --git a/third_party/crashpad/crashpad/test/ios/host/cptest_shared_object.h b/third_party/crashpad/crashpad/test/ios/host/cptest_shared_object.h index 4a78193..bcd7554 100644 --- a/third_party/crashpad/crashpad/test/ios/host/cptest_shared_object.h +++ b/third_party/crashpad/crashpad/test/ios/host/cptest_shared_object.h
@@ -73,6 +73,9 @@ // Trigger a caught NSException, this will not crash - (void)catchNSException; +// Trigger an NSException with sinkholes in CoreAutoLayout. +- (void)crashCoreAutoLayoutSinkhole; + // Trigger a crash with an infinite recursion. - (void)crashRecursion; @@ -84,6 +87,7 @@ // Trigger a crash after writing various annotations. - (void)crashWithAnnotations; + @end #endif // CRASHPAD_TEST_IOS_HOST_SHARED_OBJECT_H_
diff --git a/third_party/crashpad/crashpad/tools/generate_dump.cc b/third_party/crashpad/crashpad/tools/generate_dump.cc index e22f92a5..ab027b8 100644 --- a/third_party/crashpad/crashpad/tools/generate_dump.cc +++ b/third_party/crashpad/crashpad/tools/generate_dump.cc
@@ -49,6 +49,7 @@ #include "util/win/xp_compat.h" #elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) #include "snapshot/linux/process_snapshot_linux.h" +#include "util/linux/direct_ptrace_connection.h" #endif // OS_APPLE namespace crashpad { @@ -198,8 +199,12 @@ } #elif defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_ANDROID) // TODO(jperaza): https://crashpad.chromium.org/bug/30. + DirectPtraceConnection task; + if (!task.Initialize(options.pid)) { + return EXIT_FAILURE; + } ProcessSnapshotLinux process_snapshot; - if (!process_snapshot.Initialize(nullptr)) { + if (!process_snapshot.Initialize(&task)) { return EXIT_FAILURE; } #endif // OS_APPLE
diff --git a/third_party/crashpad/crashpad/util/file/filesystem.h b/third_party/crashpad/crashpad/util/file/filesystem.h index e12f127..e2affcc6 100644 --- a/third_party/crashpad/crashpad/util/file/filesystem.h +++ b/third_party/crashpad/crashpad/util/file/filesystem.h
@@ -111,6 +111,22 @@ //! \return `true` if the directory was removed. Otherwise, `false`. bool LoggingRemoveDirectory(const base::FilePath& path); +//! \brief Returns the size of the file at |filepath|. +//! The function will ignore symlinks (not follow them, not add them to +//! the returned size). +//! +//! \return The size of the file pointed by |filepath|. +uint64_t GetFileSize(const base::FilePath& filepath); + +//! \brief Returns the recursive sum of the size of the files in |dirPath|. +//! The function will ignore symlinks (not follow them, not add them to +//! the returned size). +//! +//! \param[in] dirPath The path to the directory +//! +//! \return The sum of the size of the files in |dirPath|. +uint64_t GetDirectorySize(const base::FilePath& dirPath); + } // namespace crashpad #endif // CRASHPAD_UTIL_FILE_FILESYSTEM_H_
diff --git a/third_party/crashpad/crashpad/util/file/filesystem_posix.cc b/third_party/crashpad/crashpad/util/file/filesystem_posix.cc index 60799eb..c413397 100644 --- a/third_party/crashpad/crashpad/util/file/filesystem_posix.cc +++ b/third_party/crashpad/crashpad/util/file/filesystem_posix.cc
@@ -22,6 +22,7 @@ #include "base/logging.h" #include "build/build_config.h" +#include "util/file/directory_reader.h" namespace crashpad { @@ -112,4 +113,38 @@ return true; } +uint64_t GetFileSize(const base::FilePath& filepath) { + if (!IsRegularFile(filepath)) { + return 0; + } + struct stat statbuf; + if (stat(filepath.value().c_str(), &statbuf) == 0) { + return statbuf.st_size; + } + PLOG(ERROR) << "stat " << filepath.value().c_str(); + return 0; +} + +uint64_t GetDirectorySize(const base::FilePath& dirpath) { + if (!IsDirectory(dirpath, /*allow_symlinks=*/false)) { + return 0; + } + DirectoryReader reader; + if (!reader.Open(dirpath)) { + return 0; + } + base::FilePath filename; + DirectoryReader::Result result; + uint64_t size = 0; + while ((result = reader.NextFile(&filename)) == + DirectoryReader::Result::kSuccess) { + const base::FilePath filepath(dirpath.Append(filename)); + if (IsDirectory(filepath, /*allow_symlinks=*/false)) { + size += GetDirectorySize(filepath); + } else { + size += GetFileSize(filepath); + } + } + return size; +} } // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/file/filesystem_test.cc b/third_party/crashpad/crashpad/util/file/filesystem_test.cc index 30cd0d12..9338cdc 100644 --- a/third_party/crashpad/crashpad/util/file/filesystem_test.cc +++ b/third_party/crashpad/crashpad/util/file/filesystem_test.cc
@@ -21,12 +21,15 @@ #include "test/errors.h" #include "test/filesystem.h" #include "test/scoped_temp_dir.h" +#include "util/file/file_writer.h" #include "util/misc/time.h" namespace crashpad { namespace test { namespace { +constexpr char kTestFileContent[] = "file_content"; + bool CurrentTime(timespec* now) { #if defined(OS_APPLE) timeval now_tv; @@ -471,6 +474,62 @@ #endif // !OS_FUCHSIA +TEST(Filesystem, GetFileSize) { + ScopedTempDir temp_dir; + base::FilePath filepath(temp_dir.path().Append(FILE_PATH_LITERAL("file"))); + FileWriter writer; + bool is_created = writer.Open( + filepath, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly); + ASSERT_TRUE(is_created); + writer.Write(kTestFileContent, sizeof(kTestFileContent)); + writer.Close(); + uint64_t filesize = GetFileSize(filepath); + EXPECT_EQ(filesize, sizeof(kTestFileContent)); + +#if !defined(OS_FUCHSIA) + // Create a link to a file. + base::FilePath link(temp_dir.path().Append(FILE_PATH_LITERAL("link"))); + ASSERT_TRUE(CreateSymbolicLink(filepath, link)); + uint64_t filesize_link = GetFileSize(link); + EXPECT_EQ(filesize_link, 0u); +#endif // !OS_FUCHSIA +} + +TEST(Filesystem, GetDirectorySize) { + ScopedTempDir temp_dir; + base::FilePath dir(temp_dir.path().Append(FILE_PATH_LITERAL("dir"))); + ASSERT_TRUE( + LoggingCreateDirectory(dir, FilePermissions::kWorldReadable, false)); + base::FilePath filepath1(temp_dir.path().Append(FILE_PATH_LITERAL("file"))); + FileWriter writer1; + bool is_created1 = writer1.Open( + filepath1, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly); + ASSERT_TRUE(is_created1); + writer1.Write(kTestFileContent, sizeof(kTestFileContent)); + writer1.Close(); + + base::FilePath filepath2(dir.Append(FILE_PATH_LITERAL("file"))); + FileWriter writer2; + bool is_created2 = writer2.Open( + filepath2, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly); + ASSERT_TRUE(is_created2); + writer2.Write(kTestFileContent, sizeof(kTestFileContent)); + writer2.Close(); + +#if !defined(OS_FUCHSIA) + // Create a link to a file. + base::FilePath link(dir.Append(FILE_PATH_LITERAL("link"))); + ASSERT_TRUE(CreateSymbolicLink(filepath2, link)); + + // Create a link to a dir. + base::FilePath linkdir(temp_dir.path().Append(FILE_PATH_LITERAL("link"))); + ASSERT_TRUE(CreateSymbolicLink(dir, linkdir)); +#endif // !OS_FUCHSIA + + uint64_t filesize = GetDirectorySize(temp_dir.path()); + EXPECT_EQ(filesize, 2 * sizeof(kTestFileContent)); +} + } // namespace } // namespace test } // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/file/filesystem_win.cc b/third_party/crashpad/crashpad/util/file/filesystem_win.cc index d0270fc6..8edb295 100644 --- a/third_party/crashpad/crashpad/util/file/filesystem_win.cc +++ b/third_party/crashpad/crashpad/util/file/filesystem_win.cc
@@ -19,6 +19,7 @@ #include "base/logging.h" #include "base/strings/utf_string_conversions.h" +#include "util/file/directory_reader.h" #include "util/misc/time.h" namespace crashpad { @@ -159,4 +160,40 @@ return LoggingRemoveDirectoryImpl(path); } +uint64_t GetFileSize(const base::FilePath& filepath) { + struct _stati64 statbuf; + if (!IsRegularFile(filepath)) { + return 0; + } + int ret_value = _wstat64(filepath.value().c_str(), &statbuf); + if (ret_value == 0) { + return statbuf.st_size; + } + PLOG(ERROR) << "stat " << filepath.value().c_str(); + return 0; +} + +uint64_t GetDirectorySize(const base::FilePath& dirpath) { + if (!IsDirectory(dirpath, /*allow_symlinks=*/false)) { + return 0; + } + DirectoryReader reader; + if (!reader.Open(dirpath)) { + return 0; + } + base::FilePath filename; + DirectoryReader::Result result; + uint64_t size = 0; + while ((result = reader.NextFile(&filename)) == + DirectoryReader::Result::kSuccess) { + const base::FilePath filepath(dirpath.Append(filename)); + if (IsDirectory(filepath, /*allow_symlinks=*/false)) { + size += GetDirectorySize(filepath); + } else { + size += GetFileSize(filepath); + } + } + return size; +} + } // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/linux/memory_map.cc b/third_party/crashpad/crashpad/util/linux/memory_map.cc index e15a1c5e..47eec97 100644 --- a/third_party/crashpad/crashpad/util/linux/memory_map.cc +++ b/third_party/crashpad/crashpad/util/linux/memory_map.cc
@@ -227,6 +227,12 @@ std::vector<MemoryMap::Mapping>::const_reverse_iterator rend_; }; +// Faster than a CheckedRange, for temporary values. +struct FastRange { + VMAddress base; + VMSize size; +}; + } // namespace MemoryMap::Mapping::Mapping() @@ -321,6 +327,57 @@ return nullptr; } +std::vector<CheckedRange<VMAddress>> MemoryMap::GetReadableRanges( + const CheckedRange<VMAddress, VMSize>& range) const { + using Range = CheckedRange<VMAddress, VMSize>; + + VMAddress range_base = range.base(); + VMAddress range_end = range.end(); + std::vector<FastRange> overlapping; + + // Find all readable ranges overlapping the target range, maintaining order. + for (const auto& mapping : mappings_) { + if (!mapping.readable) + continue; + if (mapping.range.End() < range_base) + continue; + if (mapping.range.Base() >= range_end) + continue; + // Special case: the "[vvar]" region is marked readable, but we can't + // access it. + if (mapping.inode == 0 && mapping.name == "[vvar]") + continue; + overlapping.push_back({mapping.range.Base(), mapping.range.Size()}); + } + if (overlapping.empty()) + return std::vector<Range>(); + + // For the first and last, trim to the boundary of the incoming range. + FastRange& front = overlapping.front(); + VMAddress original_front_base = front.base; + front.base = std::max(front.base, range_base); + front.size = (original_front_base + front.size) - front.base; + FastRange& back = overlapping.back(); + VMAddress back_end = back.base + back.size; + back.size = std::min(range_end, back_end) - back.base; + + // Coalesce, and convert to return type. + std::vector<Range> result; + result.push_back({overlapping[0].base, overlapping[0].size}); + DCHECK(result.back().IsValid()); + for (size_t i = 1; i < overlapping.size(); ++i) { + if (result.back().end() == overlapping[i].base) { + result.back().SetRange(result.back().base(), + result.back().size() + overlapping[i].size); + } else { + result.push_back({overlapping[i].base, overlapping[i].size}); + } + DCHECK(result.back().IsValid()); + } + + return result; +} + std::unique_ptr<MemoryMap::Iterator> MemoryMap::FindFilePossibleMmapStarts( const Mapping& mapping) const { INITIALIZATION_STATE_DCHECK_VALID(initialized_);
diff --git a/third_party/crashpad/crashpad/util/linux/memory_map.h b/third_party/crashpad/crashpad/util/linux/memory_map.h index f6f7cc8..2a542ebb 100644 --- a/third_party/crashpad/crashpad/util/linux/memory_map.h +++ b/third_party/crashpad/crashpad/util/linux/memory_map.h
@@ -77,6 +77,16 @@ //! it was obtained from. const Mapping* FindMappingWithName(const std::string& name) const; + //! \brief Given a range to be read from the target process, returns a vector + //! of ranges, representing the readable portions of the original range. + //! + //! \param[in] range The range being identified. + //! + //! \return A vector of ranges corresponding to the portion of \a range that + //! is readable based on the memory map. + std::vector<CheckedRange<uint64_t>> GetReadableRanges( + const CheckedRange<LinuxVMAddress, LinuxVMSize>& range) const; + //! \brief An abstract base class for iterating over ordered sets of mappings //! in a MemoryMap. class Iterator {
diff --git a/third_party/crashpad/crashpad/util/posix/signals.cc b/third_party/crashpad/crashpad/util/posix/signals.cc index b90e8f6..5df5a08d 100644 --- a/third_party/crashpad/crashpad/util/posix/signals.cc +++ b/third_party/crashpad/crashpad/util/posix/signals.cc
@@ -22,6 +22,10 @@ #include "base/cxx17_backports.h" #include "base/logging.h" +#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS) +#include <sys/syscall.h> +#endif + namespace crashpad { namespace { @@ -280,6 +284,21 @@ _exit(kFailureExitCode); } + // If we can raise a signal with siginfo on this platform, do so. This ensures + // that we preserve the siginfo information for asynchronous signals (i.e. + // signals that do not re-raise autonomously), such as signals delivered via + // kill() and asynchronous hardware faults such as SEGV_MTEAERR, which would + // otherwise be lost when re-raising the signal via raise(). +#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS) + int retval = syscall(SYS_rt_tgsigqueueinfo, + getpid(), + syscall(SYS_gettid), + siginfo->si_signo, + siginfo); + if (retval != 0) { + _exit(kFailureExitCode); + } +#else // Explicitly re-raise the signal if it will not re-raise itself. Because // signal handlers normally execute with their signal blocked, this raise() // cannot immediately deliver the signal. Delivery is deferred until the @@ -289,6 +308,7 @@ if (!WillSignalReraiseAutonomously(siginfo) && raise(sig) != 0) { _exit(kFailureExitCode); } +#endif // defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS) } // static
diff --git a/third_party/crashpad/crashpad/util/posix/signals_test.cc b/third_party/crashpad/crashpad/util/posix/signals_test.cc index 2bd5580..cb29ff5 100644 --- a/third_party/crashpad/crashpad/util/posix/signals_test.cc +++ b/third_party/crashpad/crashpad/util/posix/signals_test.cc
@@ -34,15 +34,48 @@ #include "test/scoped_temp_dir.h" #include "util/posix/scoped_mmap.h" +#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS) +#include <sys/auxv.h> +#include <sys/prctl.h> + +#if defined(ARCH_CPU_ARM64) +#ifndef HWCAP2_MTE +#define HWCAP2_MTE (1 << 18) +#endif +#ifndef SEGV_MTEAERR +#define SEGV_MTEAERR 8 +#endif +#ifndef PROT_MTE +#define PROT_MTE 0x20 +#endif +#ifndef PR_SET_TAGGED_ADDR_CTRL +#define PR_SET_TAGGED_ADDR_CTRL 55 +#endif +#ifndef PR_TAGGED_ADDR_ENABLE +#define PR_TAGGED_ADDR_ENABLE (1UL << 0) +#endif +#ifndef PR_MTE_TCF_ASYNC +#define PR_MTE_TCF_ASYNC (1UL << 2) +#endif +#endif // defined(ARCH_CPU_ARM64) +#endif // defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS) + namespace crashpad { namespace test { namespace { constexpr int kUnexpectedExitStatus = 3; +struct TestableSignal { + int sig, code; +}; + // Keep synchronized with CauseSignal(). -bool CanCauseSignal(int sig) { - return sig == SIGABRT || sig == SIGALRM || sig == SIGBUS || +std::vector<TestableSignal> TestableSignals() { + std::vector<TestableSignal> signals; + signals.push_back({SIGABRT, 0}); + signals.push_back({SIGALRM, 0}); + signals.push_back({SIGBUS, 0}); /* According to DDI0487D (Armv8 Architecture Reference Manual) the expected * behavior for division by zero (Section 3.4.8) is: "... results in a * zero being written to the destination register, without any @@ -50,24 +83,30 @@ * This applies to Armv8 (and not earlier) for both 32bit and 64bit app code. */ #if defined(ARCH_CPU_X86_FAMILY) - sig == SIGFPE || + signals.push_back({SIGFPE, 0}); #endif - #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARMEL) - sig == SIGILL || + signals.push_back({SIGILL, 0}); #endif // defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARMEL) - sig == SIGPIPE || sig == SIGSEGV || + signals.push_back({SIGPIPE, 0}); + signals.push_back({SIGSEGV, 0}); +#if (defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS)) && \ + defined(ARCH_CPU_ARM64) + if (getauxval(AT_HWCAP2) & HWCAP2_MTE) { + signals.push_back({SIGSEGV, SEGV_MTEAERR}); + } +#endif #if defined(OS_APPLE) - sig == SIGSYS || + signals.push_back({SIGSYS, 0}); #endif // OS_APPLE #if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM64) - sig == SIGTRAP || + signals.push_back({SIGTRAP, 0}); #endif // defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM64) - false; + return signals; } -// Keep synchronized with CanCauseSignal(). -void CauseSignal(int sig) { +// Keep synchronized with TestableSignals(). +void CauseSignal(int sig, int code) { switch (sig) { case SIGABRT: { abort(); @@ -164,8 +203,37 @@ } case SIGSEGV: { - volatile int* i = nullptr; - *i = 0; + switch (code) { + case 0: { + volatile int* i = nullptr; + *i = 0; + break; + } +#if (defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS)) && \ + defined(ARCH_CPU_ARM64) + case SEGV_MTEAERR: { + ScopedMmap mapping; + if (!mapping.ResetMmap(nullptr, + getpagesize(), + PROT_READ | PROT_WRITE | PROT_MTE, + MAP_PRIVATE | MAP_ANON, + -1, + 0)) { + _exit(kUnexpectedExitStatus); + } + if (prctl(PR_SET_TAGGED_ADDR_CTRL, + PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_ASYNC, + 0, + 0, + 0) != 0) { + _exit(kUnexpectedExitStatus); + } + mapping.addr_as<char*>()[1ULL << 56] = 0; + break; + } +#endif // (defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_CHROMEOS)) && + // defined(ARCH_CPU_ARM64) + } break; } @@ -218,9 +286,10 @@ }; static constexpr int kExitingHandlerExitStatus = 2; - SignalsTest(TestType test_type, SignalSource signal_source, int sig) + SignalsTest(TestType test_type, SignalSource signal_source, int sig, int code) : Multiprocess(), sig_(sig), + code_(code), test_type_(test_type), signal_source_(signal_source) {} @@ -299,7 +368,7 @@ switch (signal_source_) { case SignalSource::kCause: - CauseSignal(sig_); + CauseSignal(sig_, code_); break; case SignalSource::kRaise: raise(sig_); @@ -310,6 +379,7 @@ } int sig_; + int code_; TestType test_type_; SignalSource signal_source_; static Signals::OldActions old_actions_; @@ -352,32 +422,28 @@ } TEST(Signals, Cause_DefaultHandler) { - for (int sig = 1; sig < NSIG; ++sig) { - SCOPED_TRACE(base::StringPrintf("sig %d (%s)", sig, strsignal(sig))); - - if (!CanCauseSignal(sig)) { - continue; - } + for (TestableSignal s : TestableSignals()) { + SCOPED_TRACE(base::StringPrintf( + "sig %d (%s), code %d", s.sig, strsignal(s.sig), s.code)); SignalsTest test(SignalsTest::TestType::kDefaultHandler, SignalsTest::SignalSource::kCause, - sig); - test.SetExpectedChildTermination(Multiprocess::kTerminationSignal, sig); + s.sig, + s.code); + test.SetExpectedChildTermination(Multiprocess::kTerminationSignal, s.sig); test.Run(); } } TEST(Signals, Cause_HandlerExits) { - for (int sig = 1; sig < NSIG; ++sig) { - SCOPED_TRACE(base::StringPrintf("sig %d (%s)", sig, strsignal(sig))); - - if (!CanCauseSignal(sig)) { - continue; - } + for (TestableSignal s : TestableSignals()) { + SCOPED_TRACE(base::StringPrintf( + "sig %d (%s), code %d", s.sig, strsignal(s.sig), s.code)); SignalsTest test(SignalsTest::TestType::kHandlerExits, SignalsTest::SignalSource::kCause, - sig); + s.sig, + s.code); test.SetExpectedChildTermination(Multiprocess::kTerminationNormal, SignalsTest::kExitingHandlerExitStatus); test.Run(); @@ -385,32 +451,28 @@ } TEST(Signals, Cause_HandlerReraisesToDefault) { - for (int sig = 1; sig < NSIG; ++sig) { - SCOPED_TRACE(base::StringPrintf("sig %d (%s)", sig, strsignal(sig))); - - if (!CanCauseSignal(sig)) { - continue; - } + for (TestableSignal s : TestableSignals()) { + SCOPED_TRACE(base::StringPrintf( + "sig %d (%s), code %d", s.sig, strsignal(s.sig), s.code)); SignalsTest test(SignalsTest::TestType::kHandlerReraisesToDefault, SignalsTest::SignalSource::kCause, - sig); - test.SetExpectedChildTermination(Multiprocess::kTerminationSignal, sig); + s.sig, + s.code); + test.SetExpectedChildTermination(Multiprocess::kTerminationSignal, s.sig); test.Run(); } } TEST(Signals, Cause_HandlerReraisesToPrevious) { - for (int sig = 1; sig < NSIG; ++sig) { - SCOPED_TRACE(base::StringPrintf("sig %d (%s)", sig, strsignal(sig))); - - if (!CanCauseSignal(sig)) { - continue; - } + for (TestableSignal s : TestableSignals()) { + SCOPED_TRACE(base::StringPrintf( + "sig %d (%s), code %d", s.sig, strsignal(s.sig), s.code)); SignalsTest test(SignalsTest::TestType::kHandlerReraisesToPrevious, SignalsTest::SignalSource::kCause, - sig); + s.sig, + s.code); test.SetExpectedChildTermination(Multiprocess::kTerminationNormal, SignalsTest::kExitingHandlerExitStatus); test.Run(); @@ -427,7 +489,8 @@ SignalsTest test(SignalsTest::TestType::kDefaultHandler, SignalsTest::SignalSource::kRaise, - sig); + sig, + 0); test.SetExpectedChildTermination(Multiprocess::kTerminationSignal, sig); test.Run(); } @@ -443,7 +506,8 @@ SignalsTest test(SignalsTest::TestType::kHandlerExits, SignalsTest::SignalSource::kRaise, - sig); + sig, + 0); test.SetExpectedChildTermination(Multiprocess::kTerminationNormal, SignalsTest::kExitingHandlerExitStatus); test.Run(); @@ -475,7 +539,8 @@ SignalsTest test(SignalsTest::TestType::kHandlerReraisesToDefault, SignalsTest::SignalSource::kRaise, - sig); + sig, + 0); test.SetExpectedChildTermination(Multiprocess::kTerminationSignal, sig); test.Run(); } @@ -506,7 +571,8 @@ SignalsTest test(SignalsTest::TestType::kHandlerReraisesToPrevious, SignalsTest::SignalSource::kRaise, - sig); + sig, + 0); test.SetExpectedChildTermination(Multiprocess::kTerminationNormal, SignalsTest::kExitingHandlerExitStatus); test.Run();
diff --git a/third_party/dav1d/BUILD.gn b/third_party/dav1d/BUILD.gn index 967690a8..7b9fd8e4 100644 --- a/third_party/dav1d/BUILD.gn +++ b/third_party/dav1d/BUILD.gn
@@ -79,6 +79,10 @@ defines += [ "STACK_ALIGNMENT=$stack_alignment" ] } + if (!is_android && !is_win) { + defines += [ "HAVE_PTHREAD_GETAFFINITY_NP=1" ] + } + # Don't let dav1d export any symbols. Otherwise the verify_order step on macOS # can fail since these exports end up in the final Chromium binary. defines += [ "DAV1D_API=" ]
diff --git a/third_party/dav1d/config/linux-noasm/x64/config.h b/third_party/dav1d/config/linux-noasm/x64/config.h index 92a2bd8..26621ea5 100644 --- a/third_party/dav1d/config/linux-noasm/x64/config.h +++ b/third_party/dav1d/config/linux-noasm/x64/config.h
@@ -33,6 +33,8 @@ #define HAVE_POSIX_MEMALIGN 1 +// #define HAVE_PTHREAD_GETAFFINITY_NP 1 -- Controlled by Chomium + #define HAVE_UNISTD_H 1 // #define STACK_ALIGNMENT 32 -- Stack alignment is controlled by Chromium
diff --git a/third_party/dav1d/config/linux/arm/config.h b/third_party/dav1d/config/linux/arm/config.h index 7d2cfa2..0e41d72 100644 --- a/third_party/dav1d/config/linux/arm/config.h +++ b/third_party/dav1d/config/linux/arm/config.h
@@ -37,4 +37,6 @@ #define HAVE_POSIX_MEMALIGN 1 +// #define HAVE_PTHREAD_GETAFFINITY_NP 1 -- Controlled by Chomium + #define HAVE_UNISTD_H 1
diff --git a/third_party/dav1d/config/linux/arm64/config.h b/third_party/dav1d/config/linux/arm64/config.h index 603edd8..5843190 100644 --- a/third_party/dav1d/config/linux/arm64/config.h +++ b/third_party/dav1d/config/linux/arm64/config.h
@@ -37,4 +37,6 @@ #define HAVE_POSIX_MEMALIGN 1 +// #define HAVE_PTHREAD_GETAFFINITY_NP 1 -- Controlled by Chomium + #define HAVE_UNISTD_H 1
diff --git a/third_party/dav1d/config/linux/x64/config.asm b/third_party/dav1d/config/linux/x64/config.asm index cad44f1..b3456c10 100644 --- a/third_party/dav1d/config/linux/x64/config.asm +++ b/third_party/dav1d/config/linux/x64/config.asm
@@ -7,8 +7,6 @@ %define FORCE_VEX_ENCODING 0 -%define HAVE_AVX512ICL 1 - %define PIC 1 ; %define STACK_ALIGNMENT 32 -- Stack alignment is controlled by Chromium
diff --git a/third_party/dav1d/config/linux/x64/config.h b/third_party/dav1d/config/linux/x64/config.h index c5e455b8..0a8856e 100644 --- a/third_party/dav1d/config/linux/x64/config.h +++ b/third_party/dav1d/config/linux/x64/config.h
@@ -27,14 +27,14 @@ #define HAVE_ASM 1 -#define HAVE_AVX512ICL 1 - #define HAVE_CLOCK_GETTIME 1 #define HAVE_DLSYM 1 #define HAVE_POSIX_MEMALIGN 1 +// #define HAVE_PTHREAD_GETAFFINITY_NP 1 -- Controlled by Chomium + #define HAVE_UNISTD_H 1 // #define STACK_ALIGNMENT 32 -- Stack alignment is controlled by Chromium
diff --git a/third_party/dav1d/config/linux/x86/config.asm b/third_party/dav1d/config/linux/x86/config.asm index e53742c..df0a747 100644 --- a/third_party/dav1d/config/linux/x86/config.asm +++ b/third_party/dav1d/config/linux/x86/config.asm
@@ -7,8 +7,6 @@ %define FORCE_VEX_ENCODING 0 -%define HAVE_AVX512ICL 1 - %define PIC 1 ; %define STACK_ALIGNMENT 16 -- Stack alignment is controlled by Chromium
diff --git a/third_party/dav1d/config/linux/x86/config.h b/third_party/dav1d/config/linux/x86/config.h index 9869da9..f4a2486f 100644 --- a/third_party/dav1d/config/linux/x86/config.h +++ b/third_party/dav1d/config/linux/x86/config.h
@@ -27,14 +27,14 @@ #define HAVE_ASM 1 -#define HAVE_AVX512ICL 1 - #define HAVE_CLOCK_GETTIME 1 #define HAVE_DLSYM 1 #define HAVE_POSIX_MEMALIGN 1 +// #define HAVE_PTHREAD_GETAFFINITY_NP 1 -- Controlled by Chomium + #define HAVE_UNISTD_H 1 // #define STACK_ALIGNMENT 16 -- Stack alignment is controlled by Chromium
diff --git a/third_party/dav1d/config/win/arm64/config.h b/third_party/dav1d/config/win/arm64/config.h index cec842d7..12fcedf6 100644 --- a/third_party/dav1d/config/win/arm64/config.h +++ b/third_party/dav1d/config/win/arm64/config.h
@@ -29,8 +29,6 @@ #define HAVE_ASM 1 -#define HAVE_AVX512ICL 1 - #define HAVE_IO_H 1 // #define STACK_ALIGNMENT 16 -- Stack alignment is controlled by Chromium
diff --git a/third_party/dav1d/config/win/x64/config.asm b/third_party/dav1d/config/win/x64/config.asm index e112059..8581b132 100644 --- a/third_party/dav1d/config/win/x64/config.asm +++ b/third_party/dav1d/config/win/x64/config.asm
@@ -7,8 +7,6 @@ %define FORCE_VEX_ENCODING 0 -%define HAVE_AVX512ICL 1 - %define PIC 1 ; %define STACK_ALIGNMENT 16 -- Stack alignment is controlled by Chromium
diff --git a/third_party/dav1d/config/win/x64/config.h b/third_party/dav1d/config/win/x64/config.h index 111480e..abb7c55 100644 --- a/third_party/dav1d/config/win/x64/config.h +++ b/third_party/dav1d/config/win/x64/config.h
@@ -29,8 +29,6 @@ #define HAVE_ASM 1 -#define HAVE_AVX512ICL 1 - #define HAVE_IO_H 1 // #define STACK_ALIGNMENT 16 -- Stack alignment is controlled by Chromium
diff --git a/third_party/dav1d/config/win/x86/config.asm b/third_party/dav1d/config/win/x86/config.asm index 2dcc9f0..15e21ac 100644 --- a/third_party/dav1d/config/win/x86/config.asm +++ b/third_party/dav1d/config/win/x86/config.asm
@@ -7,8 +7,6 @@ %define FORCE_VEX_ENCODING 0 -%define HAVE_AVX512ICL 1 - %define PIC 1 %define PREFIX 1
diff --git a/third_party/dav1d/config/win/x86/config.h b/third_party/dav1d/config/win/x86/config.h index e96202c..1c62409 100644 --- a/third_party/dav1d/config/win/x86/config.h +++ b/third_party/dav1d/config/win/x86/config.h
@@ -29,8 +29,6 @@ #define HAVE_ASM 1 -#define HAVE_AVX512ICL 1 - #define HAVE_IO_H 1 #define PREFIX 1
diff --git a/third_party/dav1d/dav1d_generated.gni b/third_party/dav1d/dav1d_generated.gni index e6fffbfa..6dcea79 100644 --- a/third_party/dav1d/dav1d_generated.gni +++ b/third_party/dav1d/dav1d_generated.gni
@@ -18,20 +18,25 @@ "libdav1d/src/x86/ipred16_avx2.asm", "libdav1d/src/x86/ipred16_sse.asm", "libdav1d/src/x86/ipred_avx2.asm", + "libdav1d/src/x86/ipred_avx512.asm", "libdav1d/src/x86/ipred_sse.asm", "libdav1d/src/x86/itx16_avx2.asm", "libdav1d/src/x86/itx16_sse.asm", "libdav1d/src/x86/itx_avx2.asm", + "libdav1d/src/x86/itx_avx512.asm", "libdav1d/src/x86/itx_sse.asm", "libdav1d/src/x86/loopfilter16_avx2.asm", "libdav1d/src/x86/loopfilter16_sse.asm", "libdav1d/src/x86/loopfilter_avx2.asm", + "libdav1d/src/x86/loopfilter_avx512.asm", "libdav1d/src/x86/loopfilter_sse.asm", "libdav1d/src/x86/looprestoration16_avx2.asm", "libdav1d/src/x86/looprestoration16_sse.asm", "libdav1d/src/x86/looprestoration_avx2.asm", + "libdav1d/src/x86/looprestoration_avx512.asm", "libdav1d/src/x86/looprestoration_sse.asm", "libdav1d/src/x86/mc16_avx2.asm", + "libdav1d/src/x86/mc16_avx512.asm", "libdav1d/src/x86/mc16_sse.asm", "libdav1d/src/x86/mc_avx2.asm", "libdav1d/src/x86/mc_avx512.asm",
diff --git a/third_party/dav1d/generate_configs.py b/third_party/dav1d/generate_configs.py index 0e58dd6..e139e43e 100755 --- a/third_party/dav1d/generate_configs.py +++ b/third_party/dav1d/generate_configs.py
@@ -135,6 +135,10 @@ # platform's default stack alignment; https://crbug.com/928743. (r'(#define STACK_ALIGNMENT \d{1,2})', r'// \1 -- Stack alignment is controlled by Chromium'), + + # Android doesn't have pthread_getaffinity_np. + (r'(#define HAVE_PTHREAD_GETAFFINITY_NP \d{1,2})', + r'// \1 -- Controlled by Chomium'), ]) config_asm_path = os.path.join(temp_dir, 'config.asm')
diff --git a/third_party/dav1d/version/vcs_version.h b/third_party/dav1d/version/vcs_version.h index 0784689f..a0a39ce 100644 --- a/third_party/dav1d/version/vcs_version.h +++ b/third_party/dav1d/version/vcs_version.h
@@ -1,2 +1,2 @@ /* auto-generated, do not edit */ -#define DAV1D_VERSION "0.9.2-0-g7b433e0" +#define DAV1D_VERSION "0.9.2-64-g692c0ce"
diff --git a/third_party/dav1d/version/version.h b/third_party/dav1d/version/version.h index fec3ab80..a8bb98a 100644 --- a/third_party/dav1d/version/version.h +++ b/third_party/dav1d/version/version.h
@@ -27,8 +27,8 @@ #ifndef DAV1D_VERSION_H #define DAV1D_VERSION_H -#define DAV1D_API_VERSION_MAJOR 5 -#define DAV1D_API_VERSION_MINOR 1 -#define DAV1D_API_VERSION_PATCH 1 +#define DAV1D_API_VERSION_MAJOR 6 +#define DAV1D_API_VERSION_MINOR 0 +#define DAV1D_API_VERSION_PATCH 0 #endif /* DAV1D_VERSION_H */
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 3fca9fcf..9a13177d 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-168-gd31bafcb9 -Revision: d31bafcb9ce7dee7036089a394556ebf201221ec +Version: VER-2-11-0-170-ge4f7673e4 +Revision: e4f7673e46450298db1ce5fda8a3d310cfb50d78 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/third_party/gif_player/src/jp/tomorrowkey/android/gifplayer/BaseGifDrawable.java b/third_party/gif_player/src/jp/tomorrowkey/android/gifplayer/BaseGifDrawable.java index 08e3bd4..bc9fb18 100644 --- a/third_party/gif_player/src/jp/tomorrowkey/android/gifplayer/BaseGifDrawable.java +++ b/third_party/gif_player/src/jp/tomorrowkey/android/gifplayer/BaseGifDrawable.java
@@ -237,6 +237,14 @@ } } + /** + * Posts a RESET_DECODER request to the decoder thread so that the decoder starts decoding back + * from the start of the GIF. + */ + public void requestReset() { + sDecoderHandler.sendMessage(sDecoderHandler.obtainMessage(RESET_DECODER, this)); + } + @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); @@ -377,7 +385,7 @@ /** * Restarts decoding the image from the beginning. Called from the background thread. */ - protected void reset() { + private void reset() { // Return to the position of the first image frame in the stream. mPosition = mGifImage.mHeaderSize; mBackupSaved = false;
diff --git a/third_party/grpc/BUILD.gn b/third_party/grpc/BUILD.gn index a6f90bd..eae94dc 100644 --- a/third_party/grpc/BUILD.gn +++ b/third_party/grpc/BUILD.gn
@@ -51,6 +51,7 @@ cflags = [ "-Wno-implicit-fallthrough", "-Wno-shadow", + "-Wno-unreachable-code-return", ] if (is_android) { @@ -205,6 +206,7 @@ "src/include/grpc/event_engine/event_engine.h", "src/include/grpc/event_engine/internal/memory_allocator_impl.h", "src/include/grpc/event_engine/memory_allocator.h", + "src/include/grpc/event_engine/memory_request.h", "src/include/grpc/event_engine/port.h", "src/include/grpc/fork.h", "src/include/grpc/grpc.h", @@ -341,6 +343,7 @@ "src/include/grpcpp/security/credentials.h", "src/include/grpcpp/security/server_credentials.h", "src/include/grpcpp/security/tls_certificate_provider.h", + "src/include/grpcpp/security/tls_certificate_verifier.h", "src/include/grpcpp/security/tls_credentials_options.h", "src/include/grpcpp/server.h", "src/include/grpcpp/server_builder.h", @@ -695,7 +698,8 @@ "src/src/core/lib/debug/stats.h", "src/src/core/lib/debug/stats_data.h", "src/src/core/lib/debug/trace.h", - "src/src/core/lib/event_engine/endpoint_config_internal.h", + "src/src/core/lib/event_engine/channel_args_endpoint_config.h", + "src/src/core/lib/event_engine/event_engine_factory.h", "src/src/core/lib/event_engine/sockaddr.h", "src/src/core/lib/gpr/alloc.h", "src/src/core/lib/gpr/env.h", @@ -712,6 +716,7 @@ "src/src/core/lib/gprpp/bitset.h", "src/src/core/lib/gprpp/chunked_vector.h", "src/src/core/lib/gprpp/construct_destruct.h", + "src/src/core/lib/gprpp/cpp_impl_of.h", "src/src/core/lib/gprpp/debug_location.h", "src/src/core/lib/gprpp/dual_ref_counted.h", "src/src/core/lib/gprpp/examine_stack.h", @@ -758,7 +763,6 @@ "src/src/core/lib/iomgr/ev_posix.h", "src/src/core/lib/iomgr/event_engine/closure.h", "src/src/core/lib/iomgr/event_engine/endpoint.h", - "src/src/core/lib/iomgr/event_engine/iomgr.h", "src/src/core/lib/iomgr/event_engine/pollset.h", "src/src/core/lib/iomgr/event_engine/promise.h", "src/src/core/lib/iomgr/event_engine/resolved_address_internal.h", @@ -788,7 +792,6 @@ "src/src/core/lib/iomgr/python_util.h", "src/src/core/lib/iomgr/resolve_address.h", "src/src/core/lib/iomgr/resolve_address_custom.h", - "src/src/core/lib/iomgr/resource_quota.h", "src/src/core/lib/iomgr/sockaddr.h", "src/src/core/lib/iomgr/sockaddr_posix.h", "src/src/core/lib/iomgr/sockaddr_windows.h", @@ -820,6 +823,24 @@ # "src/src/core/lib/matchers/matchers.h", "src/src/core/lib/profiling/timers.h", + "src/src/core/lib/promise/activity.h", + "src/src/core/lib/promise/context.h", + "src/src/core/lib/promise/detail/basic_seq.h", + "src/src/core/lib/promise/detail/promise_factory.h", + "src/src/core/lib/promise/detail/promise_like.h", + "src/src/core/lib/promise/detail/status.h", + "src/src/core/lib/promise/detail/switch.h", + "src/src/core/lib/promise/exec_ctx_wakeup_scheduler.h", + "src/src/core/lib/promise/loop.h", + "src/src/core/lib/promise/map.h", + "src/src/core/lib/promise/poll.h", + "src/src/core/lib/promise/race.h", + "src/src/core/lib/promise/seq.h", + "src/src/core/lib/resource_quota/api.h", + "src/src/core/lib/resource_quota/memory_quota.h", + "src/src/core/lib/resource_quota/resource_quota.h", + "src/src/core/lib/resource_quota/thread_quota.h", + "src/src/core/lib/resource_quota/trace.h", "src/src/core/lib/security/authorization/authorization_engine.h", "src/src/core/lib/security/authorization/authorization_policy_provider.h", "src/src/core/lib/security/authorization/evaluate_args.h", @@ -847,6 +868,7 @@ "src/src/core/lib/security/credentials/ssl/ssl_credentials.h", "src/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h", "src/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h", + "src/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h", "src/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h", "src/src/core/lib/security/credentials/tls/tls_credentials.h", "src/src/core/lib/security/credentials/tls/tls_utils.h", @@ -938,7 +960,6 @@ "src/src/cpp/client/secure_credentials.h", "src/src/cpp/common/channel_filter.h", "src/src/cpp/common/secure_auth_context.h", - "src/src/cpp/common/tls_credentials_options_util.h", "src/src/cpp/server/dynamic_thread_pool.h", "src/src/cpp/server/external_connection_acceptor_impl.h", "src/src/cpp/server/health/default_health_check_service.h", @@ -1272,7 +1293,6 @@ "src/src/core/ext/upbdefs-generated/xds/type/v3/typed_struct.upbdefs.c", "src/src/core/lib/address_utils/parse_address.cc", "src/src/core/lib/address_utils/sockaddr_utils.cc", - "src/src/core/lib/avl/avl.cc", "src/src/core/lib/backoff/backoff.cc", "src/src/core/lib/channel/channel_args.cc", "src/src/core/lib/channel/channel_stack.cc", @@ -1295,8 +1315,10 @@ "src/src/core/lib/debug/stats.cc", "src/src/core/lib/debug/stats_data.cc", "src/src/core/lib/debug/trace.cc", - "src/src/core/lib/event_engine/endpoint_config.cc", + "src/src/core/lib/event_engine/channel_args_endpoint_config.cc", "src/src/core/lib/event_engine/event_engine.cc", + "src/src/core/lib/event_engine/event_engine_factory.cc", + "src/src/core/lib/event_engine/memory_allocator.cc", "src/src/core/lib/event_engine/sockaddr.cc", "src/src/core/lib/gpr/alloc.cc", "src/src/core/lib/gpr/atm.cc", @@ -1404,7 +1426,6 @@ "src/src/core/lib/iomgr/resolve_address_custom.cc", "src/src/core/lib/iomgr/resolve_address_posix.cc", "src/src/core/lib/iomgr/resolve_address_windows.cc", - "src/src/core/lib/iomgr/resource_quota.cc", "src/src/core/lib/iomgr/socket_factory_posix.cc", "src/src/core/lib/iomgr/socket_mutator.cc", "src/src/core/lib/iomgr/socket_utils_common_posix.cc", @@ -1446,6 +1467,11 @@ # "src/src/core/lib/matchers/matchers.cc", "src/src/core/lib/profiling/basic_timers.cc", "src/src/core/lib/profiling/stap_timers.cc", + "src/src/core/lib/promise/activity.cc", + "src/src/core/lib/resource_quota/api.cc", + "src/src/core/lib/resource_quota/memory_quota.cc", + "src/src/core/lib/resource_quota/resource_quota.cc", + "src/src/core/lib/resource_quota/thread_quota.cc", "src/src/core/lib/security/authorization/authorization_policy_provider_vtable.cc", "src/src/core/lib/security/authorization/evaluate_args.cc", "src/src/core/lib/security/authorization/sdk_server_authz_filter.cc", @@ -1480,6 +1506,7 @@ "src/src/core/lib/security/credentials/ssl/ssl_credentials.cc", "src/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc", "src/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc", + "src/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc", "src/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc", "src/src/core/lib/security/credentials/tls/tls_credentials.cc", "src/src/core/lib/security/credentials/tls/tls_utils.cc", @@ -1595,8 +1622,8 @@ "src/src/cpp/common/secure_channel_arguments.cc", "src/src/cpp/common/secure_create_auth_context.cc", "src/src/cpp/common/tls_certificate_provider.cc", + "src/src/cpp/common/tls_certificate_verifier.cc", "src/src/cpp/common/tls_credentials_options.cc", - "src/src/cpp/common/tls_credentials_options_util.cc", "src/src/cpp/common/validate_service_config.cc", "src/src/cpp/common/version_cc.cc", "src/src/cpp/server/async_generic_service.cc", @@ -1670,6 +1697,7 @@ "src/src/core/lib/iomgr/iomgr.cc", "src/src/core/lib/iomgr/pollset.cc", "src/src/core/lib/iomgr/timer.cc", + "src/src/core/lib/resource_quota/trace.cc", "src/src/core/lib/security/util/json_util.cc", "src/src/cpp/client/insecure_credentials.cc",
diff --git a/third_party/grpc/README.chromium b/third_party/grpc/README.chromium index 4e9cea2b..95cd8b8 100644 --- a/third_party/grpc/README.chromium +++ b/third_party/grpc/README.chromium
@@ -2,7 +2,7 @@ URL: https://github.com/grpc/grpc License: Apache 2.0 Version: v1.41.1+ -Revision: 1777ddf3c344f110323a625d75ff87c5ebc8d789 +Revision: da47e8823754d12f1dd643bc911e80703b557ade Security Critical: yes Please note that that the use of gRPC is not generally allowed within Chromium.
diff --git a/third_party/grpc/template/BUILD.chromium.gn.template b/third_party/grpc/template/BUILD.chromium.gn.template index bd7ebc4..91d88d6 100644 --- a/third_party/grpc/template/BUILD.chromium.gn.template +++ b/third_party/grpc/template/BUILD.chromium.gn.template
@@ -56,6 +56,7 @@ cflags = [ "-Wno-implicit-fallthrough", "-Wno-shadow", + "-Wno-unreachable-code-return", ] if (is_android) {
diff --git a/third_party/libvpx/README.chromium b/third_party/libvpx/README.chromium index b3c724af..07d1d5b 100644 --- a/third_party/libvpx/README.chromium +++ b/third_party/libvpx/README.chromium
@@ -6,9 +6,9 @@ License File: source/libvpx/LICENSE Security Critical: yes -Date: Tuesday October 12 2021 +Date: Wednesday November 10 2021 Branch: main -Commit: e259e6951d794ca6a6f2f3c9c40c5c99818613d3 +Commit: ec80f88c5d05539c89f8bda8df571b66cab9566d Description: Contains the sources used to compile libvpx binaries used by Google Chrome and
diff --git a/third_party/libvpx/source/config/vpx_version.h b/third_party/libvpx/source/config/vpx_version.h index 7889ab6..14b2974 100644 --- a/third_party/libvpx/source/config/vpx_version.h +++ b/third_party/libvpx/source/config/vpx_version.h
@@ -2,8 +2,8 @@ #define VERSION_MAJOR 1 #define VERSION_MINOR 11 #define VERSION_PATCH 0 -#define VERSION_EXTRA "21-ge259e6951" +#define VERSION_EXTRA "35-gec80f88c5" #define VERSION_PACKED \ ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH)) -#define VERSION_STRING_NOSP "v1.11.0-21-ge259e6951" -#define VERSION_STRING " v1.11.0-21-ge259e6951" +#define VERSION_STRING_NOSP "v1.11.0-35-gec80f88c5" +#define VERSION_STRING " v1.11.0-35-gec80f88c5"
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index dda65e3..e637420b 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -748,6 +748,7 @@ }, "ash/public/cpp/resources/ash_public_unscaled_resources.grd": { "includes": [4100], + "structures": [4101], }, "base/tracing/protos/resources.grd": { "includes": [4120],
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index e54166f8..825d2629 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -245,7 +245,7 @@ 'Afl Upload Linux ASan': 'afl_asan_shared_release_bot', 'ChromiumOS ASAN Release': 'chromeos_asan_lsan_fuzzer_v8_heap_release_bot', 'Libfuzzer Upload Chrome OS ASan': 'libfuzzer_chromeos_asan_release_bot', - 'Libfuzzer Upload iOS Catalyst Debug': 'ios_catalyst_debug_static_bot_compile_only_libfuzzer_no_lld_no_remoting', + 'Libfuzzer Upload iOS Catalyst Debug': 'ios_catalyst_debug_static_bot_compile_only_libfuzzer_no_dsyms_no_lld_no_remoting', 'Libfuzzer Upload Linux32 ASan': 'libfuzzer_asan_release_bot_x86', 'Libfuzzer Upload Linux32 ASan Debug': 'libfuzzer_asan_debug_bot_x86', 'Libfuzzer Upload Linux32 V8-ARM ASan': 'libfuzzer_asan_release_bot_x86_v8_arm', @@ -327,7 +327,7 @@ 'ios15-sdk-device': 'ios_device_release_static_bot_xctest', 'ios15-sdk-simulator': 'ios_simulator_debug_static_bot_xctest', 'ios-asan': 'ios_simulator_release_static_asan_bot_xctest', - 'ios-catalyst': 'ios_catalyst_debug_static_bot_compile_only_libfuzzer_no_lld_no_remoting', + 'ios-catalyst': 'ios_catalyst_debug_static_bot_compile_only_libfuzzer_no_dsyms_no_lld_no_remoting', 'ios-reclient': 'ios_simulator_debug_static_bot_xctest_reclient', 'ios-simulator-code-coverage': 'clang_code_coverage_ios_xctest', 'ios-simulator-cr-recipe': 'ios_simulator_debug_static_bot_xctest', @@ -1100,7 +1100,7 @@ 'gpu-fyi-try-mac-nvidia-retina-rel': 'gpu_fyi_tests_release_trybot', 'gpu-try-mac-amd-retina-dbg': 'gpu_tests_debug_bot', 'gpu-try-mac-intel-dbg': 'gpu_tests_debug_bot', - 'ios-catalyst': 'ios_catalyst_debug_static_bot_compile_only_libfuzzer_no_lld_no_remoting', + 'ios-catalyst': 'ios_catalyst_debug_static_bot_compile_only_libfuzzer_no_dsyms_no_lld_no_remoting', 'ios-device': 'ios_device_release_compile_only', 'ios14-beta-simulator': 'ios_simulator_debug_static_bot_xctest', 'ios14-sdk-simulator': 'ios_simulator_debug_static_bot_xctest_arm64', @@ -2314,7 +2314,7 @@ ], 'gpu_tests_wayland_release_bot_reclient': [ - 'gpu_tests', 'release_bot_reclient', 'linux_wayland', + 'gpu_tests', 'release_bot_reclient', 'linux_wayland', 'ozone_headless', ], 'gpu_tests_release_bot_minimal_symbols': [ @@ -2424,7 +2424,7 @@ 'gpu_tests_wayland_release_trybot_no_symbols_use_dummy_lastchange_code_coverage': [ 'gpu_tests', 'release_trybot', 'no_symbols', 'use_dummy_lastchange', - 'linux_wayland', + 'linux_wayland', 'ozone_headless', ], 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange_code_coverage_reclient': [ @@ -2457,8 +2457,8 @@ 'headless_shell', 'release', 'static', 'goma', ], - 'ios_catalyst_debug_static_bot_compile_only_libfuzzer_no_lld_no_remoting': [ - 'compile_only', 'debug_static_bot', 'ios', 'ios_build_chromium', 'ios_catalyst', 'ios_cpu_x64', 'ios_disable_xcode_project_generation', 'libfuzzer', 'no_lld', 'no_remoting', + 'ios_catalyst_debug_static_bot_compile_only_libfuzzer_no_dsyms_no_lld_no_remoting': [ + 'compile_only', 'debug_static_bot', 'ios', 'ios_build_chromium', 'ios_catalyst', 'ios_cpu_x64', 'ios_disable_xcode_project_generation', 'libfuzzer', 'no_dsyms', 'no_lld', 'no_remoting', ], 'ios_clang_tot_xctest': [ @@ -3679,6 +3679,10 @@ 'gn_args': 'com_init_check_hook_disabled=true', }, + 'no_dsyms': { + 'gn_args': 'enable_dsyms=false', + }, + 'no_goma': { 'gn_args': 'use_goma=false', }, @@ -3744,6 +3748,10 @@ 'gn_args': 'use_ozone=true', }, + 'ozone_headless': { + 'gn_args': 'ozone_platform_headless=true', + }, + 'linux_wayland': { 'gn_args': 'ozone_auto_platforms=false ozone_platform_wayland=true ozone_platform="wayland" use_bundled_weston=true', },
diff --git a/tools/mb/mb_config_expectations/chromium.fuzz.json b/tools/mb/mb_config_expectations/chromium.fuzz.json index 6c8903a..f0208b6b 100644 --- a/tools/mb/mb_config_expectations/chromium.fuzz.json +++ b/tools/mb/mb_config_expectations/chromium.fuzz.json
@@ -334,6 +334,7 @@ }, "Libfuzzer Upload iOS Catalyst Debug": { "gn_args": { + "enable_dsyms": false, "enable_remoting": false, "ios_set_attributes_for_xcode_project_generation": false, "is_component_build": false,
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index b30ca08f..56892b2 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -515,6 +515,7 @@ }, "ios-catalyst": { "gn_args": { + "enable_dsyms": false, "enable_remoting": false, "ios_set_attributes_for_xcode_project_generation": false, "is_component_build": false,
diff --git a/tools/mb/mb_config_expectations/chromium.linux.json b/tools/mb/mb_config_expectations/chromium.linux.json index 945c93213..e522f4d 100644 --- a/tools/mb/mb_config_expectations/chromium.linux.json +++ b/tools/mb/mb_config_expectations/chromium.linux.json
@@ -117,6 +117,7 @@ "is_debug": false, "ozone_auto_platforms": false, "ozone_platform": "wayland", + "ozone_platform_headless": true, "ozone_platform_wayland": true, "proprietary_codecs": true, "use_bundled_weston": true,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json index 8c801fc4..916f9cb 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
@@ -846,6 +846,7 @@ "is_debug": false, "ozone_auto_platforms": false, "ozone_platform": "wayland", + "ozone_platform_headless": true, "ozone_platform_wayland": true, "proprietary_codecs": true, "symbol_level": 0,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json index f58d3a64..d8054eb 100644 --- a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json +++ b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
@@ -226,6 +226,7 @@ }, "ios-catalyst": { "gn_args": { + "enable_dsyms": false, "enable_remoting": false, "ios_set_attributes_for_xcode_project_generation": false, "is_component_build": false,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c501657c..6aa3703 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -3194,6 +3194,7 @@ <int value="2" label="Launched From SuggestionChip"/> <int value="3" label="Launched From Shelf"/> <int value="4" label="Launched From SearchBox"/> + <int value="5" label="Launched From RecentApps"/> </enum> <enum name="AppListLaunchRecorderError"> @@ -63659,6 +63660,17 @@ <int value="1" label="Active other profiles."/> </enum> +<enum name="OptimizationGuideExecutionStatus"> + <int value="0" label="Unknown"/> + <int value="1" label="Success"/> + <int value="2" label="Pending"/> + <int value="3" label="ErrorInternalError"/> + <int value="4" label="ErrorModelFileNotAvailable"/> + <int value="5" label="ErrorModelFileNotValid"/> + <int value="6" label="ErrorEmptyOrInvalidInput"/> + <int value="7" label="ErrorUnknown"/> +</enum> + <enum name="OptimizationGuideHintCacheLevelDBStoreLoadMetadataResult"> <int value="0" label="Success"/> <int value="1" label="LoadMetadataFailed"/> @@ -69042,6 +69054,19 @@ <int value="3" label="kNotificationService"/> </enum> +<enum name="PrerenderCancelledUnknownInterface"> + <summary> + Enumerates names of Mojo interfaces. Work as supplementary information for + PrerenderCancelledInterface.kUnknown. See comments in + InterfaceNameHasher(content/browser/prerender/prerender_metrics.cc) for how + to update the enums. + </summary> + <int value="-2012727489" label="device.mojom.ScreenOrientation"/> + <int value="191605727" label="content.mojom.PepperHost"/> + <int value="1984681860" + label="chrome.mojom.OpenSearchDescriptionDocumentHandler"/> +</enum> + <enum name="PrerenderCookieSendType"> <obsolete> Deprecated March 13 2015. @@ -88547,9 +88572,9 @@ <enum name="VPNRemoteAuthenticationType"> <int value="0" label="OpenVPN Default"/> <int value="1" label="OpenVPN Certificate"/> - <int value="2" label="L2TP/IPSec Default"/> - <int value="3" label="L2TP/IPSec Certificate"/> - <int value="4" label="L2TP/IPSec PSK"/> + <int value="2" label="L2TP/IPsec Default"/> + <int value="3" label="L2TP/IPsec Certificate"/> + <int value="4" label="L2TP/IPsec PSK"/> </enum> <enum name="VPNUserAuthenticationType"> @@ -88557,9 +88582,10 @@ <int value="1" label="OpenVPN Certificate"/> <int value="2" label="OpenVPN Username/Password"/> <int value="3" label="OpenVPN Username/Password/OTP"/> - <int value="4" label="L2TP/IPSec None"/> - <int value="5" label="L2TP/IPSec Certificate"/> - <int value="6" label="L2TP/IPSec Username/Password"/> + <int value="4" label="L2TP/IPsec None"/> + <int value="5" label="L2TP/IPsec Certificate"/> + <int value="6" label="L2TP/IPsec Username/Password"/> + <int value="7" label="OpenVPN Username/Token"/> </enum> <enum name="VPNWireGuardAllowedIPsType">
diff --git a/tools/metrics/histograms/metadata/memory/histograms.xml b/tools/metrics/histograms/metadata/memory/histograms.xml index a5d3308..906b3c4 100644 --- a/tools/metrics/histograms/metadata/memory/histograms.xml +++ b/tools/metrics/histograms/metadata/memory/histograms.xml
@@ -2593,6 +2593,41 @@ </summary> </histogram> +<histogram name="Memory.RenderProcessHost.Count.OriginAgentClusterOverhead" + units="processes" expires_after="2022-09-28"> + <owner>wjmaclean@chromium.org</owner> + <owner>alexmos@chromium.org</owner> + <owner>creis@chromium.org</owner> + <summary> + An estimate of additional processes created due to OriginAgentCluster (OAC). + Computed assuming no coalescing of multiple BrowsingInstances into a single + RenderProcess (including no subframe process reuse), and only when + cross-process origin isolation occurs due to the OAC header. Given this, the + count of additional SiteInstances corresponds exactly to the additional + number of RenderProcesses that OAC gives rise to, and therefore gives a + sense of how much process count overhead it creates. Recorded once per UMA + ping. + </summary> +</histogram> + +<histogram name="Memory.RenderProcessHost.Percent.OriginAgentClusterOverhead" + units="%" expires_after="2022-09-28"> + <owner>wjmaclean@chromium.org</owner> + <owner>alexmos@chromium.org</owner> + <owner>creis@chromium.org</owner> + <summary> + The percentage of the total renderer process count that is due to the + OriginAgentCluster (OAC) header, based on the overhead estimate from + Memory.RenderProcessHost.Count.OriginAgentClusterProcesses. That value is + computed assuming no coalescing of multiple BrowsingInstances into a single + RenderProcess (including no subframe process reuse), and only when + cross-process origin isolation occurs due to the OAC header. Given this, the + percentage of total SiteInstances due to the OAC header corresponds exactly + to the percentage of RenderProcesses that OAC gives rise to. Recorded once + per UMA ping. + </summary> +</histogram> + <histogram name="Memory.ShmemDir.AmountOfFreeSpace" units="MB" expires_after="M77"> <owner>reveman@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml index 0dc0b93..9b6d560b 100644 --- a/tools/metrics/histograms/metadata/navigation/histograms.xml +++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -1601,6 +1601,32 @@ </summary> </histogram> +<histogram name="Prerender.Experimental.PrerenderCancelledUnknownInterface" + enum="PrerenderCancelledUnknownInterface" expires_after="2022-01-27"> + <owner>nhiroki@chromium.org</owner> + <owner>toyoshim@chromium.org</owner> + <owner>lingqi@chromium.org</owner> + <summary> + This histogram tracks the interfaces that + Prerender.Experimental.PrerenderCancelledInterface fails to track. It is + needed because: + + * Embedders can set their own policies, so Prerender2 cannot map all of them + to enums. + + * Channel-associated interfaces' policies are set to kCancel implicitly. + It's hard to track all of them, especially the newly added + channel-associated interfaces. + + This sparse histogram allows Prerender2 to record all of these interfaces + separately. + + It is recored by MojoBinderPolicyApplier in the browser process once it + receives the binding request of a kCancel Mojo interface and cannot find an + accurate enum type for this interface. + </summary> +</histogram> + <histogram name="Prerender.Experimental.PrerenderHostCancelReasonBeforeActivation" enum="PrerenderHostFinalStatus" expires_after="2021-08-06">
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml index d2eff4e..dda50d78 100644 --- a/tools/metrics/histograms/metadata/net/histograms.xml +++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -2400,10 +2400,9 @@ </histogram> <histogram name="Net.NetworkErrorLogging.SignedExchangeRequestOutcome" - enum="NetNetworkErrorLoggingRequestOutcome" expires_after="M99"> - <owner>horo@chromium.org</owner> + enum="NetNetworkErrorLoggingRequestOutcome" expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> When Network Error Logging observes a completed request of signed exchange that might generate a report, what happens to it. NEL observes all requests,
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml index d82657d..3e26dac 100644 --- a/tools/metrics/histograms/metadata/optimization/histograms.xml +++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -351,6 +351,19 @@ </histogram> <histogram + name="OptimizationGuide.ModelExecutor.ExecutionStatus.{OptimizationTarget}" + enum="OptimizationGuideExecutionStatus" expires_after="M106"> + <owner>robertogden@chromium.org</owner> + <owner>chrome-intelligence-core@google.com</owner> + <summary> + Records the result of attempting to execute a {OptimizationTarget} model, + including loading the file from disk. Recorded once per model execution + attempt for {OptimizationTarget}. + </summary> + <token key="OptimizationTarget" variants="OptimizationTarget"/> +</histogram> + +<histogram name="OptimizationGuide.ModelExecutor.ModelAvailableToLoad.{OptimizationTarget}" enum="BooleanAvailable" expires_after="M106"> <owner>robertogden@chromium.org</owner> @@ -383,6 +396,9 @@ <histogram name="OptimizationGuide.ModelExecutor.ModelLoadingResult.{OptimizationTarget}" enum="ModelExecutorLoadingState" expires_after="M106"> + <obsolete> + Removed in favor of OptimizationGuide.ModelExecutor.ExecutionStatus in M98. + </obsolete> <owner>mcrouse@chromium.org</owner> <owner>chrome-intelligence-core@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index 083fabb7..ee1ebb5 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -14966,10 +14966,9 @@ </histogram> <histogram name="SignedExchange.CertificateFetch.CacheHit" - enum="BooleanCacheHit" expires_after="M99"> + enum="BooleanCacheHit" expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Records if the fetched Signed Exchange certchain was served from HTTP cache or not. @@ -14977,30 +14976,27 @@ </histogram> <histogram name="SignedExchange.CertVerificationResult" enum="NetErrorCodes" - expires_after="M99"> + expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Reports the result of Signed Exchange cert verification, including success. </summary> </histogram> <histogram name="SignedExchange.CTVerificationResult" enum="CTComplianceStatus" - expires_after="M99"> + expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Reports the result of Signed Exchange CT verification, including success. </summary> </histogram> <histogram name="SignedExchange.FallbackRedirectLoop" enum="BooleanDetected" - expires_after="M99"> + expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Records true when a fallback redirect of Signed Exchange has failed with ERR_TO_MANY_REDIRECTS. @@ -15011,10 +15007,9 @@ </histogram> <histogram name="SignedExchange.LoadResult2" enum="SignedExchangeLoadResult" - expires_after="2022-04-03"> + expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Records the result of loading a resource from Signed HTTP Exchange. Emitted each time a response is handled as Signed Exchange. @@ -15022,10 +15017,9 @@ </histogram> <histogram name="SignedExchange.OCSPResponseStatus" enum="OCSPResponseStatus" - expires_after="M99"> + expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> The status of OCSP response in Signed Exchange certificates. Reported each time Signed Exchange's OCSP check is performed. @@ -15033,10 +15027,9 @@ </histogram> <histogram name="SignedExchange.OCSPRevocationStatus" - enum="OCSPRevocationStatus" expires_after="M99"> + enum="OCSPRevocationStatus" expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Reports the revocation status of OCSP response in Signed Exchange certificates. Emitted when Signed Exchange's OCSP check is performed, but @@ -15045,10 +15038,9 @@ </histogram> <histogram name="SignedExchange.Prefetch.LoadResult2" - enum="SignedExchangeLoadResult" expires_after="M99"> - <owner>kinuko@chromium.org</owner> + enum="SignedExchangeLoadResult" expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Records if the prefetched Signed Exchange was properly formatted and passed verification steps. Reported for each completed SignedExchange prefetch. @@ -15056,10 +15048,9 @@ </histogram> <histogram name="SignedExchange.Prefetch.Precision.30Seconds" - enum="BooleanUsage" expires_after="M99"> - <owner>kinuko@chromium.org</owner> + enum="BooleanUsage" expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Records if the prefetched Signed Exchange was actually the target of a navigation which happened within 30 seconds. Reported when a corresponding @@ -15069,10 +15060,9 @@ </histogram> <histogram name="SignedExchange.Prefetch.Recall.30Seconds" enum="BooleanUsage" - expires_after="M99"> - <owner>kinuko@chromium.org</owner> + expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Records how much Signed Exchange navigations were prefetched and not prefetched. Matched against 30 seconds window. Reported for each Signed @@ -15081,10 +15071,9 @@ </histogram> <histogram name="SignedExchange.SignatureVerificationError.Expired" - units="seconds" expires_after="M99"> - <owner>kinuko@chromium.org</owner> + units="seconds" expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Recorded when Signed Exchange signature was expired. Records the time delta between current time and signature's "expires" value. @@ -15092,10 +15081,9 @@ </histogram> <histogram name="SignedExchange.SignatureVerificationError.NotYetValid" - units="seconds" expires_after="M99"> + units="seconds" expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Recorded when Signed Exchange signature was not yet valid. Records the time delta between current time and signature's "date" value. @@ -15103,10 +15091,9 @@ </histogram> <histogram name="SignedExchange.SignatureVerificationResult" - enum="SignedExchangeSignatureVerificationResult" expires_after="M99"> - <owner>kinuko@chromium.org</owner> + enum="SignedExchangeSignatureVerificationResult" expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Reports the result of Signed Exchange signature verification, including success. @@ -15114,10 +15101,9 @@ </histogram> <histogram name="SignedExchange.Time.CertificateFetch.Failure" units="ms" - expires_after="M99"> + expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> The amount of time elapsed to fetch certificate chain from certUrl, for which the fetch has failed. @@ -15125,10 +15111,9 @@ </histogram> <histogram name="SignedExchange.Time.CertificateFetch.Success" units="ms" - expires_after="M99"> + expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> The amount of time elapsed to fetch certificate chain from certUrl, for which the fetch has succeeded. @@ -15136,10 +15121,9 @@ </histogram> <histogram name="SignedExchange.Time.SignatureVerify" units="ms" - expires_after="M99"> + expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>kinuko@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> The amount of time that elapsed during SignedExchangeSignatureVerifier::Verify. @@ -15147,10 +15131,9 @@ </histogram> <histogram name="SignedExchange.TimeUntilExpiration" units="seconds" - expires_after="M99"> - <owner>kinuko@chromium.org</owner> + expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> Number of seconds until the Signed Exchange's expiration time. Recorded when Signed Exchange signature verification is performed, and emitted only for @@ -15159,10 +15142,9 @@ </histogram> <histogram name="SignedExchange.ValidityPingDuration" units="ms" - expires_after="M99"> - <owner>kinuko@chromium.org</owner> + expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary> The amount of time elapsed to ping the original publisher of the Signed Exchanges. @@ -15170,10 +15152,9 @@ </histogram> <histogram name="SignedExchange.ValidityPingResult" - enum="SignedExchangeValidityPingResult" expires_after="M99"> - <owner>kinuko@chromium.org</owner> + enum="SignedExchangeValidityPingResult" expires_after="2022-05-17"> <owner>ksakamoto@chromium.org</owner> - <owner>horo@chromium.org</owner> + <owner>webpackage-dev@chromium.org</owner> <summary>Reports the result of the Signed Exchange validity ping.</summary> </histogram>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 607e2b7e..f0831bb7 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": "00048704ddeb487897201c27844b446b7858bf89", - "remote_path": "perfetto_binaries/trace_processor_shell/win/faacbdad8d522af7b85ec400f4ee3596543579f2/trace_processor_shell.exe" + "hash": "db1ea5513a9b0265050df2914505b26d14f61c94", + "remote_path": "perfetto_binaries/trace_processor_shell/win/f890ec27af91a43e1f0ca7795a902ef972590c5f/trace_processor_shell.exe" }, "mac": { - "hash": "ac95d55afcebef81ece5cc7170878c6b6728f64c", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/faacbdad8d522af7b85ec400f4ee3596543579f2/trace_processor_shell" + "hash": "aece35d86d1d8ca96758b47cab36fd2afaf72524", + "remote_path": "perfetto_binaries/trace_processor_shell/mac/f890ec27af91a43e1f0ca7795a902ef972590c5f/trace_processor_shell" }, "linux_arm64": { "hash": "5074025a2898ec41a872e70a5719e417acb0a380", "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "linux": { - "hash": "462b2a670ffa33004e835d5f955cd2be996449c0", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/46ca7fc784a7fc642396b5fd0c7fba70eded9ed7/trace_processor_shell" + "hash": "1af51df53e0241e511be2449310b3696a87f9cf9", + "remote_path": "perfetto_binaries/trace_processor_shell/linux/f890ec27af91a43e1f0ca7795a902ef972590c5f/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/perf/run_benchmark b/tools/perf/run_benchmark index e7d129c..45f0f94 100755 --- a/tools/perf/run_benchmark +++ b/tools/perf/run_benchmark
@@ -1,4 +1,4 @@ -#!/usr/bin/env vpython +#!/usr/bin/env vpython3 # Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/security/idn_test_case_generator.py b/tools/security/idn_test_case_generator.py index a1c0dd0..54e38ee 100755 --- a/tools/security/idn_test_case_generator.py +++ b/tools/security/idn_test_case_generator.py
@@ -17,58 +17,28 @@ def str_to_c_string(string): - """Converts a Python str (ASCII) to a C string literal. + """Converts a Python bytes to a C++ string literal. - >>> str_to_c_string('abc\x8c') + >>> str_to_c_string(b'abc\x8c') '"abc\\\\x8c"' """ - return repr(string).replace("'", '"') + return repr(string).replace("'", '"').removeprefix('b') -def ishexdigit(c): - """ - >>> ishexdigit('0') - True - >>> ishexdigit('9') - True - >>> ishexdigit('/') - False - >>> ishexdigit(':') - False - >>> ishexdigit('a') - True - >>> ishexdigit('f') - True - >>> ishexdigit('g') - False - >>> ishexdigit('A') - True - >>> ishexdigit('F') - True - >>> ishexdigit('G') - False +def unicode_to_c_ustring(string): + """Converts a Python unicode string to a C++ u16-string literal. + + >>> unicode_to_c_ustring(u'b\u00fccher.de') + 'u"b\\\\u00fccher.de"' """ - return c.isdigit() or ord('a') <= ord(c.lower()) <= ord('f') - - -def unicode_to_c_wstring(string): - """Converts a Python str or unicode to a C wide-string literal. - - >>> unicode_to_c_wstring(u'b\u00fccher.de') - 'L"b\\\\x00fc" L"cher.de"' - """ - result = ['L"'] + result = ['u"'] for c in string: - # If the previous character was \x-escaped, and the next character is a - # hex digit, we need to end and restart the string literal. Otherwise, - # the next character will extend the \x escape sequence. - if result[-1].startswith('\\x') and ishexdigit(c): - result.append('" L"') - escaped = repr(c)[2:-1] - # Convert '\u' to '\x', and also force a minimum of 4 digits (this isn't - # necessary but is preferred style for these test cases). - if escaped[:2] in ('\\x', '\\u'): - escaped = '\\x%04x' % ord(c) + if (ord(c) > 0xffff): + escaped = '\\U%08x' % ord(c) + elif (ord(c) > 0x7f): + escaped = '\\u%04x' % ord(c) + else: + escaped = c result.append(escaped) result.append('"') return ''.join(result) @@ -83,24 +53,24 @@ |unicode_domain| is a Unicode string of the domain (NOT IDNA-encoded). |unicode_allowed| specifies whether the test case should expect the domain - to be displayed in Unicode form (True) or in IDNA/Punycode ASCII encoding - (False). |case_name| is just for the comment. + to be displayed in Unicode form (kSafe) or in IDNA/Punycode ASCII encoding + (kUnsafe). |case_name| is just for the comment. This function will automatically convert the domain to its IDNA format, and prepare the test case in C++ syntax. >>> make_case(u'\u5317\u4eac\u5927\u5b78.cn', True, 'Hanzi (Chinese)') // Hanzi (Chinese) - {"xn--1lq90ic7f1rc.cn", L"\\x5317\\x4eac\\x5927\\x5b78.cn", true}, + {"xn--1lq90ic7f1rc.cn", u"\\u5317\\u4eac\\u5927\\u5b78.cn", kSafe}, >>> make_case(u'b\u00fccher.de', True) - {"xn--bcher-kva.de", L"b\\x00fc" L"cher.de", true}, + {"xn--bcher-kva.de", u"b\\u00fccher.de", kSafe}, This will also apply normalization to the Unicode domain, as required by the IDNA algorithm. This example shows U+210F normalized to U+0127 (this generates the exact same test case as u'\u0127ello'): >>> make_case(u'\u210fello', True) - {"xn--ello-4xa", L"\\x0127" L"ello", true}, + {"xn--ello-4xa", u"\\u0127ello", kSafe}, """ idna_input = codecs.encode(unicode_domain, 'idna') # Round-trip to ensure normalization. @@ -108,8 +78,8 @@ if case_name: print(' // %s' % case_name) print(' {%s, %s, %s},' % - (str_to_c_string(idna_input), unicode_to_c_wstring(unicode_output), - repr(unicode_allowed).lower())) + (str_to_c_string(idna_input), unicode_to_c_ustring(unicode_output), + 'kSafe' if unicode_allowed else 'kUnsafe')) def main(args=None): @@ -144,9 +114,12 @@ if not args.domain: parser.error('Required argument: DOMAIN') - # Assume stdin.encoding is the encoding used for command-line arguments. - domain = args.domain.decode(sys.stdin.encoding) - make_case(domain, unicode_allowed=args.unicode_allowed, case_name=args.name) + if '://' in args.domain: + parser.error('A URL must not be passed as the domain argument') + + make_case(args.domain, + unicode_allowed=args.unicode_allowed, + case_name=args.name) if __name__ == '__main__':
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 9ce0393..b086b9f 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -9,64 +9,64 @@ <annotations> <item id="CRD_relay_session_request" added_in_milestone="62" hash_code="24058523" type="0" deprecated="2019-07-22" content_hash_code="36997811" file_path=""/> - <item id="accounts_image_fetcher" added_in_milestone="66" hash_code="98658519" type="0" content_hash_code="45432230" os_list="linux,windows" file_path="components/signin/internal/identity_manager/account_fetcher_service.cc"/> - <item id="adb_client_socket" added_in_milestone="65" hash_code="87775794" type="0" content_hash_code="56654828" os_list="linux,windows" file_path="chrome/browser/devtools/device/adb/adb_client_socket.cc"/> + <item id="accounts_image_fetcher" added_in_milestone="66" hash_code="98658519" type="0" content_hash_code="45432230" os_list="linux,windows,chromeos" file_path="components/signin/internal/identity_manager/account_fetcher_service.cc"/> + <item id="adb_client_socket" added_in_milestone="65" hash_code="87775794" type="0" content_hash_code="56654828" os_list="linux,windows,chromeos" file_path="chrome/browser/devtools/device/adb/adb_client_socket.cc"/> <item id="affiliation_lookup" added_in_milestone="62" hash_code="111904019" type="0" deprecated="2021-07-27" content_hash_code="81061452" file_path=""/> - <item id="affiliation_lookup_by_hash" added_in_milestone="87" hash_code="57748571" type="0" content_hash_code="40566404" os_list="linux,windows" file_path="components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.cc"/> - <item id="aggregation_service_helper_keys" added_in_milestone="96" hash_code="49783589" type="0" content_hash_code="68319105" os_list="linux,windows" file_path="content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc"/> - <item id="aggregation_service_report" added_in_milestone="95" hash_code="95942194" type="0" content_hash_code="44673922" os_list="linux,windows" file_path="content/browser/aggregation_service/aggregatable_report_sender.cc"/> - <item id="android_device_manager_socket" added_in_milestone="65" hash_code="37249086" type="0" content_hash_code="6436865" os_list="linux,windows" file_path="chrome/browser/devtools/device/android_device_manager.cc"/> - <item id="android_web_socket" added_in_milestone="65" hash_code="39356976" type="0" content_hash_code="12310113" os_list="linux,windows" file_path="chrome/browser/devtools/device/android_web_socket.cc"/> + <item id="affiliation_lookup_by_hash" added_in_milestone="87" hash_code="57748571" type="0" content_hash_code="40566404" os_list="linux,windows,chromeos" file_path="components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.cc"/> + <item id="aggregation_service_helper_keys" added_in_milestone="96" hash_code="49783589" type="0" content_hash_code="68319105" os_list="linux,windows,chromeos" file_path="content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc"/> + <item id="aggregation_service_report" added_in_milestone="95" hash_code="95942194" type="0" content_hash_code="44673922" os_list="linux,windows,chromeos" file_path="content/browser/aggregation_service/aggregatable_report_sender.cc"/> + <item id="android_device_manager_socket" added_in_milestone="65" hash_code="37249086" type="0" content_hash_code="6436865" os_list="linux,windows,chromeos" file_path="chrome/browser/devtools/device/android_device_manager.cc"/> + <item id="android_web_socket" added_in_milestone="65" hash_code="39356976" type="0" content_hash_code="12310113" os_list="linux,windows,chromeos" file_path="chrome/browser/devtools/device/android_web_socket.cc"/> <item id="appcache_update_job" added_in_milestone="62" hash_code="25790702" type="0" deprecated="2021-10-27" content_hash_code="27424887" file_path=""/> - <item id="auction_downloader" added_in_milestone="92" hash_code="27833508" type="0" content_hash_code="118747666" os_list="linux,windows" file_path="content/services/auction_worklet/auction_downloader.cc"/> - <item id="auction_report_sender" added_in_milestone="92" hash_code="96136865" type="0" content_hash_code="62368950" os_list="linux,windows" file_path="content/browser/interest_group/ad_auction_service_impl.cc"/> - <item id="autofill_image_fetcher_card_art_image" added_in_milestone="93" hash_code="90561372" type="0" content_hash_code="24622412" os_list="linux,windows" file_path="components/autofill/core/browser/ui/autofill_image_fetcher.cc"/> - <item id="autofill_query" added_in_milestone="62" hash_code="88863520" type="0" content_hash_code="15563339" os_list="linux,windows" file_path="components/autofill/core/browser/autofill_download_manager.cc"/> - <item id="autofill_upload" added_in_milestone="62" hash_code="104798869" type="0" content_hash_code="110634763" os_list="linux,windows" file_path="components/autofill/core/browser/autofill_download_manager.cc"/> + <item id="auction_downloader" added_in_milestone="92" hash_code="27833508" type="0" content_hash_code="118747666" os_list="linux,windows,chromeos" file_path="content/services/auction_worklet/auction_downloader.cc"/> + <item id="auction_report_sender" added_in_milestone="92" hash_code="96136865" type="0" content_hash_code="62368950" os_list="linux,windows,chromeos" file_path="content/browser/interest_group/ad_auction_service_impl.cc"/> + <item id="autofill_image_fetcher_card_art_image" added_in_milestone="93" hash_code="90561372" type="0" content_hash_code="24622412" os_list="linux,windows,chromeos" file_path="components/autofill/core/browser/ui/autofill_image_fetcher.cc"/> + <item id="autofill_query" added_in_milestone="62" hash_code="88863520" type="0" content_hash_code="15563339" os_list="linux,windows,chromeos" file_path="components/autofill/core/browser/autofill_download_manager.cc"/> + <item id="autofill_upload" added_in_milestone="62" hash_code="104798869" type="0" content_hash_code="110634763" os_list="linux,windows,chromeos" file_path="components/autofill/core/browser/autofill_download_manager.cc"/> <item id="backdrop_collection_images_download" added_in_milestone="68" hash_code="34767164" type="0" content_hash_code="62971406" os_list="linux,windows" file_path="chrome/browser/search/background/ntp_background_service.cc"/> <item id="backdrop_collection_names_download" added_in_milestone="68" hash_code="49246286" type="0" content_hash_code="93501319" os_list="linux,windows" file_path="chrome/browser/search/background/ntp_background_service.cc"/> <item id="backdrop_next_image_download" added_in_milestone="77" hash_code="7754485" type="0" content_hash_code="98537970" os_list="linux,windows" file_path="chrome/browser/search/background/ntp_background_service.cc"/> - <item id="background_fetch_context" added_in_milestone="62" hash_code="16469669" type="0" content_hash_code="52235434" os_list="linux,windows" file_path="content/browser/background_fetch/background_fetch_delegate_proxy.cc"/> - <item id="bidirectional_stream" added_in_milestone="67" hash_code="108665132" type="0" content_hash_code="130038340" os_list="linux,windows" file_path="net/http/bidirectional_stream.cc"/> - <item id="blink_extension_resource_loader" added_in_milestone="63" hash_code="84165821" type="0" content_hash_code="63536185" os_list="linux,windows" file_path="third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc"/> - <item id="blink_resource_loader" added_in_milestone="62" hash_code="101845102" type="0" content_hash_code="75331172" os_list="linux,windows" file_path="third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc"/> + <item id="background_fetch_context" added_in_milestone="62" hash_code="16469669" type="0" content_hash_code="52235434" os_list="linux,windows,chromeos" file_path="content/browser/background_fetch/background_fetch_delegate_proxy.cc"/> + <item id="bidirectional_stream" added_in_milestone="67" hash_code="108665132" type="0" content_hash_code="130038340" os_list="linux,windows,chromeos" file_path="net/http/bidirectional_stream.cc"/> + <item id="blink_extension_resource_loader" added_in_milestone="63" hash_code="84165821" type="0" content_hash_code="63536185" os_list="linux,windows,chromeos" file_path="third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc"/> + <item id="blink_resource_loader" added_in_milestone="62" hash_code="101845102" type="0" content_hash_code="75331172" os_list="linux,windows,chromeos" file_path="third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc"/> <item id="blob_read" added_in_milestone="62" hash_code="112303907" type="0" deprecated="2019-08-09" content_hash_code="135449692" file_path=""/> <item id="blob_reader" added_in_milestone="62" hash_code="5154306" type="0" deprecated="2018-06-14" content_hash_code="39702178" file_path=""/> - <item id="bluetooth_socket" added_in_milestone="65" hash_code="94099818" type="0" content_hash_code="30932349" os_list="linux,windows" file_path="device/bluetooth/bluetooth_socket_net.cc"/> - <item id="box_access_token_fetcher" added_in_milestone="89" hash_code="90263263" type="0" content_hash_code="120150044" os_list="linux,windows" file_path="chrome/browser/enterprise/connectors/file_system/access_token_fetcher.cc"/> - <item id="brandcode_config" added_in_milestone="62" hash_code="109679553" type="0" content_hash_code="128843792" os_list="linux,windows" file_path="chrome/browser/profile_resetter/brandcode_config_fetcher.cc"/> + <item id="bluetooth_socket" added_in_milestone="65" hash_code="94099818" type="0" content_hash_code="30932349" os_list="linux,windows,chromeos" file_path="device/bluetooth/bluetooth_socket_net.cc"/> + <item id="box_access_token_fetcher" added_in_milestone="89" hash_code="90263263" type="0" content_hash_code="120150044" os_list="linux,windows,chromeos" file_path="chrome/browser/enterprise/connectors/file_system/access_token_fetcher.cc"/> + <item id="brandcode_config" added_in_milestone="62" hash_code="109679553" type="0" content_hash_code="128843792" os_list="linux,windows,chromeos" file_path="chrome/browser/profile_resetter/brandcode_config_fetcher.cc"/> <item id="browser_switcher_ieem_sitelist" added_in_milestone="72" hash_code="97159948" type="0" content_hash_code="129062966" os_list="linux,windows" file_path="chrome/browser/browser_switcher/browser_switcher_service.cc"/> - <item id="cablev2_websocket_from_authenticator" added_in_milestone="87" hash_code="28613769" type="0" content_hash_code="119863612" os_list="linux,windows" file_path="device/fido/cable/v2_authenticator.cc"/> - <item id="cablev2_websocket_from_client" added_in_milestone="86" hash_code="3464399" type="0" content_hash_code="116618103" os_list="windows,linux" file_path="device/fido/cable/fido_tunnel_device.cc"/> - <item id="captive_portal_service" added_in_milestone="62" hash_code="88754904" type="0" content_hash_code="70737580" os_list="linux,windows" file_path="components/captive_portal/content/captive_portal_service.cc"/> + <item id="cablev2_websocket_from_authenticator" added_in_milestone="87" hash_code="28613769" type="0" content_hash_code="119863612" os_list="linux,windows,chromeos" file_path="device/fido/cable/v2_authenticator.cc"/> + <item id="cablev2_websocket_from_client" added_in_milestone="86" hash_code="3464399" type="0" content_hash_code="116618103" os_list="windows,linux,chromeos" file_path="device/fido/cable/fido_tunnel_device.cc"/> + <item id="captive_portal_service" added_in_milestone="62" hash_code="88754904" type="0" content_hash_code="70737580" os_list="linux,windows,chromeos" file_path="components/captive_portal/content/captive_portal_service.cc"/> <item id="cast_channel_send" added_in_milestone="66" hash_code="103172229" type="0" deprecated="2018-08-23" content_hash_code="33946302" file_path=""/> <item id="cast_keep_alive_delegate" added_in_milestone="66" hash_code="134755844" type="0" deprecated="2018-08-23" content_hash_code="66118796" file_path=""/> <item id="cast_message_handler" added_in_milestone="66" hash_code="87558948" type="0" deprecated="2018-08-23" content_hash_code="49684899" file_path=""/> - <item id="cast_socket" added_in_milestone="66" hash_code="115192205" type="0" content_hash_code="42881651" os_list="linux,windows" file_path="components/cast_channel/cast_socket.cc"/> - <item id="cast_udp_socket" added_in_milestone="66" hash_code="22573197" type="0" content_hash_code="75328301" os_list="linux,windows" file_path="components/mirroring/service/udp_socket_client.cc"/> - <item id="cast_udp_transport" added_in_milestone="65" hash_code="5576536" type="0" content_hash_code="107643273" os_list="linux,windows" file_path="media/cast/net/udp_transport_impl.cc"/> - <item id="certificate_verifier_url_loader" added_in_milestone="80" hash_code="80134684" type="0" content_hash_code="92630208" os_list="linux,windows" file_path="services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.cc"/> - <item id="certificate_verifier_url_request" added_in_milestone="80" hash_code="85988208" type="0" content_hash_code="59262468" os_list="linux,windows" file_path="net/cert_net/cert_net_fetcher_url_request.cc"/> + <item id="cast_socket" added_in_milestone="66" hash_code="115192205" type="0" content_hash_code="42881651" os_list="linux,windows,chromeos" file_path="components/cast_channel/cast_socket.cc"/> + <item id="cast_udp_socket" added_in_milestone="66" hash_code="22573197" type="0" content_hash_code="75328301" os_list="linux,windows,chromeos" file_path="components/mirroring/service/udp_socket_client.cc"/> + <item id="cast_udp_transport" added_in_milestone="65" hash_code="5576536" type="0" content_hash_code="107643273" os_list="linux,windows,chromeos" file_path="media/cast/net/udp_transport_impl.cc"/> + <item id="certificate_verifier_url_loader" added_in_milestone="80" hash_code="80134684" type="0" content_hash_code="92630208" os_list="linux,windows,chromeos" file_path="services/cert_verifier/cert_net_url_loader/cert_net_fetcher_url_loader.cc"/> + <item id="certificate_verifier_url_request" added_in_milestone="80" hash_code="85988208" type="0" content_hash_code="59262468" os_list="linux,windows,chromeos" file_path="net/cert_net/cert_net_fetcher_url_request.cc"/> <item id="chrome_HaTS_service" added_in_milestone="83" hash_code="136028241" type="0" deprecated="2021-02-03" content_hash_code="68990360" file_path=""/> - <item id="chrome_apps_socket_api" added_in_milestone="65" hash_code="8591273" type="0" content_hash_code="130709397" os_list="linux,windows" file_path="extensions/browser/api/socket/socket.cc"/> - <item id="chrome_cart_discounts_lookup" added_in_milestone="92" hash_code="44551896" type="0" content_hash_code="95675425" os_list="linux,windows" file_path="chrome/browser/cart/cart_discount_fetcher.cc"/> - <item id="chrome_cart_get_discounted_link" added_in_milestone="92" hash_code="58596544" type="0" content_hash_code="86139104" os_list="linux,windows" file_path="chrome/browser/cart/cart_discount_link_fetcher.cc"/> + <item id="chrome_apps_socket_api" added_in_milestone="65" hash_code="8591273" type="0" content_hash_code="130709397" os_list="linux,windows,chromeos" file_path="extensions/browser/api/socket/socket.cc"/> + <item id="chrome_cart_discounts_lookup" added_in_milestone="92" hash_code="44551896" type="0" content_hash_code="95675425" os_list="linux,windows,chromeos" file_path="chrome/browser/cart/cart_discount_fetcher.cc"/> + <item id="chrome_cart_get_discounted_link" added_in_milestone="92" hash_code="58596544" type="0" content_hash_code="86139104" os_list="linux,windows,chromeos" file_path="chrome/browser/cart/cart_discount_link_fetcher.cc"/> <item id="chrome_cleaner" added_in_milestone="63" hash_code="27071967" type="0" content_hash_code="111240292" os_list="windows" file_path="chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc"/> <item id="chrome_cleanup_report" added_in_milestone="70" hash_code="71102679" type="0" content_hash_code="130565656" os_list="windows" file_path="chrome/chrome_cleaner/logging/cleaner_logging_service.cc"/> - <item id="chrome_feedback_report_app" added_in_milestone="62" hash_code="134729048" type="0" content_hash_code="79660618" os_list="linux,windows" file_path="components/feedback/feedback_uploader.cc"/> - <item id="chrome_variations_service" added_in_milestone="62" hash_code="115188287" type="0" content_hash_code="16094337" os_list="linux,windows" file_path="components/variations/service/variations_service.cc"/> - <item id="client_download_request" added_in_milestone="62" hash_code="125522256" type="0" content_hash_code="79464901" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc"/> + <item id="chrome_feedback_report_app" added_in_milestone="62" hash_code="134729048" type="0" content_hash_code="79660618" os_list="linux,windows,chromeos" file_path="components/feedback/feedback_uploader.cc"/> + <item id="chrome_variations_service" added_in_milestone="62" hash_code="115188287" type="0" content_hash_code="16094337" os_list="linux,windows,chromeos" file_path="components/variations/service/variations_service.cc"/> + <item id="client_download_request" added_in_milestone="62" hash_code="125522256" type="0" content_hash_code="79464901" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/download_protection/check_client_download_request_base.cc"/> <item id="cloud_print" added_in_milestone="65" hash_code="111712433" type="2" content_hash_code="60926140" os_list="linux,windows" semantics_fields="1,5" policy_fields="-1,3,4" file_path="chrome/service/cloud_print/cloud_print_url_fetcher.cc"/> <item id="cloud_print_backend" added_in_milestone="62" hash_code="71578042" type="1" second_id="111712433" content_hash_code="85425333" os_list="linux,windows" semantics_fields="2,3,4" file_path="chrome/service/cloud_print/cloud_print_proxy_backend.cc"/> <item id="cloud_print_credential_update" added_in_milestone="66" hash_code="137420486" type="0" content_hash_code="1179808" os_list="linux,windows" file_path="chrome/service/cloud_print/cloud_print_proxy_backend.cc"/> <item id="cloud_print_proxy" added_in_milestone="62" hash_code="50859288" type="1" second_id="111712433" content_hash_code="90868083" os_list="linux,windows" semantics_fields="2,3,4" file_path="chrome/service/cloud_print/cloud_print_proxy.cc"/> - <item id="cloud_speech_recognition" added_in_milestone="85" hash_code="61001455" type="0" content_hash_code="114921835" os_list="linux,windows" file_path="chrome/services/speech/cloud_speech_recognition_client.cc"/> - <item id="content_hash_verification_job" added_in_milestone="62" hash_code="64733114" type="0" content_hash_code="127912411" os_list="linux,windows" file_path="extensions/browser/content_hash_fetcher.cc"/> + <item id="cloud_speech_recognition" added_in_milestone="85" hash_code="61001455" type="0" content_hash_code="114921835" os_list="linux,windows,chromeos" file_path="chrome/services/speech/cloud_speech_recognition_client.cc"/> + <item id="content_hash_verification_job" added_in_milestone="62" hash_code="64733114" type="0" content_hash_code="127912411" os_list="linux,windows,chromeos" file_path="extensions/browser/content_hash_fetcher.cc"/> <item id="content_resource_fetcher" added_in_milestone="63" hash_code="70796791" type="0" deprecated="2017-09-16" content_hash_code="135648626" file_path=""/> - <item id="content_suggestion_get_favicon" added_in_milestone="62" hash_code="16653985" type="0" content_hash_code="134280933" os_list="linux,windows" file_path="components/ntp_snippets/content_suggestions_service.cc"/> - <item id="conversion_measurement_report" added_in_milestone="84" hash_code="113422320" type="0" content_hash_code="102111798" os_list="linux,windows" file_path="content/browser/attribution_reporting/attribution_network_sender_impl.cc"/> - <item id="credenential_avatar" added_in_milestone="62" hash_code="53695122" type="0" content_hash_code="113035371" os_list="linux,windows" file_path="chrome/browser/ui/passwords/account_avatar_fetcher.cc"/> - <item id="cros_recovery_image_download" added_in_milestone="62" hash_code="101725581" type="0" content_hash_code="10999698" os_list="linux,windows" file_path="chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc"/> + <item id="content_suggestion_get_favicon" added_in_milestone="62" hash_code="16653985" type="0" content_hash_code="134280933" os_list="linux,windows,chromeos" file_path="components/ntp_snippets/content_suggestions_service.cc"/> + <item id="conversion_measurement_report" added_in_milestone="84" hash_code="113422320" type="0" content_hash_code="102111798" os_list="linux,windows,chromeos" file_path="content/browser/attribution_reporting/attribution_network_sender_impl.cc"/> + <item id="credenential_avatar" added_in_milestone="62" hash_code="53695122" type="0" content_hash_code="113035371" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/passwords/account_avatar_fetcher.cc"/> + <item id="cros_recovery_image_download" added_in_milestone="62" hash_code="101725581" type="0" content_hash_code="10999698" os_list="linux,windows,chromeos" file_path="chrome/browser/extensions/api/image_writer_private/write_from_url_operation.cc"/> <item id="cryptauth_device_sync_tickle" added_in_milestone="62" hash_code="96565489" type="1" second_id="29188932" deprecated="2018-03-15" content_hash_code="115714668" file_path=""/> <item id="cryptauth_enrollment_flow_finish" added_in_milestone="62" hash_code="54836939" type="1" second_id="29188932" deprecated="2018-04-04" content_hash_code="17060642" file_path=""/> <item id="cryptauth_enrollment_flow_setup" added_in_milestone="62" hash_code="84889397" type="1" second_id="29188932" deprecated="2018-04-04" content_hash_code="128348931" file_path=""/> @@ -79,265 +79,265 @@ <item id="data_reduction_proxy_secure_proxy_check" added_in_milestone="62" hash_code="131236802" type="0" deprecated="2020-03-13" content_hash_code="122297136" file_path=""/> <item id="data_reduction_proxy_warmup" added_in_milestone="62" hash_code="8250451" type="0" deprecated="2020-03-13" content_hash_code="6321249" file_path=""/> <item id="desktop_ios_promotion" added_in_milestone="63" hash_code="13694792" type="0" deprecated="2018-11-04" content_hash_code="19776951" file_path=""/> - <item id="desktop_screenshot_save" added_in_milestone="94" hash_code="18870110" type="0" content_hash_code="26509513" os_list="linux,windows" file_path="chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.cc"/> + <item id="desktop_screenshot_save" added_in_milestone="94" hash_code="18870110" type="0" content_hash_code="26509513" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/views/sharing_hub/screenshot/screenshot_captured_bubble.cc"/> <item id="device_geolocation_request" added_in_milestone="62" hash_code="77673751" type="0" deprecated="2017-10-20" content_hash_code="97181773" file_path=""/> - <item id="device_management_service" added_in_milestone="62" hash_code="117782019" type="0" content_hash_code="104419970" os_list="linux,windows" file_path="components/policy/core/common/cloud/device_management_service.cc"/> - <item id="devtools_cdp_network_resource" added_in_milestone="87" hash_code="60744935" type="0" content_hash_code="85833926" os_list="linux,windows" file_path="content/browser/devtools/protocol/devtools_network_resource_loader.cc"/> - <item id="devtools_free_data_source" added_in_milestone="62" hash_code="22774132" type="0" content_hash_code="35733000" os_list="linux,windows" file_path="chrome/browser/ui/webui/devtools_ui_data_source.cc"/> - <item id="devtools_handle_front_end_messages" added_in_milestone="62" hash_code="135636011" type="0" content_hash_code="76808593" os_list="linux,windows" file_path="content/shell/browser/shell_devtools_bindings.cc"/> - <item id="devtools_hard_coded_data_source" added_in_milestone="62" hash_code="111565057" type="0" content_hash_code="75183720" os_list="linux,windows" file_path="chrome/browser/ui/webui/devtools_ui_data_source.cc"/> - <item id="devtools_http_handler" added_in_milestone="66" hash_code="49160454" type="0" content_hash_code="88414393" os_list="linux,windows" file_path="content/browser/devtools/devtools_http_handler.cc"/> + <item id="device_management_service" added_in_milestone="62" hash_code="117782019" type="0" content_hash_code="104419970" os_list="linux,windows,chromeos" file_path="components/policy/core/common/cloud/device_management_service.cc"/> + <item id="devtools_cdp_network_resource" added_in_milestone="87" hash_code="60744935" type="0" content_hash_code="85833926" os_list="linux,windows,chromeos" file_path="content/browser/devtools/protocol/devtools_network_resource_loader.cc"/> + <item id="devtools_free_data_source" added_in_milestone="62" hash_code="22774132" type="0" content_hash_code="35733000" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/webui/devtools_ui_data_source.cc"/> + <item id="devtools_handle_front_end_messages" added_in_milestone="62" hash_code="135636011" type="0" content_hash_code="76808593" os_list="linux,windows,chromeos" file_path="content/shell/browser/shell_devtools_bindings.cc"/> + <item id="devtools_hard_coded_data_source" added_in_milestone="62" hash_code="111565057" type="0" content_hash_code="75183720" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/webui/devtools_ui_data_source.cc"/> + <item id="devtools_http_handler" added_in_milestone="66" hash_code="49160454" type="0" content_hash_code="88414393" os_list="linux,windows,chromeos" file_path="content/browser/devtools/devtools_http_handler.cc"/> <item id="devtools_interceptor" added_in_milestone="62" hash_code="98123737" type="0" deprecated="2019-07-31" content_hash_code="64591843" file_path=""/> - <item id="devtools_network_resource" added_in_milestone="62" hash_code="129652775" type="0" content_hash_code="32810159" os_list="linux,windows" file_path="chrome/browser/devtools/devtools_ui_bindings.cc"/> - <item id="devtools_proxy_config" added_in_milestone="85" hash_code="79904729" type="0" content_hash_code="31996982" os_list="linux,windows" file_path="content/browser/devtools/protocol/target_handler.cc"/> + <item id="devtools_network_resource" added_in_milestone="62" hash_code="129652775" type="0" content_hash_code="32810159" os_list="linux,windows,chromeos" file_path="chrome/browser/devtools/devtools_ui_bindings.cc"/> + <item id="devtools_proxy_config" added_in_milestone="85" hash_code="79904729" type="0" content_hash_code="31996982" os_list="linux,windows,chromeos" file_path="content/browser/devtools/protocol/target_handler.cc"/> <item id="dial_get_app_info" added_in_milestone="65" hash_code="15952025" type="0" deprecated="2018-02-27" content_hash_code="90542080" file_path=""/> <item id="dial_get_device_description" added_in_milestone="62" hash_code="50422598" type="0" deprecated="2018-02-27" content_hash_code="129827780" file_path=""/> - <item id="dial_url_fetcher" added_in_milestone="67" hash_code="41424546" type="0" content_hash_code="129828432" os_list="linux,windows" file_path="chrome/browser/media/router/discovery/dial/dial_url_fetcher.cc"/> - <item id="digital_asset_links" added_in_milestone="90" hash_code="134272131" type="0" content_hash_code="13554846" os_list="linux,windows" file_path="components/digital_asset_links/digital_asset_links_handler.cc"/> - <item id="direct_sockets" added_in_milestone="88" hash_code="32472991" type="0" content_hash_code="64752301" os_list="linux,windows" file_path="content/browser/direct_sockets/direct_sockets_service_impl.cc"/> - <item id="dns_over_https" added_in_milestone="66" hash_code="79895226" type="0" content_hash_code="45123510" os_list="linux,windows" file_path="net/dns/dns_transaction.cc"/> - <item id="dns_transaction" added_in_milestone="65" hash_code="79227717" type="0" content_hash_code="132206495" os_list="linux,windows" file_path="net/dns/dns_transaction.cc"/> - <item id="dom_distiller" added_in_milestone="62" hash_code="3989826" type="0" content_hash_code="106153970" os_list="linux,windows" file_path="components/dom_distiller/core/distiller_url_fetcher.cc"/> - <item id="domain_reliability_report_upload" added_in_milestone="62" hash_code="108804096" type="0" content_hash_code="35902036" os_list="linux,windows" file_path="components/domain_reliability/uploader.cc"/> - <item id="domain_security_policy" added_in_milestone="62" hash_code="77597059" type="0" content_hash_code="30916983" os_list="linux,windows" file_path="services/network/network_context.cc"/> + <item id="dial_url_fetcher" added_in_milestone="67" hash_code="41424546" type="0" content_hash_code="129828432" os_list="linux,windows,chromeos" file_path="chrome/browser/media/router/discovery/dial/dial_url_fetcher.cc"/> + <item id="digital_asset_links" added_in_milestone="90" hash_code="134272131" type="0" content_hash_code="13554846" os_list="linux,windows,chromeos" file_path="components/digital_asset_links/digital_asset_links_handler.cc"/> + <item id="direct_sockets" added_in_milestone="88" hash_code="32472991" type="0" content_hash_code="64752301" os_list="linux,windows,chromeos" file_path="content/browser/direct_sockets/direct_sockets_service_impl.cc"/> + <item id="dns_over_https" added_in_milestone="66" hash_code="79895226" type="0" content_hash_code="45123510" os_list="linux,windows,chromeos" file_path="net/dns/dns_transaction.cc"/> + <item id="dns_transaction" added_in_milestone="65" hash_code="79227717" type="0" content_hash_code="132206495" os_list="linux,windows,chromeos" file_path="net/dns/dns_transaction.cc"/> + <item id="dom_distiller" added_in_milestone="62" hash_code="3989826" type="0" content_hash_code="106153970" os_list="linux,windows,chromeos" file_path="components/dom_distiller/core/distiller_url_fetcher.cc"/> + <item id="domain_reliability_report_upload" added_in_milestone="62" hash_code="108804096" type="0" content_hash_code="35902036" os_list="linux,windows,chromeos" file_path="components/domain_reliability/uploader.cc"/> + <item id="domain_security_policy" added_in_milestone="62" hash_code="77597059" type="0" content_hash_code="30916983" os_list="linux,windows,chromeos" file_path="services/network/network_context.cc"/> <item id="doodle_fetcher" added_in_milestone="62" hash_code="97199008" type="0" deprecated="2017-08-28" content_hash_code="87981692" file_path=""/> <item id="doodle_service" added_in_milestone="62" hash_code="41154842" type="0" deprecated="2017-08-28" content_hash_code="28273962" file_path=""/> - <item id="download_internals_webui_source" added_in_milestone="66" hash_code="38670228" type="0" content_hash_code="129391056" os_list="linux,windows" file_path="chrome/browser/ui/webui/download_internals/download_internals_ui_message_handler.cc"/> - <item id="download_manager_resume" added_in_milestone="62" hash_code="35380758" type="0" content_hash_code="41227674" os_list="linux,windows" file_path="components/download/internal/common/download_item_impl.cc"/> + <item id="download_internals_webui_source" added_in_milestone="66" hash_code="38670228" type="0" content_hash_code="129391056" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/webui/download_internals/download_internals_ui_message_handler.cc"/> + <item id="download_manager_resume" added_in_milestone="62" hash_code="35380758" type="0" content_hash_code="41227674" os_list="linux,windows,chromeos" file_path="components/download/internal/common/download_item_impl.cc"/> <item id="download_recovery_component" added_in_milestone="71" hash_code="131711536" type="0" content_hash_code="3243311" os_list="windows" file_path="chrome/chrome_cleaner/components/recovery_component.cc"/> - <item id="download_web_contents_frame" added_in_milestone="62" hash_code="56351037" type="0" content_hash_code="3657889" os_list="linux,windows" file_path="content/browser/web_contents/web_contents_impl.cc"/> - <item id="downloads_api_run_async" added_in_milestone="62" hash_code="121068967" type="0" content_hash_code="9280914" os_list="linux,windows" file_path="chrome/browser/extensions/api/downloads/downloads_api.cc"/> - <item id="downloads_dom_handler" added_in_milestone="73" hash_code="95951029" type="0" content_hash_code="137150731" os_list="linux,windows" file_path="chrome/browser/ui/webui/downloads/downloads_dom_handler.cc"/> - <item id="drag_download_file" added_in_milestone="62" hash_code="95910019" type="0" content_hash_code="126492858" os_list="linux,windows" file_path="content/browser/download/drag_download_file.cc"/> - <item id="drive_service" added_in_milestone="90" hash_code="56074781" type="0" content_hash_code="94248995" os_list="linux,windows" file_path="chrome/browser/new_tab_page/modules/drive/drive_service.cc"/> - <item id="early_hints_preload" added_in_milestone="91" hash_code="35266994" type="0" content_hash_code="42984058" os_list="linux,windows" file_path="content/browser/loader/navigation_early_hints_manager.cc"/> - <item id="enterprise_safe_browsing_realtime_url_lookup" added_in_milestone="86" hash_code="22262963" type="0" content_hash_code="14052810" os_list="linux,windows" file_path="chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc"/> - <item id="expect_ct_reporter" added_in_milestone="69" hash_code="23537266" type="0" content_hash_code="130492494" os_list="linux,windows" file_path="services/network/expect_ct_reporter.cc"/> - <item id="extension_blacklist" added_in_milestone="62" hash_code="59592717" type="0" content_hash_code="116742516" os_list="linux,windows" file_path="chrome/browser/extensions/blocklist_state_fetcher.cc"/> - <item id="extension_crx_fetcher" added_in_milestone="62" hash_code="21145003" type="0" content_hash_code="79150319" os_list="linux,windows" file_path="extensions/browser/updater/extension_downloader.cc"/> - <item id="extension_install_signer" added_in_milestone="62" hash_code="50464499" type="0" content_hash_code="106712014" os_list="linux,windows" file_path="chrome/browser/extensions/install_signer.cc"/> - <item id="extension_manifest_fetcher" added_in_milestone="62" hash_code="5151071" type="0" content_hash_code="93862569" os_list="linux,windows" file_path="extensions/browser/updater/extension_downloader.cc"/> - <item id="external_policy_fetcher" added_in_milestone="62" hash_code="9459438" type="0" content_hash_code="64260484" os_list="linux,windows" file_path="components/policy/core/common/cloud/external_policy_data_fetcher.cc"/> + <item id="download_web_contents_frame" added_in_milestone="62" hash_code="56351037" type="0" content_hash_code="3657889" os_list="linux,windows,chromeos" file_path="content/browser/web_contents/web_contents_impl.cc"/> + <item id="downloads_api_run_async" added_in_milestone="62" hash_code="121068967" type="0" content_hash_code="9280914" os_list="linux,windows,chromeos" file_path="chrome/browser/extensions/api/downloads/downloads_api.cc"/> + <item id="downloads_dom_handler" added_in_milestone="73" hash_code="95951029" type="0" content_hash_code="137150731" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/webui/downloads/downloads_dom_handler.cc"/> + <item id="drag_download_file" added_in_milestone="62" hash_code="95910019" type="0" content_hash_code="126492858" os_list="linux,windows,chromeos" file_path="content/browser/download/drag_download_file.cc"/> + <item id="drive_service" added_in_milestone="90" hash_code="56074781" type="0" content_hash_code="94248995" os_list="linux,windows,chromeos" file_path="chrome/browser/new_tab_page/modules/drive/drive_service.cc"/> + <item id="early_hints_preload" added_in_milestone="91" hash_code="35266994" type="0" content_hash_code="42984058" os_list="linux,windows,chromeos" file_path="content/browser/loader/navigation_early_hints_manager.cc"/> + <item id="enterprise_safe_browsing_realtime_url_lookup" added_in_milestone="86" hash_code="22262963" type="0" content_hash_code="14052810" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.cc"/> + <item id="expect_ct_reporter" added_in_milestone="69" hash_code="23537266" type="0" content_hash_code="130492494" os_list="linux,windows,chromeos" file_path="services/network/expect_ct_reporter.cc"/> + <item id="extension_blacklist" added_in_milestone="62" hash_code="59592717" type="0" content_hash_code="116742516" os_list="linux,windows,chromeos" file_path="chrome/browser/extensions/blocklist_state_fetcher.cc"/> + <item id="extension_crx_fetcher" added_in_milestone="62" hash_code="21145003" type="0" content_hash_code="79150319" os_list="linux,windows,chromeos" file_path="extensions/browser/updater/extension_downloader.cc"/> + <item id="extension_install_signer" added_in_milestone="62" hash_code="50464499" type="0" content_hash_code="106712014" os_list="linux,windows,chromeos" file_path="chrome/browser/extensions/install_signer.cc"/> + <item id="extension_manifest_fetcher" added_in_milestone="62" hash_code="5151071" type="0" content_hash_code="93862569" os_list="linux,windows,chromeos" file_path="extensions/browser/updater/extension_downloader.cc"/> + <item id="external_policy_fetcher" added_in_milestone="62" hash_code="9459438" type="0" content_hash_code="64260484" os_list="linux,windows,chromeos" file_path="components/policy/core/common/cloud/external_policy_data_fetcher.cc"/> <item id="family_info" added_in_milestone="62" hash_code="30913825" type="0" deprecated="2019-07-30" content_hash_code="25369370" file_path=""/> - <item id="favicon_loader" added_in_milestone="63" hash_code="112189210" type="0" content_hash_code="70773116" os_list="linux,windows" file_path="third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc"/> + <item id="favicon_loader" added_in_milestone="63" hash_code="112189210" type="0" content_hash_code="70773116" os_list="linux,windows,chromeos" file_path="third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc"/> <item id="feed_image_fetcher" added_in_milestone="68" hash_code="87439531" type="0" deprecated="2019-01-04" content_hash_code="26756208" file_path=""/> - <item id="file_system_connector_to_box" added_in_milestone="89" hash_code="29061438" type="1" second_id="29188932" content_hash_code="39353559" os_list="linux,windows" semantics_fields="1,2,3,4,5" policy_fields="-1,3,4" file_path="chrome/browser/enterprise/connectors/file_system/box_api_call_flow.cc"/> - <item id="floc_event_logger" added_in_milestone="89" hash_code="86015226" type="1" second_id="13704791" content_hash_code="68024778" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="3" file_path="chrome/browser/federated_learning/floc_event_logger.cc"/> + <item id="file_system_connector_to_box" added_in_milestone="89" hash_code="29061438" type="1" second_id="29188932" content_hash_code="39353559" os_list="linux,windows,chromeos" semantics_fields="1,2,3,4,5" policy_fields="-1,3,4" file_path="chrome/browser/enterprise/connectors/file_system/box_api_call_flow.cc"/> + <item id="floc_event_logger" added_in_milestone="89" hash_code="86015226" type="1" second_id="13704791" content_hash_code="68024778" os_list="linux,windows,chromeos" semantics_fields="2,3,4" policy_fields="3" file_path="chrome/browser/federated_learning/floc_event_logger.cc"/> <item id="floc_id_provider_impl" added_in_milestone="85" hash_code="103052331" type="1" second_id="13704791" deprecated="2021-01-05" content_hash_code="41421380" file_path=""/> - <item id="floc_remote_permission_service" added_in_milestone="85" hash_code="13704791" type="2" content_hash_code="86293622" os_list="linux,windows" semantics_fields="1,5" policy_fields="1,2,4" file_path="chrome/browser/federated_learning/floc_remote_permission_service.cc"/> - <item id="ftl_messaging_client_ack_messages" added_in_milestone="86" hash_code="55663676" type="0" content_hash_code="20913627" os_list="linux,windows" file_path="remoting/signaling/ftl_messaging_client.cc"/> - <item id="ftl_messaging_client_receive_messages" added_in_milestone="86" hash_code="136248372" type="0" content_hash_code="36609143" os_list="linux,windows" file_path="remoting/signaling/ftl_messaging_client.cc"/> - <item id="ftl_messaging_client_send_messages" added_in_milestone="86" hash_code="48924790" type="0" content_hash_code="6841587" os_list="linux,windows" file_path="remoting/signaling/ftl_messaging_client.cc"/> - <item id="ftl_registration_manager" added_in_milestone="86" hash_code="38256901" type="0" content_hash_code="12581281" os_list="linux,windows" file_path="remoting/signaling/ftl_registration_manager.cc"/> - <item id="gaia_auth_check_connection_info" added_in_milestone="62" hash_code="4598626" type="0" content_hash_code="57347000" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> + <item id="floc_remote_permission_service" added_in_milestone="85" hash_code="13704791" type="2" content_hash_code="86293622" os_list="linux,windows,chromeos" semantics_fields="1,5" policy_fields="1,2,4" file_path="chrome/browser/federated_learning/floc_remote_permission_service.cc"/> + <item id="ftl_messaging_client_ack_messages" added_in_milestone="86" hash_code="55663676" type="0" content_hash_code="20913627" os_list="linux,windows,chromeos" file_path="remoting/signaling/ftl_messaging_client.cc"/> + <item id="ftl_messaging_client_receive_messages" added_in_milestone="86" hash_code="136248372" type="0" content_hash_code="36609143" os_list="linux,windows,chromeos" file_path="remoting/signaling/ftl_messaging_client.cc"/> + <item id="ftl_messaging_client_send_messages" added_in_milestone="86" hash_code="48924790" type="0" content_hash_code="6841587" os_list="linux,windows,chromeos" file_path="remoting/signaling/ftl_messaging_client.cc"/> + <item id="ftl_registration_manager" added_in_milestone="86" hash_code="38256901" type="0" content_hash_code="12581281" os_list="linux,windows,chromeos" file_path="remoting/signaling/ftl_registration_manager.cc"/> + <item id="gaia_auth_check_connection_info" added_in_milestone="62" hash_code="4598626" type="0" content_hash_code="57347000" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> <item id="gaia_auth_exchange_cookies" added_in_milestone="62" hash_code="134289752" type="0" deprecated="2018-09-11" content_hash_code="66433230" file_path=""/> - <item id="gaia_auth_exchange_device_id" added_in_milestone="62" hash_code="39877119" type="0" content_hash_code="61857947" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> - <item id="gaia_auth_fetch_for_uber" added_in_milestone="62" hash_code="97978464" type="0" content_hash_code="28006265" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> - <item id="gaia_auth_get_user_info" added_in_milestone="62" hash_code="82167736" type="0" content_hash_code="4695017" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> - <item id="gaia_auth_list_accounts" added_in_milestone="62" hash_code="35565745" type="0" content_hash_code="93669150" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> - <item id="gaia_auth_log_out" added_in_milestone="62" hash_code="116426676" type="0" content_hash_code="91154233" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> - <item id="gaia_auth_login" added_in_milestone="62" hash_code="91597383" type="0" content_hash_code="111911548" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> - <item id="gaia_auth_merge_sessions" added_in_milestone="62" hash_code="26216847" type="0" content_hash_code="30423843" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> - <item id="gaia_auth_multilogin" added_in_milestone="70" hash_code="31445884" type="0" content_hash_code="77730858" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> - <item id="gaia_auth_revoke_token" added_in_milestone="62" hash_code="133982351" type="0" content_hash_code="96665330" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> - <item id="gaia_cookie_manager_external_cc_result" added_in_milestone="62" hash_code="4300475" type="0" content_hash_code="31188375" os_list="linux,windows" file_path="components/signin/internal/identity_manager/gaia_cookie_manager_service.cc"/> - <item id="gaia_create_reauth_proof_token_for_parent" added_in_milestone="80" hash_code="67750043" type="0" content_hash_code="103500636" os_list="linux,windows" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> - <item id="gaia_oauth_client_get_account_capabilities" added_in_milestone="93" hash_code="87437888" type="0" content_hash_code="51145869" os_list="linux,windows" file_path="google_apis/gaia/gaia_oauth_client.cc"/> - <item id="gaia_oauth_client_get_token_info" added_in_milestone="62" hash_code="32585152" type="0" content_hash_code="128143346" os_list="linux,windows" file_path="google_apis/gaia/gaia_oauth_client.cc"/> - <item id="gaia_oauth_client_get_tokens" added_in_milestone="62" hash_code="5637379" type="0" content_hash_code="12099176" os_list="linux,windows" file_path="google_apis/gaia/gaia_oauth_client.cc"/> - <item id="gaia_oauth_client_get_user_info" added_in_milestone="62" hash_code="83476155" type="0" content_hash_code="35159007" os_list="linux,windows" file_path="google_apis/gaia/gaia_oauth_client.cc"/> - <item id="gaia_oauth_client_refresh_token" added_in_milestone="62" hash_code="82462683" type="0" content_hash_code="22305252" os_list="linux,windows" file_path="google_apis/gaia/gaia_oauth_client.cc"/> + <item id="gaia_auth_exchange_device_id" added_in_milestone="62" hash_code="39877119" type="0" content_hash_code="61857947" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> + <item id="gaia_auth_fetch_for_uber" added_in_milestone="62" hash_code="97978464" type="0" content_hash_code="28006265" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> + <item id="gaia_auth_get_user_info" added_in_milestone="62" hash_code="82167736" type="0" content_hash_code="4695017" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> + <item id="gaia_auth_list_accounts" added_in_milestone="62" hash_code="35565745" type="0" content_hash_code="93669150" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> + <item id="gaia_auth_log_out" added_in_milestone="62" hash_code="116426676" type="0" content_hash_code="91154233" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> + <item id="gaia_auth_login" added_in_milestone="62" hash_code="91597383" type="0" content_hash_code="111911548" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> + <item id="gaia_auth_merge_sessions" added_in_milestone="62" hash_code="26216847" type="0" content_hash_code="30423843" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> + <item id="gaia_auth_multilogin" added_in_milestone="70" hash_code="31445884" type="0" content_hash_code="77730858" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> + <item id="gaia_auth_revoke_token" added_in_milestone="62" hash_code="133982351" type="0" content_hash_code="96665330" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> + <item id="gaia_cookie_manager_external_cc_result" added_in_milestone="62" hash_code="4300475" type="0" content_hash_code="31188375" os_list="linux,windows,chromeos" file_path="components/signin/internal/identity_manager/gaia_cookie_manager_service.cc"/> + <item id="gaia_create_reauth_proof_token_for_parent" added_in_milestone="80" hash_code="67750043" type="0" content_hash_code="103500636" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_auth_fetcher.cc"/> + <item id="gaia_oauth_client_get_account_capabilities" added_in_milestone="93" hash_code="87437888" type="0" content_hash_code="51145869" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_oauth_client.cc"/> + <item id="gaia_oauth_client_get_token_info" added_in_milestone="62" hash_code="32585152" type="0" content_hash_code="128143346" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_oauth_client.cc"/> + <item id="gaia_oauth_client_get_tokens" added_in_milestone="62" hash_code="5637379" type="0" content_hash_code="12099176" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_oauth_client.cc"/> + <item id="gaia_oauth_client_get_user_info" added_in_milestone="62" hash_code="83476155" type="0" content_hash_code="35159007" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_oauth_client.cc"/> + <item id="gaia_oauth_client_refresh_token" added_in_milestone="62" hash_code="82462683" type="0" content_hash_code="22305252" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_oauth_client.cc"/> <item id="gcd_rest_client" added_in_milestone="71" hash_code="105985951" type="0" deprecated="2018-10-17" content_hash_code="70710803" file_path="remoting/host/gcd_rest_client.cc"/> <item id="gcm_channel_status_request" added_in_milestone="62" hash_code="18300705" type="0" deprecated="2020-01-24" content_hash_code="53862393" file_path=""/> - <item id="gcm_checkin" added_in_milestone="62" hash_code="65957842" type="0" content_hash_code="98259579" os_list="linux,windows" file_path="google_apis/gcm/engine/checkin_request.cc"/> - <item id="gcm_connection_factory" added_in_milestone="66" hash_code="29057242" type="0" content_hash_code="75279835" os_list="linux,windows" file_path="google_apis/gcm/engine/connection_factory_impl.cc"/> - <item id="gcm_registration" added_in_milestone="62" hash_code="61656965" type="0" content_hash_code="113670632" os_list="linux,windows" file_path="google_apis/gcm/engine/registration_request.cc"/> + <item id="gcm_checkin" added_in_milestone="62" hash_code="65957842" type="0" content_hash_code="98259579" os_list="linux,windows,chromeos" file_path="google_apis/gcm/engine/checkin_request.cc"/> + <item id="gcm_connection_factory" added_in_milestone="66" hash_code="29057242" type="0" content_hash_code="75279835" os_list="linux,windows,chromeos" file_path="google_apis/gcm/engine/connection_factory_impl.cc"/> + <item id="gcm_registration" added_in_milestone="62" hash_code="61656965" type="0" content_hash_code="113670632" os_list="linux,windows,chromeos" file_path="google_apis/gcm/engine/registration_request.cc"/> <item id="gcm_subscription" added_in_milestone="62" hash_code="56434025" type="0" deprecated="2019-04-10" content_hash_code="61632174" file_path=""/> - <item id="gcm_unregistration" added_in_milestone="62" hash_code="119542033" type="0" content_hash_code="30144127" os_list="linux,windows" file_path="google_apis/gcm/engine/unregistration_request.cc"/> - <item id="geo_language_provider" added_in_milestone="65" hash_code="52821843" type="1" second_id="96590038" content_hash_code="65327456" os_list="linux,windows" semantics_fields="1" policy_fields="3,4" file_path="components/language/content/browser/geo_language_provider.cc"/> + <item id="gcm_unregistration" added_in_milestone="62" hash_code="119542033" type="0" content_hash_code="30144127" os_list="linux,windows,chromeos" file_path="google_apis/gcm/engine/unregistration_request.cc"/> + <item id="geo_language_provider" added_in_milestone="65" hash_code="52821843" type="1" second_id="96590038" content_hash_code="65327456" os_list="linux,windows,chromeos" semantics_fields="1" policy_fields="3,4" file_path="components/language/content/browser/geo_language_provider.cc"/> <item id="google_url_tracker" added_in_milestone="62" hash_code="5492492" type="0" deprecated="2019-08-01" content_hash_code="54474899" file_path=""/> <item id="gstatic_change_password_override_urls" added_in_milestone="86" hash_code="135799714" type="0" deprecated="2021-07-12" content_hash_code="133151871" file_path=""/> <item id="headless_url_request" added_in_milestone="62" hash_code="29865866" type="0" deprecated="2018-07-10" content_hash_code="76700151" file_path=""/> - <item id="heartbeat_sender" added_in_milestone="86" hash_code="4883150" type="0" content_hash_code="131927805" os_list="linux,windows" file_path="remoting/host/heartbeat_sender.cc"/> - <item id="hintsfetcher_gethintsrequest" added_in_milestone="75" hash_code="34557599" type="0" content_hash_code="57003380" os_list="linux,windows" file_path="components/optimization_guide/core/hints_fetcher.cc"/> - <item id="history_notice_utils_notice" added_in_milestone="62" hash_code="102595701" type="1" second_id="110307337" content_hash_code="130829410" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/history_notice_utils.cc"/> - <item id="history_notice_utils_popup" added_in_milestone="62" hash_code="80832574" type="1" second_id="110307337" content_hash_code="30618510" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/history_notice_utils.cc"/> - <item id="history_ui_favicon_request_handler_get_favicon" added_in_milestone="77" hash_code="17562717" type="0" content_hash_code="64054629" os_list="linux,windows" file_path="components/favicon/core/history_ui_favicon_request_handler_impl.cc"/> - <item id="http_server_error_response" added_in_milestone="66" hash_code="32197336" type="0" content_hash_code="61082230" os_list="linux,windows" file_path="net/server/http_server.cc"/> + <item id="heartbeat_sender" added_in_milestone="86" hash_code="4883150" type="0" content_hash_code="131927805" os_list="linux,windows,chromeos" file_path="remoting/host/heartbeat_sender.cc"/> + <item id="hintsfetcher_gethintsrequest" added_in_milestone="75" hash_code="34557599" type="0" content_hash_code="57003380" os_list="linux,windows,chromeos" file_path="components/optimization_guide/core/hints_fetcher.cc"/> + <item id="history_notice_utils_notice" added_in_milestone="62" hash_code="102595701" type="1" second_id="110307337" content_hash_code="130829410" os_list="linux,windows,chromeos" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/history_notice_utils.cc"/> + <item id="history_notice_utils_popup" added_in_milestone="62" hash_code="80832574" type="1" second_id="110307337" content_hash_code="30618510" os_list="linux,windows,chromeos" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/history_notice_utils.cc"/> + <item id="history_ui_favicon_request_handler_get_favicon" added_in_milestone="77" hash_code="17562717" type="0" content_hash_code="64054629" os_list="linux,windows,chromeos" file_path="components/favicon/core/history_ui_favicon_request_handler_impl.cc"/> + <item id="http_server_error_response" added_in_milestone="66" hash_code="32197336" type="0" content_hash_code="61082230" os_list="linux,windows,chromeos" file_path="net/server/http_server.cc"/> <item id="https_server_previews_navigation" added_in_milestone="74" hash_code="35725390" type="0" deprecated="2020-04-23" content_hash_code="84423109" file_path="chrome/browser/previews/previews_lite_page_redirect_serving_url_loader.cc"/> <item id="ice_config_fetcher" added_in_milestone="81" hash_code="137093034" type="0" deprecated="2020-10-13" content_hash_code="60051202" file_path="chrome/browser/sharing/webrtc/ice_config_fetcher.cc"/> - <item id="icon_cacher" added_in_milestone="62" hash_code="103133150" type="0" content_hash_code="116368348" os_list="linux,windows" file_path="components/ntp_tiles/icon_cacher_impl.cc"/> - <item id="icon_catcher_get_large_icon" added_in_milestone="62" hash_code="44494884" type="0" content_hash_code="98262037" os_list="linux,windows" file_path="components/ntp_tiles/icon_cacher_impl.cc"/> - <item id="image_annotation" added_in_milestone="73" hash_code="107881858" type="0" content_hash_code="76229990" os_list="linux,windows" file_path="services/image_annotation/annotator.cc"/> - <item id="indexed_db_internals_handler" added_in_milestone="62" hash_code="131180348" type="0" content_hash_code="59026406" os_list="linux,windows" file_path="content/browser/indexed_db/indexed_db_internals_ui.cc"/> - <item id="interest_feedv2_image_send" added_in_milestone="86" hash_code="92245202" type="0" content_hash_code="107508312" os_list="linux,windows" file_path="components/feed/core/v2/image_fetcher.cc"/> - <item id="interest_feedv2_send" added_in_milestone="83" hash_code="85742023" type="0" content_hash_code="49706671" os_list="linux,windows" file_path="components/feed/core/v2/feed_network_impl.cc"/> - <item id="interest_group_update_fetcher" added_in_milestone="94" hash_code="110915076" type="0" content_hash_code="41071213" os_list="linux,windows" file_path="content/browser/interest_group/interest_group_manager.cc"/> - <item id="intranet_redirect_detector" added_in_milestone="62" hash_code="21785164" type="0" content_hash_code="62025595" os_list="linux,windows" file_path="chrome/browser/intranet_redirect_detector.cc"/> + <item id="icon_cacher" added_in_milestone="62" hash_code="103133150" type="0" content_hash_code="116368348" os_list="linux,windows,chromeos" file_path="components/ntp_tiles/icon_cacher_impl.cc"/> + <item id="icon_catcher_get_large_icon" added_in_milestone="62" hash_code="44494884" type="0" content_hash_code="98262037" os_list="linux,windows,chromeos" file_path="components/ntp_tiles/icon_cacher_impl.cc"/> + <item id="image_annotation" added_in_milestone="73" hash_code="107881858" type="0" content_hash_code="76229990" os_list="linux,windows,chromeos" file_path="services/image_annotation/annotator.cc"/> + <item id="indexed_db_internals_handler" added_in_milestone="62" hash_code="131180348" type="0" content_hash_code="59026406" os_list="linux,windows,chromeos" file_path="content/browser/indexed_db/indexed_db_internals_ui.cc"/> + <item id="interest_feedv2_image_send" added_in_milestone="86" hash_code="92245202" type="0" content_hash_code="107508312" os_list="linux,windows,chromeos" file_path="components/feed/core/v2/image_fetcher.cc"/> + <item id="interest_feedv2_send" added_in_milestone="83" hash_code="85742023" type="0" content_hash_code="49706671" os_list="linux,windows,chromeos" file_path="components/feed/core/v2/feed_network_impl.cc"/> + <item id="interest_group_update_fetcher" added_in_milestone="94" hash_code="110915076" type="0" content_hash_code="41071213" os_list="linux,windows,chromeos" file_path="content/browser/interest_group/interest_group_manager.cc"/> + <item id="intranet_redirect_detector" added_in_milestone="62" hash_code="21785164" type="0" content_hash_code="62025595" os_list="linux,windows,chromeos" file_path="chrome/browser/intranet_redirect_detector.cc"/> <item id="invalidation_service" added_in_milestone="62" hash_code="72354423" type="0" deprecated="2020-01-23" content_hash_code="78425687" file_path=""/> <item id="javascript_report_error" added_in_milestone="87" hash_code="109607776" type="0" content_hash_code="7229012" os_list="linux" file_path="chrome/browser/error_reporting/chrome_js_error_report_processor_nonchromeos.cc"/> <item id="kids_chrome_management_client_classify_url" added_in_milestone="77" hash_code="109987793" type="0" deprecated="2019-07-30" content_hash_code="112740597" file_path=""/> - <item id="lib_address_input" added_in_milestone="62" hash_code="50816767" type="0" content_hash_code="57977576" os_list="linux,windows" file_path="third_party/libaddressinput/chromium/chrome_metadata_source.cc"/> - <item id="litepages_robots_rules" added_in_milestone="89" hash_code="50910588" type="0" content_hash_code="72567080" os_list="linux,windows" file_path="chrome/browser/subresource_redirect/origin_robots_rules.cc"/> - <item id="load_autofill_gstatic_data" added_in_milestone="78" hash_code="119416099" type="0" content_hash_code="128051538" os_list="linux,windows" file_path="chrome/browser/autofill/autofill_gstatic_reader.cc"/> - <item id="logo_service" added_in_milestone="73" hash_code="35473769" type="0" content_hash_code="20271299" os_list="linux,windows" file_path="components/search_provider_logos/logo_service_impl.cc"/> + <item id="lib_address_input" added_in_milestone="62" hash_code="50816767" type="0" content_hash_code="57977576" os_list="linux,windows,chromeos" file_path="third_party/libaddressinput/chromium/chrome_metadata_source.cc"/> + <item id="litepages_robots_rules" added_in_milestone="89" hash_code="50910588" type="0" content_hash_code="72567080" os_list="linux,windows,chromeos" file_path="chrome/browser/subresource_redirect/origin_robots_rules.cc"/> + <item id="load_autofill_gstatic_data" added_in_milestone="78" hash_code="119416099" type="0" content_hash_code="128051538" os_list="linux,windows,chromeos" file_path="chrome/browser/autofill/autofill_gstatic_reader.cc"/> + <item id="logo_service" added_in_milestone="73" hash_code="35473769" type="0" content_hash_code="20271299" os_list="linux,windows,chromeos" file_path="components/search_provider_logos/logo_service_impl.cc"/> <item id="logo_tracker" added_in_milestone="62" hash_code="36859107" type="0" deprecated="2018-12-07" content_hash_code="67588075" file_path=""/> - <item id="lookup_single_password_leak" added_in_milestone="78" hash_code="16927377" type="0" content_hash_code="12158296" os_list="linux,windows" file_path="components/password_manager/core/browser/leak_detection/leak_detection_request.cc"/> - <item id="managed_configuration_loader" added_in_milestone="89" hash_code="77734467" type="0" content_hash_code="101566873" os_list="linux,windows" file_path="chrome/browser/device_api/managed_configuration_api.cc"/> - <item id="media_router_global_media_controls_image" added_in_milestone="81" hash_code="95983790" type="0" content_hash_code="48851217" os_list="linux,windows" file_path="chrome/browser/ui/global_media_controls/cast_media_notification_item.cc"/> - <item id="memories_remote_model_request" added_in_milestone="90" hash_code="41799176" type="0" content_hash_code="53277182" os_list="linux,windows" file_path="components/history_clusters/core/remote_clustering_backend.cc"/> - <item id="metrics_report_ukm" added_in_milestone="62" hash_code="727478" type="0" content_hash_code="8746987" os_list="linux,windows" file_path="components/metrics/net/net_metrics_log_uploader.cc"/> - <item id="metrics_report_uma" added_in_milestone="62" hash_code="727528" type="0" content_hash_code="10176197" os_list="linux,windows" file_path="components/metrics/net/net_metrics_log_uploader.cc"/> - <item id="mirroring_get_setup_info" added_in_milestone="68" hash_code="78447809" type="0" content_hash_code="64839410" os_list="windows,linux" file_path="components/mirroring/service/receiver_setup_querier.cc"/> + <item id="lookup_single_password_leak" added_in_milestone="78" hash_code="16927377" type="0" content_hash_code="12158296" os_list="linux,windows,chromeos" file_path="components/password_manager/core/browser/leak_detection/leak_detection_request.cc"/> + <item id="managed_configuration_loader" added_in_milestone="89" hash_code="77734467" type="0" content_hash_code="101566873" os_list="linux,windows,chromeos" file_path="chrome/browser/device_api/managed_configuration_api.cc"/> + <item id="media_router_global_media_controls_image" added_in_milestone="81" hash_code="95983790" type="0" content_hash_code="48851217" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/global_media_controls/cast_media_notification_item.cc"/> + <item id="memories_remote_model_request" added_in_milestone="90" hash_code="41799176" type="0" content_hash_code="53277182" os_list="linux,windows,chromeos" file_path="components/history_clusters/core/remote_clustering_backend.cc"/> + <item id="metrics_report_ukm" added_in_milestone="62" hash_code="727478" type="0" content_hash_code="8746987" os_list="linux,windows,chromeos" file_path="components/metrics/net/net_metrics_log_uploader.cc"/> + <item id="metrics_report_uma" added_in_milestone="62" hash_code="727528" type="0" content_hash_code="10176197" os_list="linux,windows,chromeos" file_path="components/metrics/net/net_metrics_log_uploader.cc"/> + <item id="mirroring_get_setup_info" added_in_milestone="68" hash_code="78447809" type="0" content_hash_code="64839410" os_list="windows,linux,chromeos" file_path="components/mirroring/service/receiver_setup_querier.cc"/> <item id="missing" added_in_milestone="62" hash_code="77012883" type="0" reserved="1" os_list="linux,windows" file_path=""/> <item id="mojo_context_state" added_in_milestone="63" hash_code="93232258" type="0" deprecated="2017-10-20" content_hash_code="124821232" file_path=""/> - <item id="navigation_predictor_srp_prefetch" added_in_milestone="81" hash_code="57773453" type="0" content_hash_code="38811322" os_list="linux,windows" file_path="chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_tab_helper.cc"/> - <item id="navigation_url_loader" added_in_milestone="62" hash_code="63171670" type="0" content_hash_code="129352907" os_list="linux,windows" file_path="content/browser/loader/navigation_url_loader_impl.cc"/> + <item id="navigation_predictor_srp_prefetch" added_in_milestone="81" hash_code="57773453" type="0" content_hash_code="38811322" os_list="linux,windows,chromeos" file_path="chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_tab_helper.cc"/> + <item id="navigation_url_loader" added_in_milestone="62" hash_code="63171670" type="0" content_hash_code="129352907" os_list="linux,windows,chromeos" file_path="content/browser/loader/navigation_url_loader_impl.cc"/> <item id="nearby_share_contacts" added_in_milestone="86" hash_code="91999155" type="1" second_id="29188932" deprecated="2020-09-21" content_hash_code="74684570" file_path=""/> <item id="nearby_share_list_public_certificates" added_in_milestone="86" hash_code="123714070" type="1" second_id="29188932" deprecated="2020-09-21" content_hash_code="24145546" file_path=""/> <item id="nearby_share_update_device" added_in_milestone="86" hash_code="30656793" type="1" second_id="29188932" deprecated="2020-09-21" content_hash_code="30624346" file_path=""/> <item id="nearby_webrtc_connection" added_in_milestone="86" hash_code="37994740" type="0" deprecated="2020-09-21" content_hash_code="118366066" file_path=""/> <item id="net_error_helper" added_in_milestone="63" hash_code="60071001" type="0" deprecated="2020-07-10" content_hash_code="68322861" file_path=""/> - <item id="network_location_provider" added_in_milestone="64" hash_code="23472048" type="1" second_id="96590038" content_hash_code="41087976" os_list="linux,windows" semantics_fields="1" policy_fields="3,4" file_path="services/device/geolocation/network_location_provider.cc"/> - <item id="network_location_request" added_in_milestone="65" hash_code="96590038" type="2" content_hash_code="80741011" os_list="linux,windows" semantics_fields="2,3,4,5" policy_fields="-1" file_path="services/device/geolocation/network_location_request.cc"/> - <item id="network_time_component" added_in_milestone="62" hash_code="46188932" type="0" content_hash_code="28051857" os_list="linux,windows" file_path="components/network_time/network_time_tracker.cc"/> - <item id="new_tab_page_handler" added_in_milestone="84" hash_code="48673144" type="0" content_hash_code="49174657" os_list="linux,windows" file_path="chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc"/> - <item id="notification_client" added_in_milestone="79" hash_code="78479125" type="0" content_hash_code="129874070" os_list="linux,windows" file_path="remoting/client/notification/notification_client.cc"/> + <item id="network_location_provider" added_in_milestone="64" hash_code="23472048" type="1" second_id="96590038" content_hash_code="41087976" os_list="linux,windows,chromeos" semantics_fields="1" policy_fields="3,4" file_path="services/device/geolocation/network_location_provider.cc"/> + <item id="network_location_request" added_in_milestone="65" hash_code="96590038" type="2" content_hash_code="80741011" os_list="linux,windows,chromeos" semantics_fields="2,3,4,5" policy_fields="-1" file_path="services/device/geolocation/network_location_request.cc"/> + <item id="network_time_component" added_in_milestone="62" hash_code="46188932" type="0" content_hash_code="28051857" os_list="linux,windows,chromeos" file_path="components/network_time/network_time_tracker.cc"/> + <item id="new_tab_page_handler" added_in_milestone="84" hash_code="48673144" type="0" content_hash_code="49174657" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.cc"/> + <item id="notification_client" added_in_milestone="79" hash_code="78479125" type="0" content_hash_code="129874070" os_list="linux,windows,chromeos" file_path="remoting/client/notification/notification_client.cc"/> <item id="ntp_contextual_suggestions_fetch" added_in_milestone="62" hash_code="95711309" type="0" deprecated="2019-04-18" content_hash_code="107035434" file_path=""/> <item id="ntp_custom_background" added_in_milestone="76" hash_code="92125886" type="0" deprecated="2021-07-30" content_hash_code="61176452" file_path=""/> <item id="ntp_custom_link_checker_request" added_in_milestone="71" hash_code="78408551" type="0" deprecated="2018-10-26" content_hash_code="13407730" file_path=""/> - <item id="ntp_snippets_fetch" added_in_milestone="62" hash_code="15418154" type="0" content_hash_code="10078959" os_list="linux,windows" file_path="components/ntp_snippets/remote/json_request.cc"/> + <item id="ntp_snippets_fetch" added_in_milestone="62" hash_code="15418154" type="0" content_hash_code="10078959" os_list="linux,windows,chromeos" file_path="components/ntp_snippets/remote/json_request.cc"/> <item id="nux_ntp_background_preview" added_in_milestone="74" hash_code="124847649" type="0" content_hash_code="31404656" os_list="linux,windows" file_path="chrome/browser/ui/webui/welcome/ntp_background_fetcher.cc"/> - <item id="oauth2_access_token_fetcher" added_in_milestone="62" hash_code="27915688" type="0" content_hash_code="33501872" os_list="linux,windows" file_path="google_apis/gaia/gaia_access_token_fetcher.cc"/> - <item id="oauth2_api_call_flow" added_in_milestone="65" hash_code="29188932" type="2" content_hash_code="108831236" os_list="linux,windows" policy_fields="-1" file_path="google_apis/gaia/oauth2_api_call_flow.cc"/> - <item id="oauth2_mint_token_flow" added_in_milestone="62" hash_code="1112842" type="1" second_id="29188932" content_hash_code="91581432" os_list="linux,windows" semantics_fields="1,2,3,4,5" policy_fields="3,4" file_path="google_apis/gaia/oauth2_mint_token_flow.cc"/> + <item id="oauth2_access_token_fetcher" added_in_milestone="62" hash_code="27915688" type="0" content_hash_code="33501872" os_list="linux,windows,chromeos" file_path="google_apis/gaia/gaia_access_token_fetcher.cc"/> + <item id="oauth2_api_call_flow" added_in_milestone="65" hash_code="29188932" type="2" content_hash_code="108831236" os_list="linux,windows,chromeos" policy_fields="-1" file_path="google_apis/gaia/oauth2_api_call_flow.cc"/> + <item id="oauth2_mint_token_flow" added_in_milestone="62" hash_code="1112842" type="1" second_id="29188932" content_hash_code="91581432" os_list="linux,windows,chromeos" semantics_fields="1,2,3,4,5" policy_fields="3,4" file_path="google_apis/gaia/oauth2_mint_token_flow.cc"/> <item id="ocsp_start_url_loader" added_in_milestone="81" hash_code="3646641" type="0" deprecated="2020-04-28" content_hash_code="106270072" file_path=""/> <item id="ocsp_start_url_request" added_in_milestone="62" hash_code="60921996" type="0" deprecated="2020-04-28" content_hash_code="6288676" file_path=""/> - <item id="offline_prefetch" added_in_milestone="62" hash_code="19185953" type="0" content_hash_code="112039446" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/prefetch_request_fetcher.cc"/> - <item id="omnibox_documentsuggest" added_in_milestone="69" hash_code="6055066" type="0" content_hash_code="126973249" os_list="linux,windows" file_path="components/omnibox/browser/document_suggestions_service.cc"/> - <item id="omnibox_navigation_observer" added_in_milestone="62" hash_code="61684939" type="0" content_hash_code="70941231" os_list="linux,windows" file_path="chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc"/> - <item id="omnibox_result_change" added_in_milestone="62" hash_code="73107389" type="0" content_hash_code="24802647" os_list="linux,windows" file_path="chrome/browser/bitmap_fetcher/bitmap_fetcher_service.cc"/> - <item id="omnibox_suggest" added_in_milestone="62" hash_code="47815025" type="0" content_hash_code="86297726" os_list="linux,windows" file_path="components/omnibox/browser/search_provider.cc"/> - <item id="omnibox_suggest_deletion" added_in_milestone="62" hash_code="84212388" type="0" content_hash_code="24981550" os_list="linux,windows" file_path="components/omnibox/browser/base_search_provider.cc"/> - <item id="omnibox_zerosuggest" added_in_milestone="62" hash_code="7687691" type="0" content_hash_code="119419625" os_list="linux,windows" file_path="components/omnibox/browser/remote_suggestions_service.cc"/> - <item id="one_google_bar_service" added_in_milestone="62" hash_code="78917933" type="0" content_hash_code="46527252" os_list="linux,windows" file_path="chrome/browser/new_tab_page/one_google_bar/one_google_bar_loader_impl.cc"/> + <item id="offline_prefetch" added_in_milestone="62" hash_code="19185953" type="0" content_hash_code="112039446" os_list="linux,windows,chromeos" file_path="components/offline_pages/core/prefetch/prefetch_request_fetcher.cc"/> + <item id="omnibox_documentsuggest" added_in_milestone="69" hash_code="6055066" type="0" content_hash_code="126973249" os_list="linux,windows,chromeos" file_path="components/omnibox/browser/document_suggestions_service.cc"/> + <item id="omnibox_navigation_observer" added_in_milestone="62" hash_code="61684939" type="0" content_hash_code="70941231" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc"/> + <item id="omnibox_result_change" added_in_milestone="62" hash_code="73107389" type="0" content_hash_code="24802647" os_list="linux,windows,chromeos" file_path="chrome/browser/bitmap_fetcher/bitmap_fetcher_service.cc"/> + <item id="omnibox_suggest" added_in_milestone="62" hash_code="47815025" type="0" content_hash_code="86297726" os_list="linux,windows,chromeos" file_path="components/omnibox/browser/search_provider.cc"/> + <item id="omnibox_suggest_deletion" added_in_milestone="62" hash_code="84212388" type="0" content_hash_code="24981550" os_list="linux,windows,chromeos" file_path="components/omnibox/browser/base_search_provider.cc"/> + <item id="omnibox_zerosuggest" added_in_milestone="62" hash_code="7687691" type="0" content_hash_code="119419625" os_list="linux,windows,chromeos" file_path="components/omnibox/browser/remote_suggestions_service.cc"/> + <item id="one_google_bar_service" added_in_milestone="62" hash_code="78917933" type="0" content_hash_code="46527252" os_list="linux,windows,chromeos" file_path="chrome/browser/new_tab_page/one_google_bar/one_google_bar_loader_impl.cc"/> <item id="open_screen_message" added_in_milestone="78" hash_code="95250780" type="0" deprecated="2020-02-13" content_hash_code="39027953" file_path=""/> <item id="open_screen_tls_message" added_in_milestone="80" hash_code="61695471" type="0" deprecated="2020-02-13" content_hash_code="28355565" file_path=""/> - <item id="open_search" added_in_milestone="62" hash_code="107267424" type="0" content_hash_code="83025542" os_list="linux,windows" file_path="components/search_engines/template_url_fetcher.cc"/> - <item id="openscreen_message" added_in_milestone="83" hash_code="23036184" type="0" content_hash_code="124395439" os_list="linux,windows" file_path="components/openscreen_platform/udp_socket.cc"/> - <item id="openscreen_tls_message" added_in_milestone="83" hash_code="40127335" type="0" content_hash_code="15991338" os_list="linux,windows" file_path="components/openscreen_platform/tls_connection_factory.cc"/> + <item id="open_search" added_in_milestone="62" hash_code="107267424" type="0" content_hash_code="83025542" os_list="linux,windows,chromeos" file_path="components/search_engines/template_url_fetcher.cc"/> + <item id="openscreen_message" added_in_milestone="83" hash_code="23036184" type="0" content_hash_code="124395439" os_list="linux,windows,chromeos" file_path="components/openscreen_platform/udp_socket.cc"/> + <item id="openscreen_tls_message" added_in_milestone="83" hash_code="40127335" type="0" content_hash_code="15991338" os_list="linux,windows,chromeos" file_path="components/openscreen_platform/tls_connection_factory.cc"/> <item id="optimization_guide_model" added_in_milestone="79" hash_code="106373593" type="0" content_hash_code="32403047" os_list="linux,windows" file_path="components/optimization_guide/core/prediction_model_fetcher_impl.cc"/> - <item id="optimization_guide_model_download" added_in_milestone="88" hash_code="100143055" type="0" content_hash_code="97983899" os_list="linux,windows" file_path="chrome/browser/optimization_guide/prediction/prediction_model_download_manager.cc"/> - <item id="origin_policy_loader" added_in_milestone="69" hash_code="6483617" type="0" content_hash_code="134028975" os_list="linux,windows" file_path="services/network/origin_policy/origin_policy_fetcher.cc"/> - <item id="parallel_download_job" added_in_milestone="62" hash_code="135118587" type="0" content_hash_code="105330419" os_list="linux,windows" file_path="components/download/internal/common/parallel_download_job.cc"/> - <item id="password_protection_request" added_in_milestone="62" hash_code="66322287" type="0" content_hash_code="25596947" os_list="linux,windows" file_path="components/safe_browsing/core/browser/password_protection/password_protection_request.cc"/> - <item id="password_requirements_spec_fetch" added_in_milestone="69" hash_code="69585116" type="0" content_hash_code="5591260" os_list="linux,windows" file_path="components/password_manager/core/browser/generation/password_requirements_spec_fetcher_impl.cc"/> + <item id="optimization_guide_model_download" added_in_milestone="88" hash_code="100143055" type="0" content_hash_code="97983899" os_list="linux,windows,chromeos" file_path="chrome/browser/optimization_guide/prediction/prediction_model_download_manager.cc"/> + <item id="origin_policy_loader" added_in_milestone="69" hash_code="6483617" type="0" content_hash_code="134028975" os_list="linux,windows,chromeos" file_path="services/network/origin_policy/origin_policy_fetcher.cc"/> + <item id="parallel_download_job" added_in_milestone="62" hash_code="135118587" type="0" content_hash_code="105330419" os_list="linux,windows,chromeos" file_path="components/download/internal/common/parallel_download_job.cc"/> + <item id="password_protection_request" added_in_milestone="62" hash_code="66322287" type="0" content_hash_code="25596947" os_list="linux,windows,chromeos" file_path="components/safe_browsing/core/browser/password_protection/password_protection_request.cc"/> + <item id="password_requirements_spec_fetch" added_in_milestone="69" hash_code="69585116" type="0" content_hash_code="5591260" os_list="linux,windows,chromeos" file_path="components/password_manager/core/browser/generation/password_requirements_spec_fetcher_impl.cc"/> <item id="payment_instrument_icon_fetcher" added_in_milestone="62" hash_code="73309970" type="0" deprecated="2017-09-16" content_hash_code="84709873" file_path=""/> - <item id="payment_manifest_downloader" added_in_milestone="62" hash_code="84045030" type="0" content_hash_code="19293316" os_list="linux,windows" file_path="components/payments/core/payment_manifest_downloader.cc"/> - <item id="payments_sync_cards" added_in_milestone="62" hash_code="95588446" type="0" content_hash_code="56526513" os_list="linux,windows" file_path="components/autofill/core/browser/payments/payments_client.cc"/> - <item id="pdf_plugin_placeholder" added_in_milestone="63" hash_code="56866367" type="0" content_hash_code="16907221" os_list="linux,windows" file_path="chrome/browser/plugins/plugin_observer.cc"/> - <item id="pepper_tcp_socket" added_in_milestone="65" hash_code="120623198" type="0" content_hash_code="27489892" os_list="linux,windows" file_path="content/browser/renderer_host/pepper/pepper_socket_utils.cc"/> - <item id="pepper_udp_socket" added_in_milestone="70" hash_code="53512439" type="0" content_hash_code="7268418" os_list="linux,windows" file_path="content/browser/renderer_host/pepper/pepper_socket_utils.cc"/> - <item id="per_user_topic_registration_request" added_in_milestone="68" hash_code="10498172" type="0" content_hash_code="57098847" os_list="linux,windows" file_path="components/invalidation/impl/per_user_topic_subscription_request.cc"/> - <item id="permission_predictions" added_in_milestone="88" hash_code="89492280" type="0" content_hash_code="806663" os_list="linux,windows" file_path="components/permissions/prediction_service/prediction_service.cc"/> + <item id="payment_manifest_downloader" added_in_milestone="62" hash_code="84045030" type="0" content_hash_code="19293316" os_list="linux,windows,chromeos" file_path="components/payments/core/payment_manifest_downloader.cc"/> + <item id="payments_sync_cards" added_in_milestone="62" hash_code="95588446" type="0" content_hash_code="56526513" os_list="linux,windows,chromeos" file_path="components/autofill/core/browser/payments/payments_client.cc"/> + <item id="pdf_plugin_placeholder" added_in_milestone="63" hash_code="56866367" type="0" content_hash_code="16907221" os_list="linux,windows,chromeos" file_path="chrome/browser/plugins/plugin_observer.cc"/> + <item id="pepper_tcp_socket" added_in_milestone="65" hash_code="120623198" type="0" content_hash_code="27489892" os_list="linux,windows,chromeos" file_path="content/browser/renderer_host/pepper/pepper_socket_utils.cc"/> + <item id="pepper_udp_socket" added_in_milestone="70" hash_code="53512439" type="0" content_hash_code="7268418" os_list="linux,windows,chromeos" file_path="content/browser/renderer_host/pepper/pepper_socket_utils.cc"/> + <item id="per_user_topic_registration_request" added_in_milestone="68" hash_code="10498172" type="0" content_hash_code="57098847" os_list="linux,windows,chromeos" file_path="components/invalidation/impl/per_user_topic_subscription_request.cc"/> + <item id="permission_predictions" added_in_milestone="88" hash_code="89492280" type="0" content_hash_code="806663" os_list="linux,windows,chromeos" file_path="components/permissions/prediction_service/prediction_service.cc"/> <item id="permission_reporting" added_in_milestone="62" hash_code="131741641" type="0" deprecated="2018-03-06" content_hash_code="7213535" file_path=""/> <item id="permission_request_creator" added_in_milestone="62" hash_code="43206794" type="0" deprecated="2019-07-30" content_hash_code="73571699" file_path=""/> <item id="persist_blob_to_indexed_db" added_in_milestone="62" hash_code="32030464" type="0" deprecated="2018-08-13" content_hash_code="35410079" file_path=""/> - <item id="photos_service" added_in_milestone="94" hash_code="100936478" type="0" content_hash_code="91467634" os_list="linux,windows" file_path="chrome/browser/new_tab_page/modules/photos/photos_service.cc"/> - <item id="plugins_resource_service" added_in_milestone="62" hash_code="49601082" type="0" content_hash_code="6877335" os_list="linux,windows" file_path="chrome/browser/plugins/plugins_resource_service.cc"/> - <item id="popular_sites_fetch" added_in_milestone="62" hash_code="50755044" type="0" content_hash_code="6910083" os_list="linux,windows" file_path="components/ntp_tiles/popular_sites_impl.cc"/> - <item id="port_forwarding_controller_socket" added_in_milestone="65" hash_code="95075845" type="0" content_hash_code="122163428" os_list="linux,windows" file_path="chrome/browser/devtools/device/port_forwarding_controller.cc"/> - <item id="ppapi_download_request" added_in_milestone="62" hash_code="135967426" type="0" content_hash_code="131391591" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc"/> - <item id="predictive_prefetch" added_in_milestone="85" hash_code="72157052" type="0" content_hash_code="28097398" os_list="linux,windows" file_path="chrome/browser/predictors/prefetch_manager.cc"/> - <item id="prefetch_download" added_in_milestone="62" hash_code="44583172" type="0" content_hash_code="21424542" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/prefetch_downloader_impl.cc"/> - <item id="prefetch_proxy_canary_check" added_in_milestone="88" hash_code="9229948" type="0" content_hash_code="53040767" os_list="linux,windows" file_path="chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc"/> + <item id="photos_service" added_in_milestone="94" hash_code="100936478" type="0" content_hash_code="91467634" os_list="linux,windows,chromeos" file_path="chrome/browser/new_tab_page/modules/photos/photos_service.cc"/> + <item id="plugins_resource_service" added_in_milestone="62" hash_code="49601082" type="0" content_hash_code="6877335" os_list="linux,windows,chromeos" file_path="chrome/browser/plugins/plugins_resource_service.cc"/> + <item id="popular_sites_fetch" added_in_milestone="62" hash_code="50755044" type="0" content_hash_code="6910083" os_list="linux,windows,chromeos" file_path="components/ntp_tiles/popular_sites_impl.cc"/> + <item id="port_forwarding_controller_socket" added_in_milestone="65" hash_code="95075845" type="0" content_hash_code="122163428" os_list="linux,windows,chromeos" file_path="chrome/browser/devtools/device/port_forwarding_controller.cc"/> + <item id="ppapi_download_request" added_in_milestone="62" hash_code="135967426" type="0" content_hash_code="131391591" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/download_protection/ppapi_download_request.cc"/> + <item id="predictive_prefetch" added_in_milestone="85" hash_code="72157052" type="0" content_hash_code="28097398" os_list="linux,windows,chromeos" file_path="chrome/browser/predictors/prefetch_manager.cc"/> + <item id="prefetch_download" added_in_milestone="62" hash_code="44583172" type="0" content_hash_code="21424542" os_list="linux,windows,chromeos" file_path="components/offline_pages/core/prefetch/prefetch_downloader_impl.cc"/> + <item id="prefetch_proxy_canary_check" added_in_milestone="88" hash_code="9229948" type="0" content_hash_code="53040767" os_list="linux,windows,chromeos" file_path="chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc"/> <item id="prefetch_proxy_loader" added_in_milestone="88" hash_code="119210936" type="0" deprecated="2021-02-17" content_hash_code="18878601" file_path=""/> - <item id="prefetch_proxy_probe" added_in_milestone="88" hash_code="123387409" type="0" content_hash_code="1909853" os_list="linux,windows" file_path="chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc"/> - <item id="prefetch_visuals" added_in_milestone="75" hash_code="91068704" type="0" content_hash_code="90439946" os_list="linux,windows" file_path="components/offline_pages/core/prefetch/visuals_fetch_by_url.cc"/> + <item id="prefetch_proxy_probe" added_in_milestone="88" hash_code="123387409" type="0" content_hash_code="1909853" os_list="linux,windows,chromeos" file_path="chrome/browser/prefetch/prefetch_proxy/prefetch_proxy_origin_prober.cc"/> + <item id="prefetch_visuals" added_in_milestone="75" hash_code="91068704" type="0" content_hash_code="90439946" os_list="linux,windows,chromeos" file_path="components/offline_pages/core/prefetch/visuals_fetch_by_url.cc"/> <item id="previews_litepage_origin_prober" added_in_milestone="78" hash_code="33703614" type="0" deprecated="2020-04-23" content_hash_code="116235355" file_path="chrome/browser/previews/previews_lite_page_redirect_url_loader.cc"/> <item id="previews_litepage_prober" added_in_milestone="78" hash_code="33813109" type="0" deprecated="2020-04-23" content_hash_code="52572789" file_path="chrome/browser/previews/previews_lite_page_redirect_decider.cc"/> <item id="previews_prober" added_in_milestone="77" hash_code="41010697" type="0" deprecated="2019-07-24" content_hash_code="51581107" file_path=""/> <item id="printer_job_handler" added_in_milestone="62" hash_code="67638271" type="1" second_id="111712433" content_hash_code="75712693" os_list="linux,windows" semantics_fields="2,3,4" file_path="chrome/service/cloud_print/printer_job_handler.cc"/> - <item id="profile_avatar" added_in_milestone="62" hash_code="51164680" type="0" content_hash_code="113550845" os_list="linux,windows" file_path="chrome/browser/profiles/profile_avatar_downloader.cc"/> - <item id="profile_resetter_upload" added_in_milestone="62" hash_code="105330607" type="0" content_hash_code="129329171" os_list="linux,windows" file_path="chrome/browser/profile_resetter/reset_report_uploader.cc"/> - <item id="promo_service" added_in_milestone="72" hash_code="67052219" type="0" content_hash_code="32939033" os_list="linux,windows" file_path="chrome/browser/new_tab_page/promos/promo_service.cc"/> - <item id="proxy_config_direct" added_in_milestone="67" hash_code="119015679" type="0" content_hash_code="119931568" os_list="linux,windows" file_path="net/proxy_resolution/proxy_config_with_annotation.cc"/> - <item id="proxy_config_headless" added_in_milestone="67" hash_code="133221587" type="0" content_hash_code="77459277" os_list="linux,windows" file_path="headless/lib/browser/headless_request_context_manager.cc"/> - <item id="proxy_config_settings" added_in_milestone="67" hash_code="136468456" type="0" content_hash_code="19527377" os_list="linux,windows" file_path="components/proxy_config/pref_proxy_config_tracker_impl.cc"/> - <item id="proxy_config_system" added_in_milestone="67" hash_code="11258689" type="0" content_hash_code="77057929" os_list="linux,windows" file_path="net/proxy_resolution/configured_proxy_resolution_service.cc"/> + <item id="profile_avatar" added_in_milestone="62" hash_code="51164680" type="0" content_hash_code="113550845" os_list="linux,windows,chromeos" file_path="chrome/browser/profiles/profile_avatar_downloader.cc"/> + <item id="profile_resetter_upload" added_in_milestone="62" hash_code="105330607" type="0" content_hash_code="129329171" os_list="linux,windows,chromeos" file_path="chrome/browser/profile_resetter/reset_report_uploader.cc"/> + <item id="promo_service" added_in_milestone="72" hash_code="67052219" type="0" content_hash_code="32939033" os_list="linux,windows,chromeos" file_path="chrome/browser/new_tab_page/promos/promo_service.cc"/> + <item id="proxy_config_direct" added_in_milestone="67" hash_code="119015679" type="0" content_hash_code="119931568" os_list="linux,windows,chromeos" file_path="net/proxy_resolution/proxy_config_with_annotation.cc"/> + <item id="proxy_config_headless" added_in_milestone="67" hash_code="133221587" type="0" content_hash_code="77459277" os_list="linux,windows,chromeos" file_path="headless/lib/browser/headless_request_context_manager.cc"/> + <item id="proxy_config_settings" added_in_milestone="67" hash_code="136468456" type="0" content_hash_code="19527377" os_list="linux,windows,chromeos" file_path="components/proxy_config/pref_proxy_config_tracker_impl.cc"/> + <item id="proxy_config_system" added_in_milestone="67" hash_code="11258689" type="0" content_hash_code="77057929" os_list="linux,windows,chromeos" file_path="net/proxy_resolution/configured_proxy_resolution_service.cc"/> <item id="proxy_config_windows_resolver" added_in_milestone="86" hash_code="13924805" type="0" content_hash_code="123023599" os_list="windows" file_path="net/proxy_resolution/win/windows_system_proxy_resolution_request.cc"/> <item id="proxy_script_fetcher" added_in_milestone="62" hash_code="37531401" type="0" deprecated="2018-03-16" content_hash_code="31866133" file_path=""/> <item id="puch_client_channel" added_in_milestone="67" hash_code="34459548" type="0" deprecated="2020-01-23" content_hash_code="92475475" file_path=""/> - <item id="qr_code_save" added_in_milestone="84" hash_code="87963126" type="0" content_hash_code="72717245" os_list="linux,windows" file_path="chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc"/> - <item id="query_tiles_fetcher" added_in_milestone="84" hash_code="10243490" type="0" content_hash_code="16824373" os_list="linux,windows" file_path="components/query_tiles/internal/tile_fetcher.cc"/> - <item id="query_tiles_image_loader" added_in_milestone="83" hash_code="95103115" type="0" content_hash_code="75070538" os_list="linux,windows" file_path="components/query_tiles/internal/cached_image_loader.cc"/> - <item id="quic_chromium_incoming_pending_session" added_in_milestone="73" hash_code="120830730" type="0" content_hash_code="52904665" os_list="linux,windows" file_path="net/quic/quic_chromium_client_session.cc"/> - <item id="quic_chromium_incoming_session" added_in_milestone="66" hash_code="87635401" type="0" content_hash_code="78573093" os_list="linux,windows" file_path="net/quic/quic_chromium_client_session.cc"/> - <item id="quic_chromium_packet_writer" added_in_milestone="66" hash_code="20153177" type="0" content_hash_code="29657765" os_list="linux,windows" file_path="net/quic/quic_chromium_packet_writer.cc"/> - <item id="ranker_url_fetcher" added_in_milestone="62" hash_code="95682324" type="0" content_hash_code="45958626" os_list="linux,windows" file_path="components/assist_ranker/ranker_url_fetcher.cc"/> + <item id="qr_code_save" added_in_milestone="84" hash_code="87963126" type="0" content_hash_code="72717245" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/views/qrcode_generator/qrcode_generator_bubble.cc"/> + <item id="query_tiles_fetcher" added_in_milestone="84" hash_code="10243490" type="0" content_hash_code="16824373" os_list="linux,windows,chromeos" file_path="components/query_tiles/internal/tile_fetcher.cc"/> + <item id="query_tiles_image_loader" added_in_milestone="83" hash_code="95103115" type="0" content_hash_code="75070538" os_list="linux,windows,chromeos" file_path="components/query_tiles/internal/cached_image_loader.cc"/> + <item id="quic_chromium_incoming_pending_session" added_in_milestone="73" hash_code="120830730" type="0" content_hash_code="52904665" os_list="linux,windows,chromeos" file_path="net/quic/quic_chromium_client_session.cc"/> + <item id="quic_chromium_incoming_session" added_in_milestone="66" hash_code="87635401" type="0" content_hash_code="78573093" os_list="linux,windows,chromeos" file_path="net/quic/quic_chromium_client_session.cc"/> + <item id="quic_chromium_packet_writer" added_in_milestone="66" hash_code="20153177" type="0" content_hash_code="29657765" os_list="linux,windows,chromeos" file_path="net/quic/quic_chromium_packet_writer.cc"/> + <item id="ranker_url_fetcher" added_in_milestone="62" hash_code="95682324" type="0" content_hash_code="45958626" os_list="linux,windows,chromeos" file_path="components/assist_ranker/ranker_url_fetcher.cc"/> <item id="receive_messages_express" added_in_milestone="85" hash_code="29506140" type="0" deprecated="2020-09-21" content_hash_code="38581365" file_path=""/> <item id="refresh_token_annotation_request" added_in_milestone="62" hash_code="7433837" type="1" second_id="29188932" deprecated="2018-01-17" content_hash_code="137103383" file_path=""/> - <item id="remote_copy_message_handler" added_in_milestone="80" hash_code="80255301" type="0" content_hash_code="117673331" os_list="linux,windows" file_path="chrome/browser/sharing/shared_clipboard/remote_copy_message_handler.cc"/> - <item id="remote_suggestions_provider" added_in_milestone="62" hash_code="49544361" type="0" content_hash_code="126329742" os_list="linux,windows" file_path="components/ntp_snippets/remote/cached_image_fetcher.cc"/> - <item id="remoting_directory_delete_host" added_in_milestone="86" hash_code="89093734" type="0" content_hash_code="65893931" os_list="linux,windows" file_path="remoting/base/directory_service_client.cc"/> - <item id="remoting_directory_get_host_list" added_in_milestone="86" hash_code="93434368" type="0" content_hash_code="59980448" os_list="linux,windows" file_path="remoting/base/directory_service_client.cc"/> - <item id="remoting_directory_register_host" added_in_milestone="86" hash_code="117688925" type="0" content_hash_code="74224493" os_list="linux,windows" file_path="remoting/base/directory_service_client.cc"/> - <item id="remoting_ice_config_request" added_in_milestone="86" hash_code="88945310" type="0" content_hash_code="94742293" os_list="linux,windows" file_path="remoting/protocol/remoting_ice_config_request.cc"/> - <item id="remoting_log_to_server" added_in_milestone="86" hash_code="99742369" type="0" content_hash_code="117118166" os_list="linux,windows" file_path="remoting/signaling/remoting_log_to_server.cc"/> - <item id="remoting_register_support_host_request" added_in_milestone="86" hash_code="67117364" type="0" content_hash_code="15955284" os_list="linux,windows" file_path="remoting/host/remoting_register_support_host_request.cc"/> - <item id="remoting_telemetry_log_writer" added_in_milestone="86" hash_code="107268760" type="0" content_hash_code="81741595" os_list="linux,windows" file_path="remoting/base/telemetry_log_writer.cc"/> - <item id="render_view_context_menu" added_in_milestone="62" hash_code="25844439" type="0" content_hash_code="69471170" os_list="linux,windows" file_path="chrome/browser/renderer_context_menu/render_view_context_menu.cc"/> - <item id="renderer_initiated_download" added_in_milestone="62" hash_code="116443055" type="0" content_hash_code="37846436" os_list="linux,windows" file_path="content/browser/renderer_host/render_frame_host_impl.cc"/> - <item id="reporting" added_in_milestone="62" hash_code="109891200" type="0" content_hash_code="125758928" os_list="linux,windows" file_path="net/reporting/reporting_uploader.cc"/> + <item id="remote_copy_message_handler" added_in_milestone="80" hash_code="80255301" type="0" content_hash_code="117673331" os_list="linux,windows,chromeos" file_path="chrome/browser/sharing/shared_clipboard/remote_copy_message_handler.cc"/> + <item id="remote_suggestions_provider" added_in_milestone="62" hash_code="49544361" type="0" content_hash_code="126329742" os_list="linux,windows,chromeos" file_path="components/ntp_snippets/remote/cached_image_fetcher.cc"/> + <item id="remoting_directory_delete_host" added_in_milestone="86" hash_code="89093734" type="0" content_hash_code="65893931" os_list="linux,windows,chromeos" file_path="remoting/base/directory_service_client.cc"/> + <item id="remoting_directory_get_host_list" added_in_milestone="86" hash_code="93434368" type="0" content_hash_code="59980448" os_list="linux,windows,chromeos" file_path="remoting/base/directory_service_client.cc"/> + <item id="remoting_directory_register_host" added_in_milestone="86" hash_code="117688925" type="0" content_hash_code="74224493" os_list="linux,windows,chromeos" file_path="remoting/base/directory_service_client.cc"/> + <item id="remoting_ice_config_request" added_in_milestone="86" hash_code="88945310" type="0" content_hash_code="94742293" os_list="linux,windows,chromeos" file_path="remoting/protocol/remoting_ice_config_request.cc"/> + <item id="remoting_log_to_server" added_in_milestone="86" hash_code="99742369" type="0" content_hash_code="117118166" os_list="linux,windows,chromeos" file_path="remoting/signaling/remoting_log_to_server.cc"/> + <item id="remoting_register_support_host_request" added_in_milestone="86" hash_code="67117364" type="0" content_hash_code="15955284" os_list="linux,windows,chromeos" file_path="remoting/host/remoting_register_support_host_request.cc"/> + <item id="remoting_telemetry_log_writer" added_in_milestone="86" hash_code="107268760" type="0" content_hash_code="81741595" os_list="linux,windows,chromeos" file_path="remoting/base/telemetry_log_writer.cc"/> + <item id="render_view_context_menu" added_in_milestone="62" hash_code="25844439" type="0" content_hash_code="69471170" os_list="linux,windows,chromeos" file_path="chrome/browser/renderer_context_menu/render_view_context_menu.cc"/> + <item id="renderer_initiated_download" added_in_milestone="62" hash_code="116443055" type="0" content_hash_code="37846436" os_list="linux,windows,chromeos" file_path="content/browser/renderer_host/render_frame_host_impl.cc"/> + <item id="reporting" added_in_milestone="62" hash_code="109891200" type="0" content_hash_code="125758928" os_list="linux,windows,chromeos" file_path="net/reporting/reporting_uploader.cc"/> <item id="resource_dispatcher_host" added_in_milestone="62" hash_code="81157007" type="0" deprecated="2019-07-30" content_hash_code="35725167" file_path=""/> <item id="resource_prefetch" added_in_milestone="62" hash_code="110815970" type="0" deprecated="2018-02-28" content_hash_code="39251261" file_path=""/> - <item id="rlz_ping" added_in_milestone="63" hash_code="99279418" type="0" content_hash_code="102108802" os_list="windows" file_path="rlz/lib/financial_ping.cc"/> + <item id="rlz_ping" added_in_milestone="63" hash_code="99279418" type="0" content_hash_code="102108802" os_list="windows,chromeos" file_path="rlz/lib/financial_ping.cc"/> <item id="safe_browsing_backup_request" added_in_milestone="62" hash_code="106980485" type="0" deprecated="2018-08-14" content_hash_code="101760679" file_path=""/> <item id="safe_browsing_binary_upload" added_in_milestone="78" hash_code="71663319" type="0" deprecated="2020-09-16" content_hash_code="105913171" file_path=""/> - <item id="safe_browsing_binary_upload_app" added_in_milestone="87" hash_code="4306022" type="0" content_hash_code="64626873" os_list="linux,windows" file_path="chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc"/> - <item id="safe_browsing_binary_upload_connector" added_in_milestone="87" hash_code="59568147" type="0" content_hash_code="52138007" os_list="linux,windows" file_path="chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc"/> - <item id="safe_browsing_cache_collector" added_in_milestone="62" hash_code="115907811" type="0" content_hash_code="62296373" os_list="linux,windows" file_path="components/safe_browsing/content/browser/threat_details_cache.cc"/> - <item id="safe_browsing_certificate_error_reporting" added_in_milestone="62" hash_code="66590631" type="0" content_hash_code="26108454" os_list="linux,windows" file_path="chrome/browser/ssl/certificate_error_reporter.cc"/> + <item id="safe_browsing_binary_upload_app" added_in_milestone="87" hash_code="4306022" type="0" content_hash_code="64626873" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc"/> + <item id="safe_browsing_binary_upload_connector" added_in_milestone="87" hash_code="59568147" type="0" content_hash_code="52138007" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc"/> + <item id="safe_browsing_cache_collector" added_in_milestone="62" hash_code="115907811" type="0" content_hash_code="62296373" os_list="linux,windows,chromeos" file_path="components/safe_browsing/content/browser/threat_details_cache.cc"/> + <item id="safe_browsing_certificate_error_reporting" added_in_milestone="62" hash_code="66590631" type="0" content_hash_code="26108454" os_list="linux,windows,chromeos" file_path="chrome/browser/ssl/certificate_error_reporter.cc"/> <item id="safe_browsing_chunk_backup_request" added_in_milestone="62" hash_code="79957943" type="0" deprecated="2018-08-14" content_hash_code="133850277" file_path=""/> <item id="safe_browsing_client_side_malware_detector" added_in_milestone="62" hash_code="102935425" type="0" deprecated="2019-12-07" content_hash_code="79591279" file_path=""/> - <item id="safe_browsing_client_side_phishing_detector" added_in_milestone="62" hash_code="1313982" type="0" content_hash_code="50199143" os_list="linux,windows" file_path="components/safe_browsing/content/browser/client_side_detection_service.cc"/> - <item id="safe_browsing_extended_reporting" added_in_milestone="62" hash_code="42848942" type="0" content_hash_code="81193513" os_list="linux,windows" file_path="components/safe_browsing/core/browser/ping_manager.cc"/> - <item id="safe_browsing_feedback" added_in_milestone="62" hash_code="44583821" type="0" content_hash_code="27116846" os_list="linux,windows" file_path="chrome/browser/safe_browsing/download_protection/download_feedback.cc"/> + <item id="safe_browsing_client_side_phishing_detector" added_in_milestone="62" hash_code="1313982" type="0" content_hash_code="50199143" os_list="linux,windows,chromeos" file_path="components/safe_browsing/content/browser/client_side_detection_service.cc"/> + <item id="safe_browsing_extended_reporting" added_in_milestone="62" hash_code="42848942" type="0" content_hash_code="81193513" os_list="linux,windows,chromeos" file_path="components/safe_browsing/core/browser/ping_manager.cc"/> + <item id="safe_browsing_feedback" added_in_milestone="62" hash_code="44583821" type="0" content_hash_code="27116846" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/download_protection/download_feedback.cc"/> <item id="safe_browsing_get_full_hash" added_in_milestone="62" hash_code="68745894" type="0" deprecated="2018-08-14" content_hash_code="21739198" file_path=""/> - <item id="safe_browsing_incident" added_in_milestone="62" hash_code="124950347" type="0" content_hash_code="7306531" os_list="linux,windows" file_path="chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.cc"/> + <item id="safe_browsing_incident" added_in_milestone="62" hash_code="124950347" type="0" content_hash_code="7306531" os_list="linux,windows,chromeos" file_path="chrome/browser/safe_browsing/incident_reporting/incident_report_uploader_impl.cc"/> <item id="safe_browsing_module_loader" added_in_milestone="62" hash_code="6019475" type="0" deprecated="2021-10-01" content_hash_code="49511650" file_path=""/> - <item id="safe_browsing_realtime_url_lookup" added_in_milestone="78" hash_code="119324658" type="0" content_hash_code="71236226" os_list="linux,windows" file_path="components/safe_browsing/core/browser/realtime/url_lookup_service.cc"/> - <item id="safe_browsing_v4_get_hash" added_in_milestone="62" hash_code="8561691" type="0" content_hash_code="132435617" os_list="linux,windows" file_path="components/safe_browsing/core/browser/db/v4_get_hash_protocol_manager.cc"/> - <item id="safe_browsing_v4_update" added_in_milestone="70" hash_code="82509217" type="0" content_hash_code="5247849" os_list="linux,windows" file_path="components/safe_browsing/core/browser/db/v4_update_protocol_manager.cc"/> - <item id="safe_search_service" added_in_milestone="70" hash_code="136386805" type="0" content_hash_code="127491095" os_list="linux,windows" file_path="components/policy/content/safe_search_service.cc"/> - <item id="safety_check_update_connectivity" added_in_milestone="84" hash_code="137724067" type="0" content_hash_code="30977369" os_list="linux,windows" file_path="components/safety_check/update_check_helper.cc"/> - <item id="sanitized_image_source" added_in_milestone="86" hash_code="36944304" type="0" content_hash_code="39770427" os_list="linux,windows" file_path="chrome/browser/ui/webui/sanitized_image_source.cc"/> - <item id="save_file_manager" added_in_milestone="62" hash_code="56275203" type="0" content_hash_code="56692339" os_list="linux,windows" file_path="content/browser/download/save_file_manager.cc"/> - <item id="sct_auditing" added_in_milestone="87" hash_code="48603483" type="0" content_hash_code="43567503" os_list="linux,windows" file_path="chrome/browser/ssl/sct_reporting_service.cc"/> + <item id="safe_browsing_realtime_url_lookup" added_in_milestone="78" hash_code="119324658" type="0" content_hash_code="71236226" os_list="linux,windows,chromeos" file_path="components/safe_browsing/core/browser/realtime/url_lookup_service.cc"/> + <item id="safe_browsing_v4_get_hash" added_in_milestone="62" hash_code="8561691" type="0" content_hash_code="132435617" os_list="linux,windows,chromeos" file_path="components/safe_browsing/core/browser/db/v4_get_hash_protocol_manager.cc"/> + <item id="safe_browsing_v4_update" added_in_milestone="70" hash_code="82509217" type="0" content_hash_code="5247849" os_list="linux,windows,chromeos" file_path="components/safe_browsing/core/browser/db/v4_update_protocol_manager.cc"/> + <item id="safe_search_service" added_in_milestone="70" hash_code="136386805" type="0" content_hash_code="127491095" os_list="linux,windows,chromeos" file_path="components/policy/content/safe_search_service.cc"/> + <item id="safety_check_update_connectivity" added_in_milestone="84" hash_code="137724067" type="0" content_hash_code="30977369" os_list="linux,windows,chromeos" file_path="components/safety_check/update_check_helper.cc"/> + <item id="sanitized_image_source" added_in_milestone="86" hash_code="36944304" type="0" content_hash_code="39770427" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/webui/sanitized_image_source.cc"/> + <item id="save_file_manager" added_in_milestone="62" hash_code="56275203" type="0" content_hash_code="56692339" os_list="linux,windows,chromeos" file_path="content/browser/download/save_file_manager.cc"/> + <item id="sct_auditing" added_in_milestone="87" hash_code="48603483" type="0" content_hash_code="43567503" os_list="linux,windows,chromeos" file_path="chrome/browser/ssl/sct_reporting_service.cc"/> <item id="sdch_dictionary_fetch" added_in_milestone="62" hash_code="47152935" type="0" deprecated="2017-09-16" content_hash_code="16764294" file_path=""/> - <item id="search_prefetch_service" added_in_milestone="88" hash_code="108986091" type="0" content_hash_code="125257414" os_list="windows,linux" file_path="chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.cc"/> + <item id="search_prefetch_service" added_in_milestone="88" hash_code="108986091" type="0" content_hash_code="125257414" os_list="windows,linux,chromeos" file_path="chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.cc"/> <item id="search_suggest_service" added_in_milestone="73" hash_code="57785193" type="0" deprecated="2021-09-02" content_hash_code="132247652" file_path=""/> - <item id="security_key_socket" added_in_milestone="66" hash_code="31074955" type="0" content_hash_code="13741232" os_list="linux,windows" file_path="remoting/host/security_key/security_key_socket.cc"/> + <item id="security_key_socket" added_in_milestone="66" hash_code="31074955" type="0" content_hash_code="13741232" os_list="linux,windows,chromeos" file_path="remoting/host/security_key/security_key_socket.cc"/> <item id="send_message_express" added_in_milestone="85" hash_code="23527666" type="0" deprecated="2020-09-21" content_hash_code="96850228" file_path=""/> - <item id="service_worker_navigation_preload" added_in_milestone="63" hash_code="129872904" type="0" content_hash_code="79473248" os_list="linux,windows" file_path="content/browser/service_worker/service_worker_fetch_dispatcher.cc"/> - <item id="service_worker_script_load" added_in_milestone="90" hash_code="21498113" type="0" content_hash_code="56275791" os_list="linux,windows" file_path="content/browser/service_worker/service_worker_new_script_fetcher.cc"/> - <item id="service_worker_update_checker" added_in_milestone="71" hash_code="130931413" type="0" content_hash_code="32441998" os_list="linux,windows" file_path="content/browser/service_worker/service_worker_single_script_update_checker.cc"/> - <item id="services_http_server_error_response" added_in_milestone="68" hash_code="59302801" type="0" content_hash_code="127774041" os_list="linux,windows" file_path="services/network/public/cpp/server/http_server.cc"/> - <item id="shared_storage_worklet_module_script_downloader" added_in_milestone="95" hash_code="79084529" type="0" content_hash_code="57126817" os_list="linux,windows" file_path="content/services/shared_storage_worklet/module_script_downloader.cc"/> - <item id="sigined_exchange_cert_fetcher" added_in_milestone="66" hash_code="79442849" type="0" content_hash_code="8138156" os_list="linux,windows" file_path="content/browser/web_package/signed_exchange_cert_fetcher.cc"/> - <item id="sigined_exchange_validity_pinger" added_in_milestone="75" hash_code="57114284" type="0" content_hash_code="119482488" os_list="linux,windows" file_path="content/browser/web_package/signed_exchange_validity_pinger.cc"/> - <item id="signed_in_profile_avatar" added_in_milestone="62" hash_code="108903331" type="0" content_hash_code="72850619" os_list="linux,windows" file_path="chrome/browser/profiles/profile_downloader.cc"/> - <item id="socket_bio_adapter" added_in_milestone="66" hash_code="516551" type="0" content_hash_code="21643352" os_list="linux,windows" file_path="net/socket/socket_bio_adapter.cc"/> - <item id="spdy_push_stream" added_in_milestone="67" hash_code="36915753" type="0" content_hash_code="69224629" os_list="linux,windows" file_path="net/spdy/spdy_session.cc"/> - <item id="spdy_session_control" added_in_milestone="66" hash_code="57143548" type="0" content_hash_code="29815792" os_list="linux,windows" file_path="net/spdy/spdy_session.cc"/> - <item id="speech_recognition_downstream" added_in_milestone="62" hash_code="26096088" type="0" content_hash_code="120733233" os_list="linux,windows" file_path="content/browser/speech/speech_recognition_engine.cc"/> - <item id="speech_recognition_upstream" added_in_milestone="62" hash_code="66846958" type="0" content_hash_code="7706219" os_list="linux,windows" file_path="content/browser/speech/speech_recognition_engine.cc"/> - <item id="spellcheck_hunspell_dictionary" added_in_milestone="62" hash_code="117649486" type="0" content_hash_code="45660952" os_list="linux,windows" file_path="chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc"/> - <item id="spellcheck_lookup" added_in_milestone="62" hash_code="132553989" type="0" content_hash_code="120395045" os_list="linux,windows" file_path="components/spellcheck/browser/spelling_service_client.cc"/> - <item id="ssl_hmac_channel_authenticator" added_in_milestone="66" hash_code="106124561" type="0" content_hash_code="110454877" os_list="linux,windows" file_path="remoting/protocol/ssl_hmac_channel_authenticator.cc"/> - <item id="ssl_name_mismatch_lookup" added_in_milestone="62" hash_code="114468207" type="0" content_hash_code="97619078" os_list="linux,windows" file_path="components/security_interstitials/content/common_name_mismatch_handler.cc"/> - <item id="stream_message_pipe_adapter" added_in_milestone="66" hash_code="71837756" type="0" content_hash_code="66212605" os_list="linux,windows" file_path="remoting/protocol/stream_message_pipe_adapter.cc"/> - <item id="stream_packet_socket" added_in_milestone="84" hash_code="38197513" type="0" content_hash_code="55116994" os_list="linux,windows" file_path="remoting/protocol/stream_packet_socket.cc"/> + <item id="service_worker_navigation_preload" added_in_milestone="63" hash_code="129872904" type="0" content_hash_code="79473248" os_list="linux,windows,chromeos" file_path="content/browser/service_worker/service_worker_fetch_dispatcher.cc"/> + <item id="service_worker_script_load" added_in_milestone="90" hash_code="21498113" type="0" content_hash_code="56275791" os_list="linux,windows,chromeos" file_path="content/browser/service_worker/service_worker_new_script_fetcher.cc"/> + <item id="service_worker_update_checker" added_in_milestone="71" hash_code="130931413" type="0" content_hash_code="32441998" os_list="linux,windows,chromeos" file_path="content/browser/service_worker/service_worker_single_script_update_checker.cc"/> + <item id="services_http_server_error_response" added_in_milestone="68" hash_code="59302801" type="0" content_hash_code="127774041" os_list="linux,windows,chromeos" file_path="services/network/public/cpp/server/http_server.cc"/> + <item id="shared_storage_worklet_module_script_downloader" added_in_milestone="95" hash_code="79084529" type="0" content_hash_code="57126817" os_list="linux,windows,chromeos" file_path="content/services/shared_storage_worklet/module_script_downloader.cc"/> + <item id="sigined_exchange_cert_fetcher" added_in_milestone="66" hash_code="79442849" type="0" content_hash_code="8138156" os_list="linux,windows,chromeos" file_path="content/browser/web_package/signed_exchange_cert_fetcher.cc"/> + <item id="sigined_exchange_validity_pinger" added_in_milestone="75" hash_code="57114284" type="0" content_hash_code="119482488" os_list="linux,windows,chromeos" file_path="content/browser/web_package/signed_exchange_validity_pinger.cc"/> + <item id="signed_in_profile_avatar" added_in_milestone="62" hash_code="108903331" type="0" content_hash_code="72850619" os_list="linux,windows,chromeos" file_path="chrome/browser/profiles/profile_downloader.cc"/> + <item id="socket_bio_adapter" added_in_milestone="66" hash_code="516551" type="0" content_hash_code="21643352" os_list="linux,windows,chromeos" file_path="net/socket/socket_bio_adapter.cc"/> + <item id="spdy_push_stream" added_in_milestone="67" hash_code="36915753" type="0" content_hash_code="69224629" os_list="linux,windows,chromeos" file_path="net/spdy/spdy_session.cc"/> + <item id="spdy_session_control" added_in_milestone="66" hash_code="57143548" type="0" content_hash_code="29815792" os_list="linux,windows,chromeos" file_path="net/spdy/spdy_session.cc"/> + <item id="speech_recognition_downstream" added_in_milestone="62" hash_code="26096088" type="0" content_hash_code="120733233" os_list="linux,windows,chromeos" file_path="content/browser/speech/speech_recognition_engine.cc"/> + <item id="speech_recognition_upstream" added_in_milestone="62" hash_code="66846958" type="0" content_hash_code="7706219" os_list="linux,windows,chromeos" file_path="content/browser/speech/speech_recognition_engine.cc"/> + <item id="spellcheck_hunspell_dictionary" added_in_milestone="62" hash_code="117649486" type="0" content_hash_code="45660952" os_list="linux,windows,chromeos" file_path="chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc"/> + <item id="spellcheck_lookup" added_in_milestone="62" hash_code="132553989" type="0" content_hash_code="120395045" os_list="linux,windows,chromeos" file_path="components/spellcheck/browser/spelling_service_client.cc"/> + <item id="ssl_hmac_channel_authenticator" added_in_milestone="66" hash_code="106124561" type="0" content_hash_code="110454877" os_list="linux,windows,chromeos" file_path="remoting/protocol/ssl_hmac_channel_authenticator.cc"/> + <item id="ssl_name_mismatch_lookup" added_in_milestone="62" hash_code="114468207" type="0" content_hash_code="97619078" os_list="linux,windows,chromeos" file_path="components/security_interstitials/content/common_name_mismatch_handler.cc"/> + <item id="stream_message_pipe_adapter" added_in_milestone="66" hash_code="71837756" type="0" content_hash_code="66212605" os_list="linux,windows,chromeos" file_path="remoting/protocol/stream_message_pipe_adapter.cc"/> + <item id="stream_packet_socket" added_in_milestone="84" hash_code="38197513" type="0" content_hash_code="55116994" os_list="linux,windows,chromeos" file_path="remoting/protocol/stream_packet_socket.cc"/> <item id="suggestions_image_manager" added_in_milestone="62" hash_code="13211343" type="0" deprecated="2018-11-28" content_hash_code="36271280" file_path=""/> <item id="suggestions_service" added_in_milestone="62" hash_code="35370363" type="0" deprecated="2021-07-08" content_hash_code="66296423" file_path=""/> <item id="supervised_user_refresh_token_fetcher" added_in_milestone="62" hash_code="136117054" type="0" deprecated="2018-04-18" content_hash_code="101636136" file_path=""/> @@ -345,47 +345,75 @@ <item id="supervised_users_blacklist" added_in_milestone="62" hash_code="78544924" type="0" deprecated="2019-07-30" content_hash_code="10924669" file_path=""/> <item id="sync_attachment_downloader" added_in_milestone="62" hash_code="26372521" type="0" deprecated="2018-02-08" content_hash_code="70097603" file_path=""/> <item id="sync_attachment_uploader" added_in_milestone="62" hash_code="132657055" type="0" deprecated="2018-02-08" content_hash_code="25152853" file_path=""/> - <item id="sync_file_system" added_in_milestone="62" hash_code="102819690" type="0" content_hash_code="52153962" os_list="linux,windows" file_path="chrome/browser/sync_file_system/drive_backend/sync_engine.cc"/> - <item id="sync_http_bridge" added_in_milestone="62" hash_code="57144960" type="0" content_hash_code="32868346" os_list="linux,windows" file_path="components/sync/engine/net/http_bridge.cc"/> - <item id="sync_stop_reporter" added_in_milestone="62" hash_code="5021348" type="0" content_hash_code="56902850" os_list="linux,windows" file_path="components/sync/driver/sync_stopped_reporter.cc"/> - <item id="task_module_service" added_in_milestone="88" hash_code="50808258" type="0" content_hash_code="12116330" os_list="linux,windows" file_path="chrome/browser/new_tab_page/modules/task_module/task_module_service.cc"/> + <item id="sync_file_system" added_in_milestone="62" hash_code="102819690" type="0" content_hash_code="52153962" os_list="linux,windows,chromeos" file_path="chrome/browser/sync_file_system/drive_backend/sync_engine.cc"/> + <item id="sync_http_bridge" added_in_milestone="62" hash_code="57144960" type="0" content_hash_code="32868346" os_list="linux,windows,chromeos" file_path="components/sync/engine/net/http_bridge.cc"/> + <item id="sync_stop_reporter" added_in_milestone="62" hash_code="5021348" type="0" content_hash_code="56902850" os_list="linux,windows,chromeos" file_path="components/sync/driver/sync_stopped_reporter.cc"/> + <item id="task_module_service" added_in_milestone="88" hash_code="50808258" type="0" content_hash_code="12116330" os_list="linux,windows,chromeos" file_path="chrome/browser/new_tab_page/modules/task_module/task_module_service.cc"/> <item id="test" added_in_milestone="62" hash_code="3556498" type="0" reserved="1" os_list="linux,windows" file_path=""/> <item id="test_partial" added_in_milestone="62" hash_code="22096011" type="0" reserved="1" os_list="linux,windows" file_path=""/> - <item id="tethering_handler_socket" added_in_milestone="65" hash_code="113065062" type="0" content_hash_code="986296" os_list="linux,windows" file_path="content/browser/devtools/protocol/tethering_handler.cc"/> + <item id="tethering_handler_socket" added_in_milestone="65" hash_code="113065062" type="0" content_hash_code="986296" os_list="linux,windows,chromeos" file_path="content/browser/devtools/protocol/tethering_handler.cc"/> <item id="thumbnail_source" added_in_milestone="62" hash_code="135251783" type="0" deprecated="2018-11-27" content_hash_code="31086298" file_path=""/> - <item id="translate_url_fetcher" added_in_milestone="62" hash_code="137116619" type="0" content_hash_code="104217506" os_list="linux,windows" file_path="components/translate/core/browser/translate_url_fetcher.cc"/> - <item id="trusted_vault_request" added_in_milestone="88" hash_code="30516662" type="0" content_hash_code="121167791" os_list="linux,windows" file_path="components/sync/trusted_vault/trusted_vault_request.cc"/> - <item id="ui_devtools_server" added_in_milestone="66" hash_code="4986170" type="0" content_hash_code="62670263" os_list="linux,windows" file_path="components/ui_devtools/devtools_server.cc"/> + <item id="translate_url_fetcher" added_in_milestone="62" hash_code="137116619" type="0" content_hash_code="104217506" os_list="linux,windows,chromeos" file_path="components/translate/core/browser/translate_url_fetcher.cc"/> + <item id="trusted_vault_request" added_in_milestone="88" hash_code="30516662" type="0" content_hash_code="121167791" os_list="linux,windows,chromeos" file_path="components/sync/trusted_vault/trusted_vault_request.cc"/> + <item id="ui_devtools_server" added_in_milestone="66" hash_code="4986170" type="0" content_hash_code="62670263" os_list="linux,windows,chromeos" file_path="components/ui_devtools/devtools_server.cc"/> <item id="undefined" added_in_milestone="62" hash_code="45578882" type="0" reserved="1" os_list="linux,windows" file_path=""/> <item id="unwanted_software_report" added_in_milestone="70" hash_code="43759504" type="0" content_hash_code="59154788" os_list="windows" file_path="chrome/chrome_cleaner/logging/reporter_logging_service.cc"/> - <item id="update_client" added_in_milestone="74" hash_code="54845618" type="0" content_hash_code="86129031" os_list="linux,windows" file_path="components/update_client/net/network_impl.cc"/> + <item id="update_client" added_in_milestone="74" hash_code="54845618" type="0" content_hash_code="86129031" os_list="linux,windows,chromeos" file_path="components/update_client/net/network_impl.cc"/> <item id="url_fetcher_downloader" added_in_milestone="62" hash_code="113231892" type="0" deprecated="2019-02-09" content_hash_code="61085066" file_path=""/> - <item id="url_prevision_fetcher" added_in_milestone="62" hash_code="118389509" type="0" content_hash_code="66145513" os_list="linux,windows" file_path="content/browser/media/url_provision_fetcher.cc"/> - <item id="user_info_fetcher" added_in_milestone="62" hash_code="22265491" type="0" content_hash_code="72016232" os_list="linux,windows" file_path="components/policy/core/common/cloud/user_info_fetcher.cc"/> - <item id="video_tutorial_fetcher" added_in_milestone="87" hash_code="69879956" type="0" content_hash_code="121911479" os_list="linux,windows" file_path="chrome/browser/video_tutorials/internal/tutorial_fetcher.cc"/> - <item id="web_app_origin_association_download" added_in_milestone="90" hash_code="128608592" type="0" content_hash_code="55648317" os_list="linux,windows" file_path="components/webapps/services/web_app_origin_association/web_app_origin_association_fetcher.cc"/> - <item id="web_bundle_loader" added_in_milestone="84" hash_code="114615359" type="0" content_hash_code="57390734" os_list="linux,windows" file_path="content/browser/web_package/web_bundle_utils.cc"/> - <item id="web_history_counter" added_in_milestone="62" hash_code="137457845" type="1" second_id="110307337" content_hash_code="49663381" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/counters/history_counter.cc"/> - <item id="web_history_delete_url" added_in_milestone="74" hash_code="41749213" type="1" second_id="110307337" content_hash_code="25943026" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/history/core/browser/history_service.cc"/> - <item id="web_history_expire" added_in_milestone="62" hash_code="60946824" type="1" second_id="110307337" content_hash_code="92626030" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/history/core/browser/browsing_history_service.cc"/> - <item id="web_history_expire_between_dates" added_in_milestone="62" hash_code="126122632" type="1" second_id="110307337" content_hash_code="34304787" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/history/core/browser/history_service.cc"/> - <item id="web_history_query" added_in_milestone="62" hash_code="17400350" type="1" second_id="110307337" content_hash_code="36075147" os_list="linux,windows" semantics_fields="2,3,4" policy_fields="4" file_path="components/history/core/browser/browsing_history_service.cc"/> - <item id="web_history_service" added_in_milestone="65" hash_code="110307337" type="2" content_hash_code="16140045" os_list="linux,windows" semantics_fields="1,5" policy_fields="-1,3" file_path="components/history/core/browser/web_history_service.cc"/> - <item id="web_push_message" added_in_milestone="77" hash_code="39886742" type="0" content_hash_code="110064650" os_list="linux,windows" file_path="chrome/browser/sharing/web_push/web_push_sender.cc"/> - <item id="webid" added_in_milestone="88" hash_code="113005423" type="0" content_hash_code="121729163" os_list="linux,windows" file_path="content/browser/webid/idp_network_request_manager.cc"/> - <item id="webrtc_event_log_uploader" added_in_milestone="67" hash_code="24186190" type="0" content_hash_code="11005245" os_list="linux,windows" file_path="chrome/browser/media/webrtc/webrtc_event_log_uploader.cc"/> - <item id="webrtc_log_upload" added_in_milestone="62" hash_code="62443804" type="0" content_hash_code="33661169" os_list="linux,windows" file_path="chrome/browser/media/webrtc/webrtc_log_uploader.cc"/> - <item id="webrtc_peer_connection" added_in_milestone="66" hash_code="63497370" type="0" content_hash_code="60553259" os_list="linux,windows" file_path="third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc"/> - <item id="websocket_basic_stream" added_in_milestone="66" hash_code="51586722" type="0" content_hash_code="68121427" os_list="linux,windows" file_path="net/websockets/websocket_basic_stream.cc"/> - <item id="websocket_stream" added_in_milestone="62" hash_code="17188928" type="0" content_hash_code="7250776" os_list="linux,windows" file_path="content/browser/websockets/websocket_connector_impl.cc"/> - <item id="webstore_data_fetcher" added_in_milestone="62" hash_code="26302604" type="0" content_hash_code="24000746" os_list="linux,windows" file_path="chrome/browser/extensions/webstore_data_fetcher.cc"/> - <item id="webstore_install_helper" added_in_milestone="62" hash_code="25921771" type="0" content_hash_code="10206361" os_list="linux,windows" file_path="chrome/browser/extensions/webstore_install_helper.cc"/> - <item id="webstore_installer" added_in_milestone="62" hash_code="18764319" type="0" content_hash_code="70871152" os_list="linux,windows" file_path="chrome/browser/extensions/webstore_installer.cc"/> - <item id="webui_content_scripts_download" added_in_milestone="62" hash_code="100545943" type="0" content_hash_code="119898059" os_list="linux,windows" file_path="extensions/browser/guest_view/web_view/web_ui/web_ui_url_fetcher.cc"/> - <item id="well_known_path_that_should_not_exist" added_in_milestone="86" hash_code="134618785" type="0" content_hash_code="55913167" os_list="linux,windows" file_path="components/password_manager/core/browser/well_known_change_password_state.cc"/> - <item id="whats_new_handler" added_in_milestone="94" hash_code="127739401" type="0" content_hash_code="94869759" os_list="linux,windows" file_path="chrome/browser/ui/webui/whats_new/whats_new_util.cc"/> - <item id="worker_script_load" added_in_milestone="72" hash_code="72087791" type="0" content_hash_code="24889169" os_list="linux,windows" file_path="content/browser/worker_host/worker_script_fetcher.cc"/> + <item id="url_prevision_fetcher" added_in_milestone="62" hash_code="118389509" type="0" content_hash_code="66145513" os_list="linux,windows,chromeos" file_path="content/browser/media/url_provision_fetcher.cc"/> + <item id="user_info_fetcher" added_in_milestone="62" hash_code="22265491" type="0" content_hash_code="72016232" os_list="linux,windows,chromeos" file_path="components/policy/core/common/cloud/user_info_fetcher.cc"/> + <item id="video_tutorial_fetcher" added_in_milestone="87" hash_code="69879956" type="0" content_hash_code="121911479" os_list="linux,windows,chromeos" file_path="chrome/browser/video_tutorials/internal/tutorial_fetcher.cc"/> + <item id="web_app_origin_association_download" added_in_milestone="90" hash_code="128608592" type="0" content_hash_code="55648317" os_list="linux,windows,chromeos" file_path="components/webapps/services/web_app_origin_association/web_app_origin_association_fetcher.cc"/> + <item id="web_bundle_loader" added_in_milestone="84" hash_code="114615359" type="0" content_hash_code="57390734" os_list="linux,windows,chromeos" file_path="content/browser/web_package/web_bundle_utils.cc"/> + <item id="web_history_counter" added_in_milestone="62" hash_code="137457845" type="1" second_id="110307337" content_hash_code="49663381" os_list="linux,windows,chromeos" semantics_fields="2,3,4" policy_fields="4" file_path="components/browsing_data/core/counters/history_counter.cc"/> + <item id="web_history_delete_url" added_in_milestone="74" hash_code="41749213" type="1" second_id="110307337" content_hash_code="25943026" os_list="linux,windows,chromeos" semantics_fields="2,3,4" policy_fields="4" file_path="components/history/core/browser/history_service.cc"/> + <item id="web_history_expire" added_in_milestone="62" hash_code="60946824" type="1" second_id="110307337" content_hash_code="92626030" os_list="linux,windows,chromeos" semantics_fields="2,3,4" policy_fields="4" file_path="components/history/core/browser/browsing_history_service.cc"/> + <item id="web_history_expire_between_dates" added_in_milestone="62" hash_code="126122632" type="1" second_id="110307337" content_hash_code="34304787" os_list="linux,windows,chromeos" semantics_fields="2,3,4" policy_fields="4" file_path="components/history/core/browser/history_service.cc"/> + <item id="web_history_query" added_in_milestone="62" hash_code="17400350" type="1" second_id="110307337" content_hash_code="36075147" os_list="linux,windows,chromeos" semantics_fields="2,3,4" policy_fields="4" file_path="components/history/core/browser/browsing_history_service.cc"/> + <item id="web_history_service" added_in_milestone="65" hash_code="110307337" type="2" content_hash_code="16140045" os_list="linux,windows,chromeos" semantics_fields="1,5" policy_fields="-1,3" file_path="components/history/core/browser/web_history_service.cc"/> + <item id="web_push_message" added_in_milestone="77" hash_code="39886742" type="0" content_hash_code="110064650" os_list="linux,windows,chromeos" file_path="chrome/browser/sharing/web_push/web_push_sender.cc"/> + <item id="webid" added_in_milestone="88" hash_code="113005423" type="0" content_hash_code="121729163" os_list="linux,windows,chromeos" file_path="content/browser/webid/idp_network_request_manager.cc"/> + <item id="webrtc_event_log_uploader" added_in_milestone="67" hash_code="24186190" type="0" content_hash_code="11005245" os_list="linux,windows,chromeos" file_path="chrome/browser/media/webrtc/webrtc_event_log_uploader.cc"/> + <item id="webrtc_log_upload" added_in_milestone="62" hash_code="62443804" type="0" content_hash_code="33661169" os_list="linux,windows,chromeos" file_path="chrome/browser/media/webrtc/webrtc_log_uploader.cc"/> + <item id="webrtc_peer_connection" added_in_milestone="66" hash_code="63497370" type="0" content_hash_code="60553259" os_list="linux,windows,chromeos" file_path="third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc"/> + <item id="websocket_basic_stream" added_in_milestone="66" hash_code="51586722" type="0" content_hash_code="68121427" os_list="linux,windows,chromeos" file_path="net/websockets/websocket_basic_stream.cc"/> + <item id="websocket_stream" added_in_milestone="62" hash_code="17188928" type="0" content_hash_code="7250776" os_list="linux,windows,chromeos" file_path="content/browser/websockets/websocket_connector_impl.cc"/> + <item id="webstore_data_fetcher" added_in_milestone="62" hash_code="26302604" type="0" content_hash_code="24000746" os_list="linux,windows,chromeos" file_path="chrome/browser/extensions/webstore_data_fetcher.cc"/> + <item id="webstore_install_helper" added_in_milestone="62" hash_code="25921771" type="0" content_hash_code="10206361" os_list="linux,windows,chromeos" file_path="chrome/browser/extensions/webstore_install_helper.cc"/> + <item id="webstore_installer" added_in_milestone="62" hash_code="18764319" type="0" content_hash_code="70871152" os_list="linux,windows,chromeos" file_path="chrome/browser/extensions/webstore_installer.cc"/> + <item id="webui_content_scripts_download" added_in_milestone="62" hash_code="100545943" type="0" content_hash_code="119898059" os_list="linux,windows,chromeos" file_path="extensions/browser/guest_view/web_view/web_ui/web_ui_url_fetcher.cc"/> + <item id="well_known_path_that_should_not_exist" added_in_milestone="86" hash_code="134618785" type="0" content_hash_code="55913167" os_list="linux,windows,chromeos" file_path="components/password_manager/core/browser/well_known_change_password_state.cc"/> + <item id="whats_new_handler" added_in_milestone="94" hash_code="127739401" type="0" content_hash_code="94869759" os_list="linux,windows,chromeos" file_path="chrome/browser/ui/webui/whats_new/whats_new_util.cc"/> + <item id="worker_script_load" added_in_milestone="72" hash_code="72087791" type="0" content_hash_code="24889169" os_list="linux,windows,chromeos" file_path="content/browser/worker_host/worker_script_fetcher.cc"/> <item id="xmpp_signal_strategy" added_in_milestone="66" hash_code="88906454" type="0" deprecated="2019-07-16" content_hash_code="88958321" file_path=""/> - <item id="tailored_security_service" added_in_milestone="97" hash_code="126267513" type="0" content_hash_code="35290543" os_list="linux,windows" file_path="components/safe_browsing/core/browser/tailored_security_service/tailored_security_service.cc"/> - <item id="managed_acccount_signin_restrictions_secure_connect" added_in_milestone="97" hash_code="80836426" type="0" content_hash_code="18471055" os_list="linux,windows" file_path="components/policy/core/browser/signin/user_cloud_signin_restriction_policy_fetcher.cc"/> + <item id="tailored_security_service" added_in_milestone="97" hash_code="126267513" type="0" content_hash_code="35290543" os_list="linux,windows,chromeos" file_path="components/safe_browsing/core/browser/tailored_security_service/tailored_security_service.cc"/> + <item id="managed_acccount_signin_restrictions_secure_connect" added_in_milestone="97" hash_code="80836426" type="0" content_hash_code="18471055" os_list="linux,windows,chromeos" file_path="components/policy/core/browser/signin/user_cloud_signin_restriction_policy_fetcher.cc"/> + <item id="ambient_photo_cache" added_in_milestone="98" hash_code="72532255" type="0" content_hash_code="131854878" os_list="chromeos" file_path="ash/ambient/ambient_photo_cache.cc"/> + <item id="ambient_photo_controller" added_in_milestone="98" hash_code="43026447" type="0" content_hash_code="52972426" os_list="chromeos" file_path="ash/ambient/ambient_photo_controller.cc"/> + <item id="image_downloader" added_in_milestone="98" hash_code="23087938" type="0" content_hash_code="95757952" os_list="chromeos" file_path="ash/assistant/assistant_controller_impl.cc"/> + <item id="fast_pair_footprints_request" added_in_milestone="98" hash_code="103224904" type="1" second_id="29188932" content_hash_code="25289735" os_list="chromeos" semantics_fields="1,2,3,4,5" policy_fields="-1,3,5" file_path="ash/quick_pair/repository/fast_pair/footprints_fetcher.cc"/> + <item id="kiosk_app_icon" added_in_milestone="98" hash_code="114234406" type="0" content_hash_code="82849775" os_list="chromeos" file_path="chrome/browser/ash/app_mode/web_app/web_kiosk_app_data.cc"/> + <item id="arc_auth_code_fetcher" added_in_milestone="98" hash_code="58948865" type="0" content_hash_code="91560394" os_list="chromeos" file_path="chrome/browser/ash/arc/auth/arc_background_auth_code_fetcher.cc"/> + <item id="secondary_account_consent_logger" added_in_milestone="98" hash_code="39271880" type="0" content_hash_code="22919066" os_list="chromeos" file_path="chrome/browser/ash/child_accounts/secondary_account_consent_logger.cc"/> + <item id="customization_wallpaper_downloader" added_in_milestone="98" hash_code="96908841" type="0" content_hash_code="65962852" os_list="chromeos" file_path="chrome/browser/ash/customization/customization_wallpaper_downloader.cc"/> + <item id="ime_url_downloader" added_in_milestone="98" hash_code="60291160" type="0" content_hash_code="15806725" os_list="chromeos" file_path="chrome/browser/ash/input_method/ime_service_connector.cc"/> + <item id="chromebook_mail_api" added_in_milestone="98" hash_code="55484398" type="0" content_hash_code="29347698" os_list="chromeos" file_path="chrome/browser/ash/login/marketing_backend_connector.cc"/> + <item id="terms_of_service_fetch" added_in_milestone="98" hash_code="8947273" type="0" content_hash_code="84663928" os_list="chromeos" file_path="chrome/browser/ash/login/screens/terms_of_service_screen.cc"/> + <item id="chrome_plugin_vm_api" added_in_milestone="98" hash_code="28498700" type="0" content_hash_code="68022366" os_list="chromeos" file_path="chrome/browser/ash/plugin_vm/plugin_vm_license_checker.cc"/> + <item id="remote_command_screenshot" added_in_milestone="98" hash_code="59512733" type="0" content_hash_code="128764553" os_list="chromeos" file_path="chrome/browser/ash/policy/remote_commands/screenshot_delegate.cc"/> + <item id="remote_apps_image_downloader" added_in_milestone="98" hash_code="97092439" type="0" content_hash_code="60538097" os_list="chromeos" file_path="chrome/browser/ash/remote_apps/remote_apps_manager.cc"/> + <item id="smb_netbios_name_query" added_in_milestone="98" hash_code="32138459" type="0" content_hash_code="64600736" os_list="chromeos" file_path="chrome/browser/ash/smb_client/discovery/netbios_client.cc"/> + <item id="wallpaper_fetcher" added_in_milestone="98" hash_code="113534723" type="0" content_hash_code="68797141" os_list="chromeos" file_path="chrome/browser/chromeos/extensions/wallpaper_api.cc"/> + <item id="network_traversal_ice_config_fetcher" added_in_milestone="98" hash_code="69712029" type="0" content_hash_code="6682781" os_list="chromeos" file_path="chrome/browser/nearby_sharing/network_traversal_ice_config_fetcher.cc"/> + <item id="tachyon_ice_config_fetcher" added_in_milestone="98" hash_code="6216086" type="0" content_hash_code="32012464" os_list="chromeos" file_path="chrome/browser/nearby_sharing/tachyon_ice_config_fetcher.cc"/> + <item id="supervised_users_denylist" added_in_milestone="98" hash_code="16113717" type="0" content_hash_code="30325503" os_list="chromeos" file_path="chrome/browser/supervised_user/supervised_user_service.cc"/> + <item id="app_suggestion_get_favicon" added_in_milestone="98" hash_code="42628890" type="0" content_hash_code="133998592" os_list="chromeos" file_path="chrome/browser/ui/app_list/search/app_service_app_result.cc"/> + <item id="url_icon_source_fetch" added_in_milestone="98" hash_code="83179212" type="0" content_hash_code="43512587" os_list="chromeos" file_path="chrome/browser/ui/app_list/search/common/url_icon_source.cc"/> + <item id="launcher_item_suggest" added_in_milestone="98" hash_code="102930932" type="0" content_hash_code="77857822" os_list="chromeos" file_path="chrome/browser/ui/app_list/search/files/item_suggest_cache.cc"/> + <item id="cros_launcher_omnibox" added_in_milestone="98" hash_code="20816458" type="0" content_hash_code="79930782" os_list="chromeos" file_path="chrome/browser/ui/app_list/search/omnibox_result.cc"/> + <item id="ambient_client" added_in_milestone="98" hash_code="46775600" type="0" content_hash_code="103645727" os_list="chromeos" file_path="chrome/browser/ui/ash/ambient/ambient_client_impl.cc"/> + <item id="calendar_get_events" added_in_milestone="98" hash_code="86429515" type="0" content_hash_code="17335338" os_list="chromeos" file_path="chrome/browser/ui/ash/calendar/calendar_keyed_service.cc"/> + <item id="side_search_availability_test" added_in_milestone="98" hash_code="27796343" type="0" content_hash_code="71371120" os_list="chromeos" file_path="chrome/browser/ui/side_search/side_search_tab_contents_helper.cc"/> + <item id="edu_account_login_profile_image_fetcher" added_in_milestone="98" hash_code="59209756" type="0" content_hash_code="109654044" os_list="chromeos" file_path="chrome/browser/ui/webui/chromeos/edu_account_login_handler_chromeos.cc"/> + <item id="management_ui_customer_logo" added_in_milestone="98" hash_code="25740183" type="0" content_hash_code="27359832" os_list="chromeos" file_path="chrome/browser/ui/webui/management/management_ui_handler_chromeos.cc"/> </annotations>
diff --git a/tools/traffic_annotation/summary/grouping.xml b/tools/traffic_annotation/summary/grouping.xml index 057e93a8..53c3a4b 100644 --- a/tools/traffic_annotation/summary/grouping.xml +++ b/tools/traffic_annotation/summary/grouping.xml
@@ -30,6 +30,36 @@ </sender> </group> <group name="ChromeOS" hidden="true"> + <sender name="ChromeOS Unsorted"> + <traffic_annotation unique_id="ambient_client"/> + <traffic_annotation unique_id="ambient_photo_cache"/> + <traffic_annotation unique_id="ambient_photo_controller"/> + <traffic_annotation unique_id="app_suggestion_get_favicon"/> + <traffic_annotation unique_id="arc_auth_code_fetcher"/> + <traffic_annotation unique_id="calendar_get_events"/> + <traffic_annotation unique_id="chrome_plugin_vm_api"/> + <traffic_annotation unique_id="chromebook_mail_api"/> + <traffic_annotation unique_id="cros_launcher_omnibox"/> + <traffic_annotation unique_id="customization_wallpaper_downloader"/> + <traffic_annotation unique_id="edu_account_login_profile_image_fetcher"/> + <traffic_annotation unique_id="fast_pair_footprints_request"/> + <traffic_annotation unique_id="ime_url_downloader"/> + <traffic_annotation unique_id="image_downloader"/> + <traffic_annotation unique_id="kiosk_app_icon"/> + <traffic_annotation unique_id="launcher_item_suggest"/> + <traffic_annotation unique_id="management_ui_customer_logo"/> + <traffic_annotation unique_id="network_traversal_ice_config_fetcher"/> + <traffic_annotation unique_id="remote_apps_image_downloader"/> + <traffic_annotation unique_id="remote_command_screenshot"/> + <traffic_annotation unique_id="secondary_account_consent_logger"/> + <traffic_annotation unique_id="side_search_availability_test"/> + <traffic_annotation unique_id="smb_netbios_name_query"/> + <traffic_annotation unique_id="supervised_users_denylist"/> + <traffic_annotation unique_id="tachyon_ice_config_fetcher"/> + <traffic_annotation unique_id="terms_of_service_fetch"/> + <traffic_annotation unique_id="url_icon_source_fetch"/> + <traffic_annotation unique_id="wallpaper_fetcher"/> + </sender> <!-- ChromeOS-specific features --> <sender name="ChromeOS Recovery"> <traffic_annotation unique_id="cros_recovery_image_download"/>
diff --git a/ui/android/java/res/values-night/colors.xml b/ui/android/java/res/values-night/colors.xml index e7bbdb4..4df8d0a9 100644 --- a/ui/android/java/res/values-night/colors.xml +++ b/ui/android/java/res/values-night/colors.xml
@@ -91,7 +91,7 @@ <color name="default_green">@color/default_green_light</color> <color name="filled_button_bg_color">@color/filled_button_bg_color_light</color> <color name="filled_button_bg_color_disabled">@color/filled_button_bg_color_disabled_light</color> - <color name="divider_line_bg_color">@color/divider_line_bg_color_light</color> + <color name="divider_line_bg_color_baseline">@color/divider_line_bg_color_light</color> <color name="omnibox_bg_color">@color/omnibox_bg_color_dark</color> <color name="image_loading_color">@color/image_loading_color_light</color> <color name="promo_illustration_bg_color">@color/promo_illustration_bg_color_dark</color>
diff --git a/ui/android/java/res/values/attrs.xml b/ui/android/java/res/values/attrs.xml index f1aea5f..b836614f 100644 --- a/ui/android/java/res/values/attrs.xml +++ b/ui/android/java/res/values/attrs.xml
@@ -36,7 +36,6 @@ <!-- Semantic names that will support dynamic colors but not yet. --> <attr name="default_bg_color" format="color"/> - <attr name="divider_line_bg_color" format="color"/> <!-- Splintered semantic names that support dynamic colors. --> <attr name="default_bg_color_dynamic" format="color"/>
diff --git a/ui/android/java/res/values/semantic_colors_adaptive.xml b/ui/android/java/res/values/semantic_colors_adaptive.xml index 21ed779..51415299 100644 --- a/ui/android/java/res/values/semantic_colors_adaptive.xml +++ b/ui/android/java/res/values/semantic_colors_adaptive.xml
@@ -123,8 +123,8 @@ <color name="default_green" tools:ignore="UnusedResources">@color/default_green_dark</color> <color name="filled_button_bg_color">@color/filled_button_bg_color_dark</color> <color name="filled_button_bg_color_disabled">@color/filled_button_bg_color_disabled_dark</color> - <color name="divider_line_bg_color" tools:ignore="UnusedResources">@color/divider_line_bg_color_dark</color> - <color name="drag_handlebar_color">@color/divider_line_bg_color</color> + <color name="divider_line_bg_color_baseline" tools:ignore="UnusedResources">@color/divider_line_bg_color_dark</color> + <color name="drag_handlebar_color">@color/divider_line_bg_color_baseline</color> <color name="omnibox_bg_color" tools:ignore="UnusedResources">@color/omnibox_bg_color_light</color> <color name="image_loading_color" tools:ignore="UnusedResources">@color/image_loading_color_dark</color> <color name="promo_illustration_bg_color" tools:ignore="UnusedResources">@color/promo_illustration_bg_color_light</color>
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager.css b/ui/file_manager/file_manager/foreground/css/file_manager.css index fe22bca..cbca9dbb 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -1663,7 +1663,7 @@ } body.files-ng grid .grid-title { - color: var(--google-grey-700); + color: var(--cros-text-color-secondary); font-family: 'Roboto Medium'; padding-inline-start: 16px; padding-top: 20px; @@ -1720,28 +1720,16 @@ /* Styles specific for the grid view. */ -.thumbnail-grid .thumbnail-item { - background-color: rgb(245, 245, 245); - height: 180px; - margin-inline-start: 4px; - margin-top: 4px; - overflow: hidden; - position: relative; - vertical-align: top; /* Prevent vertical spacing for wrapped inline box. */ - width: 180px; -} - body.files-ng .thumbnail-grid .thumbnail-item { background-color: inherit; border-radius: 4px; height: 160px; margin-inline-start: 16px; margin-top: 16px; -} - -.thumbnail-grid .thumbnail-item.directory { - box-shadow: 0 1px rgba(0, 0, 0, 15%); - height: 40px; + overflow: hidden; + position: relative; + vertical-align: top; /* Prevent vertical spacing for wrapped inline box. */ + width: 180px; } body.files-ng .thumbnail-item.directory { @@ -1750,11 +1738,11 @@ } body.files-ng #list-container .thumbnail-grid li { - border: 1px solid rgba(0, 0, 0, 14%); + border: 1px solid var(--cros-separator-color); } body.files-ng grid .thumbnail-bottom .detail-icon { - color: var(--google-grey-700); + color: var(--cros-icon-color-secondary); height: 40px; padding-inline-end: 6px; padding-inline-start: 6px; @@ -1771,50 +1759,6 @@ width: 100%; } -.thumbnail-grid .thumbnail-item[selected], -.thumbnail-grid .thumbnail-item.accepts { - background-color: rgb(221, 242, 253); -} - -.thumbnail-grid .thumbnail-item[selected] .shield { - background-color: rgba(51, 103, 214, 50%); - -} - -.thumbnail-grid .thumbnail-item[lead]:not([selected]) .shield { - background-color: rgba(51, 103, 214, 20%); -} - -.thumbnail-grid .checkmark { - background-position: center; - background-repeat: no-repeat; - height: 36px; - margin-inline-start: 2px; - opacity: 0; - position: absolute; - top: 2px; - transition: opacity 220ms ease; - width: 36px; -} - -body.selecting .thumbnail-grid .checkmark.inactive, -.thumbnail-grid .thumbnail-item:hover .checkmark.inactive { - opacity: 0.6; -} - -body.check-select .thumbnail-grid .thumbnail-item .checkmark.inactive { - opacity: 1; -} - -body.check-select .thumbnail-grid .thumbnail-item[selected] - .checkmark.inactive { - opacity: 0; -} - -body.check-select .thumbnail-grid .thumbnail-item[selected] .checkmark.active { - opacity: 1; -} - .thumbnail-grid .img-container { background-color: rgb(230, 230, 230); height: 100%; @@ -1822,7 +1766,7 @@ } body.files-ng .thumbnail-grid .img-container { - color: var(--google-grey-700); + color: var(--cros-text-color-secondary); height: 120px; } @@ -1837,48 +1781,9 @@ width: 100%; } -.thumbnail-grid .shield { - background-color: rgba(160, 160, 160, 50%); - bottom: 0; - display: none; - left: 0; - position: absolute; - right: 0; - top: 0; -} - -.thumbnail-grid:focus .shield { - background-color: rgba(51, 103, 214, 50%); -} - -.thumbnail-grid .thumbnail-item[selected] .shield, -.thumbnail-grid .thumbnail-item[lead] .shield { - display: block; -} - -.thumbnail-grid .thumbnail-bottom { - background-color: rgba(255, 255, 255, 85%); - color: rgb(51, 51, 51); - height: 40px; -} - body.files-ng .thumbnail-grid .thumbnail-bottom { - background-color: white; - color: var(--google-grey-900); -} - -.thumbnail-grid .thumbnail-item.directory .thumbnail-bottom { - background-color: rgb(255, 255, 255); -} - -.thumbnail-grid .thumbnail-item[selected].directory .thumbnail-bottom, -.thumbnail-grid .thumbnail-item[lead].directory .thumbnail-bottom { - background-color: rgb(232, 232, 232); -} - -.thumbnail-grid:focus .thumbnail-item[selected].directory .thumbnail-bottom, -.thumbnail-grid:focus .thumbnail-item[lead].directory .thumbnail-bottom { - background-color: rgb(232, 246, 253); + color: var(--cros-text-color-primary); + height: 40px; } body.files-ng .thumbnail-grid .thumbnail-item[selected] .thumbnail-bottom, @@ -1887,7 +1792,7 @@ .thumbnail-bottom, body.files-ng .thumbnail-grid .thumbnail-item[lead].directory .thumbnail-bottom { - background-color: var(--google-grey-100); + background-color: var(--cros-highlight-color-hover); } body.files-ng .thumbnail-grid:focus .thumbnail-item[selected] .thumbnail-bottom, @@ -1896,7 +1801,7 @@ .thumbnail-bottom, body.files-ng .thumbnail-grid:focus .thumbnail-item[lead].directory .thumbnail-bottom { - background-color: var(--google-blue-50); + background-color: var(--cros-highlight-color); } body.check-select.files-ng .thumbnail-grid:focus .thumbnail-item[selected] @@ -1907,7 +1812,7 @@ .thumbnail-item[selected].directory .thumbnail-bottom, body.check-select.files-ng .thumbnail-grid:focus .thumbnail-item[lead].directory .thumbnail-bottom { - color: var(--google-blue-600); + color: var(--cros-text-color-selection); } body.check-select.files-ng #list-container .thumbnail-grid:focus @@ -1916,8 +1821,8 @@ .thumbnail-item[lead]:not([selected]) { /* 2px border: 1px via box-shadow + 1px via border, to accommodate the difference between regular border 1px and selected border 2px.*/ - border-color: var(--google-blue-600); - box-shadow: 0 0 0 1px var(--google-blue-600); + border-color: var(--cros-focus-ring-color); + box-shadow: 0 0 0 1px var(--cros-focus-ring-color); } body.check-select.files-ng #list-container .thumbnail-grid @@ -1926,13 +1831,8 @@ .thumbnail-item[lead]:not([selected]) { /* 2px border: 1px via box-shadow + 1px via border, to accommodate the difference between regular border 1px and selected border 2px.*/ - border-color: var(--google-grey-700); - box-shadow: 0 0 0 1px var(--google-grey-700); -} - -body.files-ng #list-container .thumbnail-grid .thumbnail-item[lead].directory - .shield { - height: 36px; + border-color: var(--cros-icon-color-secondary); + box-shadow: 0 0 0 1px var(--cros-icon-color-secondary); } .thumbnail-grid > .spacer.folder-spacer {
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index b1961a12..7f0c5a5 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -773,6 +773,7 @@ "geometry/insets_unittest.cc", "geometry/matrix3_unittest.cc", "geometry/point3_unittest.cc", + "geometry/point_f_unittest.cc", "geometry/point_unittest.cc", "geometry/quad_unittest.cc", "geometry/quaternion_unittest.cc", @@ -781,6 +782,7 @@ "geometry/rect_unittest.cc", "geometry/resize_utils_unittest.cc", "geometry/rounded_corners_f_unittest.cc", + "geometry/size_f_unittest.cc", "geometry/size_unittest.cc", "geometry/skia_conversions_unittest.cc", "geometry/transform_util_unittest.cc",
diff --git a/ui/gfx/geometry/point_f.cc b/ui/gfx/geometry/point_f.cc index 70003d0..139de31 100644 --- a/ui/gfx/geometry/point_f.cc +++ b/ui/gfx/geometry/point_f.cc
@@ -31,7 +31,7 @@ } std::string PointF::ToString() const { - return base::StringPrintf("%f,%f", x(), y()); + return base::StringPrintf("%g,%g", x(), y()); } PointF ScalePoint(const PointF& p, float x_scale, float y_scale) {
diff --git a/ui/gfx/geometry/point_f_unittest.cc b/ui/gfx/geometry/point_f_unittest.cc new file mode 100644 index 0000000..4b9f038 --- /dev/null +++ b/ui/gfx/geometry/point_f_unittest.cc
@@ -0,0 +1,117 @@ +// 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 "ui/gfx/geometry/point_f.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/point_conversions.h" + +namespace gfx { + +TEST(PointFTest, PointToPointF) { + // Check that explicit conversion from integer to float compiles. + Point a(10, 20); + PointF b = PointF(a); + + EXPECT_EQ(static_cast<float>(a.x()), b.x()); + EXPECT_EQ(static_cast<float>(a.y()), b.y()); +} + +TEST(PointFTest, IsOrigin) { + EXPECT_FALSE(PointF(0.1f, 0).IsOrigin()); + EXPECT_FALSE(PointF(0, 0.1f).IsOrigin()); + EXPECT_FALSE(PointF(0.1f, 2).IsOrigin()); + EXPECT_FALSE(PointF(-0.1f, 0).IsOrigin()); + EXPECT_FALSE(PointF(0, -0.1f).IsOrigin()); + EXPECT_FALSE(PointF(-0.1f, -2).IsOrigin()); + EXPECT_TRUE(PointF(0, 0).IsOrigin()); +} + +TEST(PointFTest, ToRoundedPoint) { + EXPECT_EQ(Point(0, 0), ToRoundedPoint(PointF(0, 0))); + EXPECT_EQ(Point(0, 0), ToRoundedPoint(PointF(0.0001f, 0.0001f))); + EXPECT_EQ(Point(0, 0), ToRoundedPoint(PointF(0.4999f, 0.4999f))); + EXPECT_EQ(Point(1, 1), ToRoundedPoint(PointF(0.5f, 0.5f))); + EXPECT_EQ(Point(1, 1), ToRoundedPoint(PointF(0.9999f, 0.9999f))); + + EXPECT_EQ(Point(10, 10), ToRoundedPoint(PointF(10, 10))); + EXPECT_EQ(Point(10, 10), ToRoundedPoint(PointF(10.0001f, 10.0001f))); + EXPECT_EQ(Point(10, 10), ToRoundedPoint(PointF(10.4999f, 10.4999f))); + EXPECT_EQ(Point(11, 11), ToRoundedPoint(PointF(10.5f, 10.5f))); + EXPECT_EQ(Point(11, 11), ToRoundedPoint(PointF(10.9999f, 10.9999f))); + + EXPECT_EQ(Point(-10, -10), ToRoundedPoint(PointF(-10, -10))); + EXPECT_EQ(Point(-10, -10), ToRoundedPoint(PointF(-10.0001f, -10.0001f))); + EXPECT_EQ(Point(-10, -10), ToRoundedPoint(PointF(-10.4999f, -10.4999f))); + EXPECT_EQ(Point(-11, -11), ToRoundedPoint(PointF(-10.5f, -10.5f))); + EXPECT_EQ(Point(-11, -11), ToRoundedPoint(PointF(-10.9999f, -10.9999f))); +} + +TEST(PointFTest, Scale) { + EXPECT_EQ(PointF(2, -2), ScalePoint(PointF(1, -1), 2)); + EXPECT_EQ(PointF(2, -2), ScalePoint(PointF(1, -1), 2, 2)); + + PointF zero; + PointF one(1, -1); + + zero.Scale(2); + zero.Scale(3, 1.5); + + one.Scale(2); + one.Scale(3, 1.5); + + EXPECT_EQ(PointF(), zero); + EXPECT_EQ(PointF(6, -3), one); +} + +TEST(PointFTest, SetToMinMax) { + PointF a; + + a = PointF(3.5f, 5.5f); + EXPECT_EQ(PointF(3.5f, 5.5f), a); + a.SetToMax(PointF(2.5f, 4.5f)); + EXPECT_EQ(PointF(3.5f, 5.5f), a); + a.SetToMax(PointF(3.5f, 5.5f)); + EXPECT_EQ(PointF(3.5f, 5.5f), a); + a.SetToMax(PointF(4.5f, 2.5f)); + EXPECT_EQ(PointF(4.5f, 5.5f), a); + a.SetToMax(PointF(8.5f, 10.5f)); + EXPECT_EQ(PointF(8.5f, 10.5f), a); + + a.SetToMin(PointF(9.5f, 11.5f)); + EXPECT_EQ(PointF(8.5f, 10.5f), a); + a.SetToMin(PointF(8.5f, 10.5f)); + EXPECT_EQ(PointF(8.5f, 10.5f), a); + a.SetToMin(PointF(11.5f, 9.5f)); + EXPECT_EQ(PointF(8.5f, 9.5f), a); + a.SetToMin(PointF(7.5f, 11.5f)); + EXPECT_EQ(PointF(7.5f, 9.5f), a); + a.SetToMin(PointF(3.5f, 5.5f)); + EXPECT_EQ(PointF(3.5f, 5.5f), a); +} + +TEST(PointFTest, IsWithinDistance) { + PointF pt(10.f, 10.f); + EXPECT_TRUE(pt.IsWithinDistance(PointF(10.f, 10.f), 0.0000000000001f)); + EXPECT_FALSE(pt.IsWithinDistance(PointF(8.f, 8.f), 1.f)); + + pt = PointF(-10.f, -10.f); + EXPECT_FALSE( + pt.IsWithinDistance(PointF(10.f, 10.f), /*allowed_distance=*/10.f)); + EXPECT_TRUE(pt.IsWithinDistance(PointF(-9.9988f, -10.0013f), 0.0017689f)); + + pt = PointF(std::numeric_limits<float>::max(), + std::numeric_limits<float>::max()); + EXPECT_FALSE(pt.IsWithinDistance(PointF(std::numeric_limits<float>::min(), + std::numeric_limits<float>::min()), + 100.f)); +} + +TEST(PointFTest, ToString) { + EXPECT_EQ("1,2", PointF(1, 2).ToString()); + EXPECT_EQ("1.03125,2.5", PointF(1.03125, 2.5).ToString()); +} + +} // namespace gfx
diff --git a/ui/gfx/geometry/point_unittest.cc b/ui/gfx/geometry/point_unittest.cc index 90f61aef9..a04d4ffe 100644 --- a/ui/gfx/geometry/point_unittest.cc +++ b/ui/gfx/geometry/point_unittest.cc
@@ -2,25 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <stddef.h> - -#include "base/cxx17_backports.h" -#include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/point.h" -#include "ui/gfx/geometry/point_conversions.h" -#include "ui/gfx/geometry/point_f.h" + +#include <stddef.h> +#include "testing/gtest/include/gtest/gtest.h" namespace gfx { -TEST(PointTest, ToPointF) { - // Check that explicit conversion from integer to float compiles. - Point a(10, 20); - PointF b = PointF(a); - - EXPECT_EQ(static_cast<float>(a.x()), b.x()); - EXPECT_EQ(static_cast<float>(a.y()), b.y()); -} - TEST(PointTest, IsOrigin) { EXPECT_FALSE(Point(1, 0).IsOrigin()); EXPECT_FALSE(Point(0, 1).IsOrigin()); @@ -29,14 +17,6 @@ EXPECT_FALSE(Point(0, -1).IsOrigin()); EXPECT_FALSE(Point(-1, -2).IsOrigin()); EXPECT_TRUE(Point(0, 0).IsOrigin()); - - EXPECT_FALSE(PointF(0.1f, 0).IsOrigin()); - EXPECT_FALSE(PointF(0, 0.1f).IsOrigin()); - EXPECT_FALSE(PointF(0.1f, 2).IsOrigin()); - EXPECT_FALSE(PointF(-0.1f, 0).IsOrigin()); - EXPECT_FALSE(PointF(0, -0.1f).IsOrigin()); - EXPECT_FALSE(PointF(-0.1f, -2).IsOrigin()); - EXPECT_TRUE(PointF(0, 0).IsOrigin()); } TEST(PointTest, VectorArithmetic) { @@ -57,107 +37,40 @@ { Point(-10, 9), a - v1 + v2 } }; - for (size_t i = 0; i < base::size(tests); ++i) - EXPECT_EQ(tests[i].expected.ToString(), tests[i].actual.ToString()); + for (auto& test : tests) + EXPECT_EQ(test.expected, test.actual); } TEST(PointTest, OffsetFromPoint) { Point a(1, 5); Point b(-20, 8); - EXPECT_EQ(Vector2d(-20 - 1, 8 - 5).ToString(), (b - a).ToString()); + EXPECT_EQ(Vector2d(-20 - 1, 8 - 5), (b - a)); } -TEST(PointTest, ToRoundedPoint) { - EXPECT_EQ(Point(0, 0), ToRoundedPoint(PointF(0, 0))); - EXPECT_EQ(Point(0, 0), ToRoundedPoint(PointF(0.0001f, 0.0001f))); - EXPECT_EQ(Point(0, 0), ToRoundedPoint(PointF(0.4999f, 0.4999f))); - EXPECT_EQ(Point(1, 1), ToRoundedPoint(PointF(0.5f, 0.5f))); - EXPECT_EQ(Point(1, 1), ToRoundedPoint(PointF(0.9999f, 0.9999f))); - - EXPECT_EQ(Point(10, 10), ToRoundedPoint(PointF(10, 10))); - EXPECT_EQ(Point(10, 10), ToRoundedPoint(PointF(10.0001f, 10.0001f))); - EXPECT_EQ(Point(10, 10), ToRoundedPoint(PointF(10.4999f, 10.4999f))); - EXPECT_EQ(Point(11, 11), ToRoundedPoint(PointF(10.5f, 10.5f))); - EXPECT_EQ(Point(11, 11), ToRoundedPoint(PointF(10.9999f, 10.9999f))); - - EXPECT_EQ(Point(-10, -10), ToRoundedPoint(PointF(-10, -10))); - EXPECT_EQ(Point(-10, -10), ToRoundedPoint(PointF(-10.0001f, -10.0001f))); - EXPECT_EQ(Point(-10, -10), ToRoundedPoint(PointF(-10.4999f, -10.4999f))); - EXPECT_EQ(Point(-11, -11), ToRoundedPoint(PointF(-10.5f, -10.5f))); - EXPECT_EQ(Point(-11, -11), ToRoundedPoint(PointF(-10.9999f, -10.9999f))); -} - -TEST(PointTest, Scale) { - EXPECT_EQ(PointF().ToString(), ScalePoint(PointF(), 2).ToString()); - EXPECT_EQ(PointF().ToString(), ScalePoint(PointF(), 2, 2).ToString()); - - EXPECT_EQ(PointF(2, -2).ToString(), ScalePoint(PointF(1, -1), 2).ToString()); - EXPECT_EQ(PointF(2, -2).ToString(), - ScalePoint(PointF(1, -1), 2, 2).ToString()); - - PointF zero; - PointF one(1, -1); - - zero.Scale(2); - zero.Scale(3, 1.5); - - one.Scale(2); - one.Scale(3, 1.5); - - EXPECT_EQ(PointF().ToString(), zero.ToString()); - EXPECT_EQ(PointF(6, -3).ToString(), one.ToString()); -} - -TEST(PointTest, ClampPoint) { +TEST(PointTest, SetToMinMax) { Point a; a = Point(3, 5); - EXPECT_EQ(Point(3, 5).ToString(), a.ToString()); + EXPECT_EQ(Point(3, 5), a); a.SetToMax(Point(2, 4)); - EXPECT_EQ(Point(3, 5).ToString(), a.ToString()); + EXPECT_EQ(Point(3, 5), a); a.SetToMax(Point(3, 5)); - EXPECT_EQ(Point(3, 5).ToString(), a.ToString()); + EXPECT_EQ(Point(3, 5), a); a.SetToMax(Point(4, 2)); - EXPECT_EQ(Point(4, 5).ToString(), a.ToString()); + EXPECT_EQ(Point(4, 5), a); a.SetToMax(Point(8, 10)); - EXPECT_EQ(Point(8, 10).ToString(), a.ToString()); + EXPECT_EQ(Point(8, 10), a); a.SetToMin(Point(9, 11)); - EXPECT_EQ(Point(8, 10).ToString(), a.ToString()); + EXPECT_EQ(Point(8, 10), a); a.SetToMin(Point(8, 10)); - EXPECT_EQ(Point(8, 10).ToString(), a.ToString()); + EXPECT_EQ(Point(8, 10), a); a.SetToMin(Point(11, 9)); - EXPECT_EQ(Point(8, 9).ToString(), a.ToString()); + EXPECT_EQ(Point(8, 9), a); a.SetToMin(Point(7, 11)); - EXPECT_EQ(Point(7, 9).ToString(), a.ToString()); + EXPECT_EQ(Point(7, 9), a); a.SetToMin(Point(3, 5)); - EXPECT_EQ(Point(3, 5).ToString(), a.ToString()); -} - -TEST(PointTest, ClampPointF) { - PointF a; - - a = PointF(3.5f, 5.5f); - EXPECT_EQ(PointF(3.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(PointF(2.5f, 4.5f)); - EXPECT_EQ(PointF(3.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(PointF(3.5f, 5.5f)); - EXPECT_EQ(PointF(3.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(PointF(4.5f, 2.5f)); - EXPECT_EQ(PointF(4.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(PointF(8.5f, 10.5f)); - EXPECT_EQ(PointF(8.5f, 10.5f).ToString(), a.ToString()); - - a.SetToMin(PointF(9.5f, 11.5f)); - EXPECT_EQ(PointF(8.5f, 10.5f).ToString(), a.ToString()); - a.SetToMin(PointF(8.5f, 10.5f)); - EXPECT_EQ(PointF(8.5f, 10.5f).ToString(), a.ToString()); - a.SetToMin(PointF(11.5f, 9.5f)); - EXPECT_EQ(PointF(8.5f, 9.5f).ToString(), a.ToString()); - a.SetToMin(PointF(7.5f, 11.5f)); - EXPECT_EQ(PointF(7.5f, 9.5f).ToString(), a.ToString()); - a.SetToMin(PointF(3.5f, 5.5f)); - EXPECT_EQ(PointF(3.5f, 5.5f).ToString(), a.ToString()); + EXPECT_EQ(Point(3, 5), a); } TEST(PointTest, Offset) { @@ -233,23 +146,4 @@ EXPECT_EQ(test, min_point); } -TEST(PointTest, IsWithinDistance) { - PointF pt(10.f, 10.f); - EXPECT_TRUE(pt.IsWithinDistance(PointF(10.f, 10.f), - /*allowed_distance=*/0.0000000000001f)); - EXPECT_FALSE(pt.IsWithinDistance(PointF(8.f, 8.f), /*allowed_distance=*/1.f)); - - pt = PointF(-10.f, -10.f); - EXPECT_FALSE( - pt.IsWithinDistance(PointF(10.f, 10.f), /*allowed_distance=*/10.f)); - EXPECT_TRUE(pt.IsWithinDistance(PointF(-9.9988f, -10.0013f), - /*epsallowed_distanceilon=*/0.0017689f)); - - pt = PointF(std::numeric_limits<float>::max(), - std::numeric_limits<float>::max()); - EXPECT_FALSE(pt.IsWithinDistance(PointF(std::numeric_limits<float>::min(), - std::numeric_limits<float>::min()), - /*allowed_distance=*/100.f)); -} - } // namespace gfx
diff --git a/ui/gfx/geometry/size_f.cc b/ui/gfx/geometry/size_f.cc index c9991383..a3743a5 100644 --- a/ui/gfx/geometry/size_f.cc +++ b/ui/gfx/geometry/size_f.cc
@@ -27,7 +27,7 @@ } std::string SizeF::ToString() const { - return base::StringPrintf("%fx%f", width(), height()); + return base::StringPrintf("%gx%g", width(), height()); } SizeF ScaleSize(const SizeF& s, float x_scale, float y_scale) {
diff --git a/ui/gfx/geometry/size_f.h b/ui/gfx/geometry/size_f.h index 007e6cc..3e73381 100644 --- a/ui/gfx/geometry/size_f.h +++ b/ui/gfx/geometry/size_f.h
@@ -66,9 +66,9 @@ std::string ToString() const; private: - FRIEND_TEST_ALL_PREFIXES(SizeTest, TrivialDimensionTests); - FRIEND_TEST_ALL_PREFIXES(SizeTest, ClampsToZero); - FRIEND_TEST_ALL_PREFIXES(SizeTest, ConsistentClamping); + FRIEND_TEST_ALL_PREFIXES(SizeFTest, IsEmpty); + FRIEND_TEST_ALL_PREFIXES(SizeFTest, ClampsToZero); + FRIEND_TEST_ALL_PREFIXES(SizeFTest, ConsistentClamping); static constexpr float kTrivial = 8.f * std::numeric_limits<float>::epsilon();
diff --git a/ui/gfx/geometry/size_f_unittest.cc b/ui/gfx/geometry/size_f_unittest.cc new file mode 100644 index 0000000..49170b7 --- /dev/null +++ b/ui/gfx/geometry/size_f_unittest.cc
@@ -0,0 +1,185 @@ +// 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 "ui/gfx/geometry/size_f.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/geometry/size_conversions.h" +#include "ui/gfx/geometry/test/geometry_util.h" + +namespace gfx { + +TEST(SizeFTest, SizeToSizeF) { + // Check that explicit conversion from integer to float compiles. + Size a(10, 20); + EXPECT_EQ(10, SizeF(a).width()); + EXPECT_EQ(20, SizeF(a).height()); + + SizeF b(10, 20); + EXPECT_EQ(b, gfx::SizeF(a)); +} + +TEST(SizeFTest, ToFlooredSize) { + EXPECT_EQ(Size(0, 0), ToFlooredSize(SizeF(0, 0))); + EXPECT_EQ(Size(0, 0), ToFlooredSize(SizeF(0.0001f, 0.0001f))); + EXPECT_EQ(Size(0, 0), ToFlooredSize(SizeF(0.4999f, 0.4999f))); + EXPECT_EQ(Size(0, 0), ToFlooredSize(SizeF(0.5f, 0.5f))); + EXPECT_EQ(Size(0, 0), ToFlooredSize(SizeF(0.9999f, 0.9999f))); + + EXPECT_EQ(Size(10, 10), ToFlooredSize(SizeF(10, 10))); + EXPECT_EQ(Size(10, 10), ToFlooredSize(SizeF(10.0001f, 10.0001f))); + EXPECT_EQ(Size(10, 10), ToFlooredSize(SizeF(10.4999f, 10.4999f))); + EXPECT_EQ(Size(10, 10), ToFlooredSize(SizeF(10.5f, 10.5f))); + EXPECT_EQ(Size(10, 10), ToFlooredSize(SizeF(10.9999f, 10.9999f))); +} + +TEST(SizeFTest, ToCeiledSize) { + EXPECT_EQ(Size(0, 0), ToCeiledSize(SizeF(0, 0))); + EXPECT_EQ(Size(1, 1), ToCeiledSize(SizeF(0.0001f, 0.0001f))); + EXPECT_EQ(Size(1, 1), ToCeiledSize(SizeF(0.4999f, 0.4999f))); + EXPECT_EQ(Size(1, 1), ToCeiledSize(SizeF(0.5f, 0.5f))); + EXPECT_EQ(Size(1, 1), ToCeiledSize(SizeF(0.9999f, 0.9999f))); + + EXPECT_EQ(Size(10, 10), ToCeiledSize(SizeF(10, 10))); + EXPECT_EQ(Size(11, 11), ToCeiledSize(SizeF(10.0001f, 10.0001f))); + EXPECT_EQ(Size(11, 11), ToCeiledSize(SizeF(10.4999f, 10.4999f))); + EXPECT_EQ(Size(11, 11), ToCeiledSize(SizeF(10.5f, 10.5f))); + EXPECT_EQ(Size(11, 11), ToCeiledSize(SizeF(10.9999f, 10.9999f))); +} + +TEST(SizeFTest, ToRoundedSize) { + EXPECT_EQ(Size(0, 0), ToRoundedSize(SizeF(0, 0))); + EXPECT_EQ(Size(0, 0), ToRoundedSize(SizeF(0.0001f, 0.0001f))); + EXPECT_EQ(Size(0, 0), ToRoundedSize(SizeF(0.4999f, 0.4999f))); + EXPECT_EQ(Size(1, 1), ToRoundedSize(SizeF(0.5f, 0.5f))); + EXPECT_EQ(Size(1, 1), ToRoundedSize(SizeF(0.9999f, 0.9999f))); + + EXPECT_EQ(Size(10, 10), ToRoundedSize(SizeF(10, 10))); + EXPECT_EQ(Size(10, 10), ToRoundedSize(SizeF(10.0001f, 10.0001f))); + EXPECT_EQ(Size(10, 10), ToRoundedSize(SizeF(10.4999f, 10.4999f))); + EXPECT_EQ(Size(11, 11), ToRoundedSize(SizeF(10.5f, 10.5f))); + EXPECT_EQ(Size(11, 11), ToRoundedSize(SizeF(10.9999f, 10.9999f))); +} + +TEST(SizeFTest, SetToMinMax) { + SizeF a; + + a = SizeF(3.5f, 5.5f); + EXPECT_EQ(SizeF(3.5f, 5.5f).ToString(), a.ToString()); + a.SetToMax(SizeF(2.5f, 4.5f)); + EXPECT_EQ(SizeF(3.5f, 5.5f).ToString(), a.ToString()); + a.SetToMax(SizeF(3.5f, 5.5f)); + EXPECT_EQ(SizeF(3.5f, 5.5f).ToString(), a.ToString()); + a.SetToMax(SizeF(4.5f, 2.5f)); + EXPECT_EQ(SizeF(4.5f, 5.5f).ToString(), a.ToString()); + a.SetToMax(SizeF(8.5f, 10.5f)); + EXPECT_EQ(SizeF(8.5f, 10.5f).ToString(), a.ToString()); + + a.SetToMin(SizeF(9.5f, 11.5f)); + EXPECT_EQ(SizeF(8.5f, 10.5f).ToString(), a.ToString()); + a.SetToMin(SizeF(8.5f, 10.5f)); + EXPECT_EQ(SizeF(8.5f, 10.5f).ToString(), a.ToString()); + a.SetToMin(SizeF(11.5f, 9.5f)); + EXPECT_EQ(SizeF(8.5f, 9.5f).ToString(), a.ToString()); + a.SetToMin(SizeF(7.5f, 11.5f)); + EXPECT_EQ(SizeF(7.5f, 9.5f).ToString(), a.ToString()); + a.SetToMin(SizeF(3.5f, 5.5f)); + EXPECT_EQ(SizeF(3.5f, 5.5f).ToString(), a.ToString()); +} + +TEST(SizeFTest, IsEmpty) { + const float clearly_trivial = SizeF::kTrivial / 2.f; + const float massize_dimension = 4e13f; + + // First, using the constructor. + EXPECT_TRUE(SizeF(clearly_trivial, 1.f).IsEmpty()); + EXPECT_TRUE(SizeF(.01f, clearly_trivial).IsEmpty()); + EXPECT_TRUE(SizeF(0.f, 0.f).IsEmpty()); + EXPECT_FALSE(SizeF(.01f, .01f).IsEmpty()); + + // Then use the setter. + SizeF test(2.f, 1.f); + EXPECT_FALSE(test.IsEmpty()); + + test.SetSize(clearly_trivial, 1.f); + EXPECT_TRUE(test.IsEmpty()); + + test.SetSize(.01f, clearly_trivial); + EXPECT_TRUE(test.IsEmpty()); + + test.SetSize(0.f, 0.f); + EXPECT_TRUE(test.IsEmpty()); + + test.SetSize(.01f, .01f); + EXPECT_FALSE(test.IsEmpty()); + + // Now just one dimension at a time. + test.set_width(clearly_trivial); + EXPECT_TRUE(test.IsEmpty()); + + test.set_width(massize_dimension); + test.set_height(clearly_trivial); + EXPECT_TRUE(test.IsEmpty()); + + test.set_width(clearly_trivial); + test.set_height(massize_dimension); + EXPECT_TRUE(test.IsEmpty()); + + test.set_width(2.f); + EXPECT_FALSE(test.IsEmpty()); +} + +// These are the ramifications of the decision to keep the recorded size +// at zero for trivial sizes. +TEST(SizeFTest, ClampsToZero) { + const float clearly_trivial = SizeF::kTrivial / 2.f; + const float nearly_trivial = SizeF::kTrivial * 1.5f; + + SizeF test(clearly_trivial, 1.f); + + EXPECT_FLOAT_EQ(0.f, test.width()); + EXPECT_FLOAT_EQ(1.f, test.height()); + + test.SetSize(.01f, clearly_trivial); + + EXPECT_FLOAT_EQ(.01f, test.width()); + EXPECT_FLOAT_EQ(0.f, test.height()); + + test.SetSize(nearly_trivial, nearly_trivial); + + EXPECT_FLOAT_EQ(nearly_trivial, test.width()); + EXPECT_FLOAT_EQ(nearly_trivial, test.height()); + + test.Scale(0.5f); + + EXPECT_FLOAT_EQ(0.f, test.width()); + EXPECT_FLOAT_EQ(0.f, test.height()); + + test.SetSize(0.f, 0.f); + test.Enlarge(clearly_trivial, clearly_trivial); + test.Enlarge(clearly_trivial, clearly_trivial); + test.Enlarge(clearly_trivial, clearly_trivial); + + EXPECT_EQ(SizeF(0.f, 0.f), test); +} + +// These make sure the constructor and setter have the same effect on the +// boundary case. This claims to know the boundary, but not which way it goes. +TEST(SizeFTest, ConsistentClamping) { + SizeF resized; + + resized.SetSize(SizeF::kTrivial, 0.f); + EXPECT_EQ(SizeF(SizeF::kTrivial, 0.f), resized); + + resized.SetSize(0.f, SizeF::kTrivial); + EXPECT_EQ(SizeF(0.f, SizeF::kTrivial), resized); +} + +TEST(SizeFTest, ToString) { + EXPECT_EQ("1x2", SizeF(1, 2).ToString()); + EXPECT_EQ("1.03125x2.5", SizeF(1.03125, 2.5).ToString()); +} + +} // namespace gfx
diff --git a/ui/gfx/geometry/size_unittest.cc b/ui/gfx/geometry/size_unittest.cc index b3ec2ec0..9a842dc 100644 --- a/ui/gfx/geometry/size_unittest.cc +++ b/ui/gfx/geometry/size_unittest.cc
@@ -2,75 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/size.h" -#include "ui/gfx/geometry/size_conversions.h" -#include "ui/gfx/geometry/size_f.h" + +#include "testing/gtest/include/gtest/gtest.h" namespace gfx { -namespace { - -int TestSizeF(const SizeF& s) { - return s.width(); -} - -} // namespace - -TEST(SizeTest, ToSizeF) { - // Check that explicit conversion from integer to float compiles. - Size a(10, 20); - float width = TestSizeF(gfx::SizeF(a)); - EXPECT_EQ(width, a.width()); - - SizeF b(10, 20); - - EXPECT_EQ(b, gfx::SizeF(a)); -} - -TEST(SizeTest, ToFlooredSize) { - EXPECT_EQ(Size(0, 0), ToFlooredSize(SizeF(0, 0))); - EXPECT_EQ(Size(0, 0), ToFlooredSize(SizeF(0.0001f, 0.0001f))); - EXPECT_EQ(Size(0, 0), ToFlooredSize(SizeF(0.4999f, 0.4999f))); - EXPECT_EQ(Size(0, 0), ToFlooredSize(SizeF(0.5f, 0.5f))); - EXPECT_EQ(Size(0, 0), ToFlooredSize(SizeF(0.9999f, 0.9999f))); - - EXPECT_EQ(Size(10, 10), ToFlooredSize(SizeF(10, 10))); - EXPECT_EQ(Size(10, 10), ToFlooredSize(SizeF(10.0001f, 10.0001f))); - EXPECT_EQ(Size(10, 10), ToFlooredSize(SizeF(10.4999f, 10.4999f))); - EXPECT_EQ(Size(10, 10), ToFlooredSize(SizeF(10.5f, 10.5f))); - EXPECT_EQ(Size(10, 10), ToFlooredSize(SizeF(10.9999f, 10.9999f))); -} - -TEST(SizeTest, ToCeiledSize) { - EXPECT_EQ(Size(0, 0), ToCeiledSize(SizeF(0, 0))); - EXPECT_EQ(Size(1, 1), ToCeiledSize(SizeF(0.0001f, 0.0001f))); - EXPECT_EQ(Size(1, 1), ToCeiledSize(SizeF(0.4999f, 0.4999f))); - EXPECT_EQ(Size(1, 1), ToCeiledSize(SizeF(0.5f, 0.5f))); - EXPECT_EQ(Size(1, 1), ToCeiledSize(SizeF(0.9999f, 0.9999f))); - - EXPECT_EQ(Size(10, 10), ToCeiledSize(SizeF(10, 10))); - EXPECT_EQ(Size(11, 11), ToCeiledSize(SizeF(10.0001f, 10.0001f))); - EXPECT_EQ(Size(11, 11), ToCeiledSize(SizeF(10.4999f, 10.4999f))); - EXPECT_EQ(Size(11, 11), ToCeiledSize(SizeF(10.5f, 10.5f))); - EXPECT_EQ(Size(11, 11), ToCeiledSize(SizeF(10.9999f, 10.9999f))); -} - -TEST(SizeTest, ToRoundedSize) { - EXPECT_EQ(Size(0, 0), ToRoundedSize(SizeF(0, 0))); - EXPECT_EQ(Size(0, 0), ToRoundedSize(SizeF(0.0001f, 0.0001f))); - EXPECT_EQ(Size(0, 0), ToRoundedSize(SizeF(0.4999f, 0.4999f))); - EXPECT_EQ(Size(1, 1), ToRoundedSize(SizeF(0.5f, 0.5f))); - EXPECT_EQ(Size(1, 1), ToRoundedSize(SizeF(0.9999f, 0.9999f))); - - EXPECT_EQ(Size(10, 10), ToRoundedSize(SizeF(10, 10))); - EXPECT_EQ(Size(10, 10), ToRoundedSize(SizeF(10.0001f, 10.0001f))); - EXPECT_EQ(Size(10, 10), ToRoundedSize(SizeF(10.4999f, 10.4999f))); - EXPECT_EQ(Size(11, 11), ToRoundedSize(SizeF(10.5f, 10.5f))); - EXPECT_EQ(Size(11, 11), ToRoundedSize(SizeF(10.9999f, 10.9999f))); -} - -TEST(SizeTest, ClampSize) { +TEST(SizeTest, SetToMinMax) { Size a; a = Size(3, 5); @@ -96,32 +34,6 @@ EXPECT_EQ(Size(3, 5).ToString(), a.ToString()); } -TEST(SizeTest, ClampSizeF) { - SizeF a; - - a = SizeF(3.5f, 5.5f); - EXPECT_EQ(SizeF(3.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(SizeF(2.5f, 4.5f)); - EXPECT_EQ(SizeF(3.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(SizeF(3.5f, 5.5f)); - EXPECT_EQ(SizeF(3.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(SizeF(4.5f, 2.5f)); - EXPECT_EQ(SizeF(4.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(SizeF(8.5f, 10.5f)); - EXPECT_EQ(SizeF(8.5f, 10.5f).ToString(), a.ToString()); - - a.SetToMin(SizeF(9.5f, 11.5f)); - EXPECT_EQ(SizeF(8.5f, 10.5f).ToString(), a.ToString()); - a.SetToMin(SizeF(8.5f, 10.5f)); - EXPECT_EQ(SizeF(8.5f, 10.5f).ToString(), a.ToString()); - a.SetToMin(SizeF(11.5f, 9.5f)); - EXPECT_EQ(SizeF(8.5f, 9.5f).ToString(), a.ToString()); - a.SetToMin(SizeF(7.5f, 11.5f)); - EXPECT_EQ(SizeF(7.5f, 9.5f).ToString(), a.ToString()); - a.SetToMin(SizeF(3.5f, 5.5f)); - EXPECT_EQ(SizeF(3.5f, 5.5f).ToString(), a.ToString()); -} - TEST(SizeTest, Enlarge) { Size test(3, 4); test.Enlarge(5, -8); @@ -153,101 +65,6 @@ EXPECT_EQ(test, min_size); } -// This checks that we set IsEmpty appropriately. -TEST(SizeTest, TrivialDimensionTests) { - const float clearly_trivial = SizeF::kTrivial / 2.f; - const float massize_dimension = 4e13f; - - // First, using the constructor. - EXPECT_TRUE(SizeF(clearly_trivial, 1.f).IsEmpty()); - EXPECT_TRUE(SizeF(.01f, clearly_trivial).IsEmpty()); - EXPECT_TRUE(SizeF(0.f, 0.f).IsEmpty()); - EXPECT_FALSE(SizeF(.01f, .01f).IsEmpty()); - - // Then use the setter. - SizeF test(2.f, 1.f); - EXPECT_FALSE(test.IsEmpty()); - - test.SetSize(clearly_trivial, 1.f); - EXPECT_TRUE(test.IsEmpty()); - - test.SetSize(.01f, clearly_trivial); - EXPECT_TRUE(test.IsEmpty()); - - test.SetSize(0.f, 0.f); - EXPECT_TRUE(test.IsEmpty()); - - test.SetSize(.01f, .01f); - EXPECT_FALSE(test.IsEmpty()); - - // Now just one dimension at a time. - test.set_width(clearly_trivial); - EXPECT_TRUE(test.IsEmpty()); - - test.set_width(massize_dimension); - test.set_height(clearly_trivial); - EXPECT_TRUE(test.IsEmpty()); - - test.set_width(clearly_trivial); - test.set_height(massize_dimension); - EXPECT_TRUE(test.IsEmpty()); - - test.set_width(2.f); - EXPECT_FALSE(test.IsEmpty()); -} - -// These are the ramifications of the decision to keep the recorded size -// at zero for trivial sizes. -TEST(SizeTest, ClampsToZero) { - const float clearly_trivial = SizeF::kTrivial / 2.f; - const float nearly_trivial = SizeF::kTrivial * 1.5f; - - SizeF test(clearly_trivial, 1.f); - - EXPECT_FLOAT_EQ(0.f, test.width()); - EXPECT_FLOAT_EQ(1.f, test.height()); - - test.SetSize(.01f, clearly_trivial); - - EXPECT_FLOAT_EQ(.01f, test.width()); - EXPECT_FLOAT_EQ(0.f, test.height()); - - test.SetSize(nearly_trivial, nearly_trivial); - - EXPECT_FLOAT_EQ(nearly_trivial, test.width()); - EXPECT_FLOAT_EQ(nearly_trivial, test.height()); - - test.Scale(0.5f); - - EXPECT_FLOAT_EQ(0.f, test.width()); - EXPECT_FLOAT_EQ(0.f, test.height()); - - test.SetSize(0.f, 0.f); - test.Enlarge(clearly_trivial, clearly_trivial); - test.Enlarge(clearly_trivial, clearly_trivial); - test.Enlarge(clearly_trivial, clearly_trivial); - - EXPECT_EQ(SizeF(0.f, 0.f), test); -} - -// These make sure the constructor and setter have the same effect on the -// boundary case. This claims to know the boundary, but not which way it goes. -TEST(SizeTest, ConsistentClamping) { - SizeF resized; - - resized.SetSize(SizeF::kTrivial, 0.f); - EXPECT_EQ(SizeF(SizeF::kTrivial, 0.f), resized); - - resized.SetSize(0.f, SizeF::kTrivial); - EXPECT_EQ(SizeF(0.f, SizeF::kTrivial), resized); -} - -// Let's make sure we don't unexpectedly grow the struct by adding constants. -// Also, if some platform packs floats inefficiently, it would be worth noting. -TEST(SizeTest, StaysSmall) { - EXPECT_EQ(2 * sizeof(float), sizeof(SizeF)); -} - TEST(SizeTest, OperatorAddSub) { Size lhs(100, 20); Size rhs(50, 10);
diff --git a/ui/gfx/geometry/vector2d_f.cc b/ui/gfx/geometry/vector2d_f.cc index c7e5ca9..ee70e17 100644 --- a/ui/gfx/geometry/vector2d_f.cc +++ b/ui/gfx/geometry/vector2d_f.cc
@@ -12,7 +12,7 @@ namespace gfx { std::string Vector2dF::ToString() const { - return base::StringPrintf("[%f %f]", x_, y_); + return base::StringPrintf("[%g %g]", x_, y_); } bool Vector2dF::IsZero() const {
diff --git a/ui/gfx/geometry/vector2d_f_unittest.cc b/ui/gfx/geometry/vector2d_f_unittest.cc index 2ce287c..0572f285 100644 --- a/ui/gfx/geometry/vector2d_f_unittest.cc +++ b/ui/gfx/geometry/vector2d_f_unittest.cc
@@ -5,11 +5,104 @@ #include "ui/gfx/geometry/vector2d_f.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/test/geometry_util.h" +#include "ui/gfx/geometry/vector2d.h" namespace gfx { -// Some Vector2dF unittests are in vector2d_unittest.cc sharing the same tests -// with Vector2d. +TEST(Vector2dTest, Vector2dToVector2dF) { + Vector2d i(3, 4); + Vector2dF f = i; + EXPECT_EQ(i, f); +} + +TEST(Vector2dFTest, IsZero) { + EXPECT_TRUE(Vector2dF().IsZero()); + EXPECT_TRUE(Vector2dF(0, 0).IsZero()); + EXPECT_FALSE(Vector2dF(0.1f, 0).IsZero()); + EXPECT_FALSE(Vector2dF(0, -0.1f).IsZero()); + EXPECT_FALSE(Vector2dF(0.1f, -0.1f).IsZero()); +} + +TEST(Vector2dFTest, Add) { + Vector2dF f1(3.1f, 5.1f); + Vector2dF f2(4.3f, -1.3f); + EXPECT_VECTOR2DF_EQ(Vector2dF(3.1f, 5.1f), f1 + Vector2dF()); + EXPECT_VECTOR2DF_EQ(Vector2dF(3.1f + 4.3f, 5.1f - 1.3f), f1 + f2); + EXPECT_VECTOR2DF_EQ(Vector2dF(3.1f - 4.3f, 5.1f + 1.3f), f1 - f2); +} + +TEST(Vector2dFTest, Negative) { + EXPECT_VECTOR2DF_EQ(Vector2dF(), -Vector2dF()); + EXPECT_VECTOR2DF_EQ(Vector2dF(-0.3f, -0.3f), -Vector2dF(0.3f, 0.3f)); + EXPECT_VECTOR2DF_EQ(Vector2dF(0.3f, 0.3f), -Vector2dF(-0.3f, -0.3f)); + EXPECT_VECTOR2DF_EQ(Vector2dF(-0.3f, 0.3f), -Vector2dF(0.3f, -0.3f)); + EXPECT_VECTOR2DF_EQ(Vector2dF(0.3f, -0.3f), -Vector2dF(-0.3f, 0.3f)); +} + +TEST(Vector2dFTest, Scale) { + float double_values[][4] = { + {4.5f, 1.2f, 3.3f, 5.6f}, {4.5f, -1.2f, 3.3f, 5.6f}, + {4.5f, 1.2f, 3.3f, -5.6f}, {4.5f, 1.2f, -3.3f, -5.6f}, + {-4.5f, 1.2f, 3.3f, 5.6f}, {-4.5f, 1.2f, 0, 5.6f}, + {-4.5f, 1.2f, 3.3f, 0}, {4.5f, 0, 3.3f, 5.6f}, + {0, 1.2f, 3.3f, 5.6f}}; + + for (auto& values : double_values) { + Vector2dF v(values[0], values[1]); + v.Scale(values[2], values[3]); + EXPECT_EQ(v.x(), values[0] * values[2]); + EXPECT_EQ(v.y(), values[1] * values[3]); + + Vector2dF v2 = ScaleVector2d(gfx::Vector2dF(values[0], values[1]), + values[2], values[3]); + EXPECT_EQ(values[0] * values[2], v2.x()); + EXPECT_EQ(values[1] * values[3], v2.y()); + } + + float single_values[][3] = { + {4.5f, 1.2f, 3.3f}, {4.5f, -1.2f, 3.3f}, {4.5f, 1.2f, 3.3f}, + {4.5f, 1.2f, -3.3f}, {-4.5f, 1.2f, 3.3f}, {-4.5f, 1.2f, 0}, + {-4.5f, 1.2f, 3.3f}, {4.5f, 0, 3.3f}, {0, 1.2f, 3.3f}}; + + for (auto& values : single_values) { + Vector2dF v(values[0], values[1]); + v.Scale(values[2]); + EXPECT_EQ(v.x(), values[0] * values[2]); + EXPECT_EQ(v.y(), values[1] * values[2]); + + Vector2dF v2 = + ScaleVector2d(gfx::Vector2dF(values[0], values[1]), values[2]); + EXPECT_EQ(values[0] * values[2], v2.x()); + EXPECT_EQ(values[1] * values[2], v2.y()); + } +} + +TEST(Vector2dFTest, SetToMinMax) { + Vector2dF a; + + a = Vector2dF(3.5f, 5.5f); + EXPECT_EQ(Vector2dF(3.5f, 5.5f), a); + a.SetToMax(Vector2dF(2.5f, 4.5f)); + EXPECT_EQ(Vector2dF(3.5f, 5.5f), a); + a.SetToMax(Vector2dF(3.5f, 5.5f)); + EXPECT_EQ(Vector2dF(3.5f, 5.5f), a); + a.SetToMax(Vector2dF(4.5f, 2.5f)); + EXPECT_EQ(Vector2dF(4.5f, 5.5f), a); + a.SetToMax(Vector2dF(8.5f, 10.5f)); + EXPECT_EQ(Vector2dF(8.5f, 10.5f), a); + + a.SetToMin(Vector2dF(9.5f, 11.5f)); + EXPECT_EQ(Vector2dF(8.5f, 10.5f), a); + a.SetToMin(Vector2dF(8.5f, 10.5f)); + EXPECT_EQ(Vector2dF(8.5f, 10.5f), a); + a.SetToMin(Vector2dF(11.5f, 9.5f)); + EXPECT_EQ(Vector2dF(8.5f, 9.5f), a); + a.SetToMin(Vector2dF(7.5f, 11.5f)); + EXPECT_EQ(Vector2dF(7.5f, 9.5f), a); + a.SetToMin(Vector2dF(3.5f, 5.5f)); + EXPECT_EQ(Vector2dF(3.5f, 5.5f), a); +} TEST(Vector2dFTest, Length) { constexpr float kFloatMax = std::numeric_limits<float>::max(); @@ -17,6 +110,16 @@ EXPECT_FLOAT_EQ(1.f, Vector2dF(1, 0).Length()); EXPECT_FLOAT_EQ(1.414214f, Vector2dF(1, 1).Length()); EXPECT_FLOAT_EQ(2.236068f, Vector2dF(-1, -2).Length()); + + // The Pythagorean triples 3-4-5 and 5-12-13. + EXPECT_FLOAT_EQ(5.f, Vector2dF(3.f, 4.f).Length()); + EXPECT_FLOAT_EQ(13.f, Vector2dF(5.f, 12.f).Length()); + + // Very small numbers. + EXPECT_FLOAT_EQ(.7071068e-20f, Vector2dF(.5e-20f, .5e-20f).Length()); + + // Very large numbers. + EXPECT_FLOAT_EQ(.7071068e20f, Vector2dF(.5e20f, .5e20f).Length()); EXPECT_FLOAT_EQ(kFloatMax, Vector2dF(kFloatMax, 0).Length()); EXPECT_FLOAT_EQ(kFloatMax, Vector2dF(kFloatMax, kFloatMax).Length()); } @@ -36,4 +139,9 @@ EXPECT_NEAR(-kPi / 4, Vector2dF(1, -1).SlopeAngleRadians(), kTolerance); } +TEST(Vector2dFTest, ToString) { + EXPECT_EQ("[1 2]", Vector2dF(1, 2).ToString()); + EXPECT_EQ("[1.03125 2.5]", Vector2dF(1.03125, 2.5).ToString()); +} + } // namespace gfx
diff --git a/ui/gfx/geometry/vector2d_unittest.cc b/ui/gfx/geometry/vector2d_unittest.cc index 7a3cb7f..7e8cd27e 100644 --- a/ui/gfx/geometry/vector2d_unittest.cc +++ b/ui/gfx/geometry/vector2d_unittest.cc
@@ -2,168 +2,48 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <stddef.h> +#include "ui/gfx/geometry/vector2d.h" +#include <stddef.h> #include <cmath> #include <limits> -#include "base/cxx17_backports.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/geometry/vector2d.h" -#include "ui/gfx/geometry/vector2d_f.h" namespace gfx { -TEST(Vector2dTest, ConversionToFloat) { - Vector2d i(3, 4); - Vector2dF f = i; - EXPECT_EQ(i, f); -} - TEST(Vector2dTest, IsZero) { - Vector2d int_zero(0, 0); - Vector2d int_nonzero(2, -2); - Vector2dF float_zero(0, 0); - Vector2dF float_nonzero(0.1f, -0.1f); - - EXPECT_TRUE(int_zero.IsZero()); - EXPECT_FALSE(int_nonzero.IsZero()); - EXPECT_TRUE(float_zero.IsZero()); - EXPECT_FALSE(float_nonzero.IsZero()); + EXPECT_TRUE(Vector2d().IsZero()); + EXPECT_TRUE(Vector2d(0, 0).IsZero()); + EXPECT_FALSE(Vector2d(1, 0).IsZero()); + EXPECT_FALSE(Vector2d(0, -2).IsZero()); + EXPECT_FALSE(Vector2d(1, -2).IsZero()); } TEST(Vector2dTest, Add) { Vector2d i1(3, 5); Vector2d i2(4, -1); - - const struct { - Vector2d expected; - Vector2d actual; - } int_tests[] = { - { Vector2d(3, 5), i1 + Vector2d() }, - { Vector2d(3 + 4, 5 - 1), i1 + i2 }, - { Vector2d(3 - 4, 5 + 1), i1 - i2 } - }; - - for (size_t i = 0; i < base::size(int_tests); ++i) - EXPECT_EQ(int_tests[i].expected.ToString(), - int_tests[i].actual.ToString()); - - Vector2dF f1(3.1f, 5.1f); - Vector2dF f2(4.3f, -1.3f); - - const struct { - Vector2dF expected; - Vector2dF actual; - } float_tests[] = { - { Vector2dF(3.1F, 5.1F), f1 + Vector2d() }, - { Vector2dF(3.1F, 5.1F), f1 + Vector2dF() }, - { Vector2dF(3.1f + 4.3f, 5.1f - 1.3f), f1 + f2 }, - { Vector2dF(3.1f - 4.3f, 5.1f + 1.3f), f1 - f2 } - }; - - for (size_t i = 0; i < base::size(float_tests); ++i) - EXPECT_EQ(float_tests[i].expected.ToString(), - float_tests[i].actual.ToString()); + EXPECT_EQ(Vector2d(3, 5), i1 + Vector2d()); + EXPECT_EQ(Vector2d(3 + 4, 5 - 1), i1 + i2); + EXPECT_EQ(Vector2d(3 - 4, 5 + 1), i1 - i2); } TEST(Vector2dTest, Negative) { - const struct { - Vector2d expected; - Vector2d actual; - } int_tests[] = { - { Vector2d(0, 0), -Vector2d(0, 0) }, - { Vector2d(-3, -3), -Vector2d(3, 3) }, - { Vector2d(3, 3), -Vector2d(-3, -3) }, - { Vector2d(-3, 3), -Vector2d(3, -3) }, - { Vector2d(3, -3), -Vector2d(-3, 3) } - }; - - for (size_t i = 0; i < base::size(int_tests); ++i) - EXPECT_EQ(int_tests[i].expected.ToString(), - int_tests[i].actual.ToString()); - - const struct { - Vector2dF expected; - Vector2dF actual; - } float_tests[] = { - { Vector2dF(0, 0), -Vector2d(0, 0) }, - { Vector2dF(-0.3f, -0.3f), -Vector2dF(0.3f, 0.3f) }, - { Vector2dF(0.3f, 0.3f), -Vector2dF(-0.3f, -0.3f) }, - { Vector2dF(-0.3f, 0.3f), -Vector2dF(0.3f, -0.3f) }, - { Vector2dF(0.3f, -0.3f), -Vector2dF(-0.3f, 0.3f) } - }; - - for (size_t i = 0; i < base::size(float_tests); ++i) - EXPECT_EQ(float_tests[i].expected.ToString(), - float_tests[i].actual.ToString()); -} - -TEST(Vector2dTest, Scale) { - float double_values[][4] = { - { 4.5f, 1.2f, 3.3f, 5.6f }, - { 4.5f, -1.2f, 3.3f, 5.6f }, - { 4.5f, 1.2f, 3.3f, -5.6f }, - { 4.5f, 1.2f, -3.3f, -5.6f }, - { -4.5f, 1.2f, 3.3f, 5.6f }, - { -4.5f, 1.2f, 0, 5.6f }, - { -4.5f, 1.2f, 3.3f, 0 }, - { 4.5f, 0, 3.3f, 5.6f }, - { 0, 1.2f, 3.3f, 5.6f } - }; - - for (size_t i = 0; i < base::size(double_values); ++i) { - Vector2dF v(double_values[i][0], double_values[i][1]); - v.Scale(double_values[i][2], double_values[i][3]); - EXPECT_EQ(v.x(), double_values[i][0] * double_values[i][2]); - EXPECT_EQ(v.y(), double_values[i][1] * double_values[i][3]); - - Vector2dF v2 = ScaleVector2d( - gfx::Vector2dF(double_values[i][0], double_values[i][1]), - double_values[i][2], double_values[i][3]); - EXPECT_EQ(double_values[i][0] * double_values[i][2], v2.x()); - EXPECT_EQ(double_values[i][1] * double_values[i][3], v2.y()); - } - - float single_values[][3] = { - { 4.5f, 1.2f, 3.3f }, - { 4.5f, -1.2f, 3.3f }, - { 4.5f, 1.2f, 3.3f }, - { 4.5f, 1.2f, -3.3f }, - { -4.5f, 1.2f, 3.3f }, - { -4.5f, 1.2f, 0 }, - { -4.5f, 1.2f, 3.3f }, - { 4.5f, 0, 3.3f }, - { 0, 1.2f, 3.3f } - }; - - for (size_t i = 0; i < base::size(single_values); ++i) { - Vector2dF v(single_values[i][0], single_values[i][1]); - v.Scale(single_values[i][2]); - EXPECT_EQ(v.x(), single_values[i][0] * single_values[i][2]); - EXPECT_EQ(v.y(), single_values[i][1] * single_values[i][2]); - - Vector2dF v2 = ScaleVector2d( - gfx::Vector2dF(double_values[i][0], double_values[i][1]), - double_values[i][2]); - EXPECT_EQ(single_values[i][0] * single_values[i][2], v2.x()); - EXPECT_EQ(single_values[i][1] * single_values[i][2], v2.y()); - } + EXPECT_EQ(Vector2d(0, 0), -Vector2d(0, 0)); + EXPECT_EQ(Vector2d(-3, -3), -Vector2d(3, 3)); + EXPECT_EQ(Vector2d(3, 3), -Vector2d(-3, -3)); + EXPECT_EQ(Vector2d(-3, 3), -Vector2d(3, -3)); + EXPECT_EQ(Vector2d(3, -3), -Vector2d(-3, 3)); } TEST(Vector2dTest, Length) { - int int_values[][2] = { - { 0, 0 }, - { 10, 20 }, - { 20, 10 }, - { -10, -20 }, - { -20, 10 }, - { 10, -20 }, + int values[][2] = { + {0, 0}, {10, 20}, {20, 10}, {-10, -20}, {-20, 10}, {10, -20}, }; - for (size_t i = 0; i < base::size(int_values); ++i) { - int v0 = int_values[i][0]; - int v1 = int_values[i][1]; + for (auto& value : values) { + int v0 = value[0]; + int v1 = value[1]; double length_squared = static_cast<double>(v0) * v0 + static_cast<double>(v1) * v1; double length = std::sqrt(length_squared); @@ -171,82 +51,32 @@ EXPECT_EQ(static_cast<float>(length_squared), vector.LengthSquared()); EXPECT_EQ(static_cast<float>(length), vector.Length()); } - - float float_values[][2] = { - { 0, 0 }, - { 10.5f, 20.5f }, - { 20.5f, 10.5f }, - { -10.5f, -20.5f }, - { -20.5f, 10.5f }, - { 10.5f, -20.5f }, - // A large vector that fails if the Length function doesn't use - // double precision internally. - { 1236278317862780234892374893213178027.12122348904204230f, - 335890352589839028212313231225425134332.38123f }, - }; - - for (size_t i = 0; i < base::size(float_values); ++i) { - double v0 = float_values[i][0]; - double v1 = float_values[i][1]; - double length_squared = - static_cast<double>(v0) * v0 + static_cast<double>(v1) * v1; - double length = std::sqrt(length_squared); - Vector2dF vector(v0, v1); - EXPECT_DOUBLE_EQ(length_squared, vector.LengthSquared()); - EXPECT_FLOAT_EQ(static_cast<float>(length), vector.Length()); - } } -TEST(Vector2dTest, ClampVector2d) { +TEST(Vector2dTest, SetToMinMax) { Vector2d a; a = Vector2d(3, 5); - EXPECT_EQ(Vector2d(3, 5).ToString(), a.ToString()); + EXPECT_EQ(Vector2d(3, 5), a); a.SetToMax(Vector2d(2, 4)); - EXPECT_EQ(Vector2d(3, 5).ToString(), a.ToString()); + EXPECT_EQ(Vector2d(3, 5), a); a.SetToMax(Vector2d(3, 5)); - EXPECT_EQ(Vector2d(3, 5).ToString(), a.ToString()); + EXPECT_EQ(Vector2d(3, 5), a); a.SetToMax(Vector2d(4, 2)); - EXPECT_EQ(Vector2d(4, 5).ToString(), a.ToString()); + EXPECT_EQ(Vector2d(4, 5), a); a.SetToMax(Vector2d(8, 10)); - EXPECT_EQ(Vector2d(8, 10).ToString(), a.ToString()); + EXPECT_EQ(Vector2d(8, 10), a); a.SetToMin(Vector2d(9, 11)); - EXPECT_EQ(Vector2d(8, 10).ToString(), a.ToString()); + EXPECT_EQ(Vector2d(8, 10), a); a.SetToMin(Vector2d(8, 10)); - EXPECT_EQ(Vector2d(8, 10).ToString(), a.ToString()); + EXPECT_EQ(Vector2d(8, 10), a); a.SetToMin(Vector2d(11, 9)); - EXPECT_EQ(Vector2d(8, 9).ToString(), a.ToString()); + EXPECT_EQ(Vector2d(8, 9), a); a.SetToMin(Vector2d(7, 11)); - EXPECT_EQ(Vector2d(7, 9).ToString(), a.ToString()); + EXPECT_EQ(Vector2d(7, 9), a); a.SetToMin(Vector2d(3, 5)); - EXPECT_EQ(Vector2d(3, 5).ToString(), a.ToString()); -} - -TEST(Vector2dTest, ClampVector2dF) { - Vector2dF a; - - a = Vector2dF(3.5f, 5.5f); - EXPECT_EQ(Vector2dF(3.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(Vector2dF(2.5f, 4.5f)); - EXPECT_EQ(Vector2dF(3.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(Vector2dF(3.5f, 5.5f)); - EXPECT_EQ(Vector2dF(3.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(Vector2dF(4.5f, 2.5f)); - EXPECT_EQ(Vector2dF(4.5f, 5.5f).ToString(), a.ToString()); - a.SetToMax(Vector2dF(8.5f, 10.5f)); - EXPECT_EQ(Vector2dF(8.5f, 10.5f).ToString(), a.ToString()); - - a.SetToMin(Vector2dF(9.5f, 11.5f)); - EXPECT_EQ(Vector2dF(8.5f, 10.5f).ToString(), a.ToString()); - a.SetToMin(Vector2dF(8.5f, 10.5f)); - EXPECT_EQ(Vector2dF(8.5f, 10.5f).ToString(), a.ToString()); - a.SetToMin(Vector2dF(11.5f, 9.5f)); - EXPECT_EQ(Vector2dF(8.5f, 9.5f).ToString(), a.ToString()); - a.SetToMin(Vector2dF(7.5f, 11.5f)); - EXPECT_EQ(Vector2dF(7.5f, 9.5f).ToString(), a.ToString()); - a.SetToMin(Vector2dF(3.5f, 5.5f)); - EXPECT_EQ(Vector2dF(3.5f, 5.5f).ToString(), a.ToString()); + EXPECT_EQ(Vector2d(3, 5), a); } TEST(Vector2dTest, IntegerOverflow) {
diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc index 52ce88f4..4a63438 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc +++ b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc
@@ -50,7 +50,8 @@ widget_ = widget; - if (!buffer_manager_->gbm_device()) + auto* gbm_device = buffer_manager_->GetGbmDevice(); + if (!gbm_device) return false; const uint32_t fourcc_format = GetFourCCFormatFromBufferFormat(format); @@ -60,16 +61,15 @@ // Create buffer object without format modifiers unless they are explicitly // advertised by the Wayland compositor, via linux-dmabuf protocol. if (modifiers.empty()) { - gbm_bo_ = buffer_manager_->gbm_device()->CreateBuffer(fourcc_format, size, - gbm_flags); + gbm_bo_ = gbm_device->CreateBuffer(fourcc_format, size, gbm_flags); } else { // When buffer |usage| implies on GBM_BO_USE_LINEAR, pass in // DRM_FORMAT_MOD_LINEAR, i.e: no tiling, when creating gbm buffers, // otherwise it fails to create BOs. if (gbm_flags & GBM_BO_USE_LINEAR) modifiers = {DRM_FORMAT_MOD_LINEAR}; - gbm_bo_ = buffer_manager_->gbm_device()->CreateBufferWithModifiers( - fourcc_format, size, gbm_flags, modifiers); + gbm_bo_ = gbm_device->CreateBufferWithModifiers(fourcc_format, size, + gbm_flags, modifiers); } if (!gbm_bo_) { @@ -94,13 +94,14 @@ gfx::BufferFormat format, gfx::NativePixmapHandle handle) { TRACE_EVENT0("wayland", "GbmPixmapWayland::InitializeBufferFromHandle"); - if (!buffer_manager_->gbm_device()) + auto* gbm_device = buffer_manager_->GetGbmDevice(); + if (!gbm_device) return false; widget_ = widget; // Create a buffer object from handle. - gbm_bo_ = buffer_manager_->gbm_device()->CreateBufferFromHandle( + gbm_bo_ = gbm_device->CreateBufferFromHandle( GetFourCCFormatFromBufferFormat(format), size, std::move(handle)); if (!gbm_bo_) { LOG(ERROR) << "Cannot create bo with format= "
diff --git a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc index b443a51..5bbdd68 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc +++ b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
@@ -16,6 +16,12 @@ #include "ui/ozone/public/mojom/wayland/wayland_overlay_config.mojom.h" #include "ui/ozone/public/overlay_plane.h" +#if defined(WAYLAND_GBM) +#include "ui/gfx/linux/gbm_wrapper.h" +#include "ui/ozone/platform/wayland/gpu/drm_render_node_handle.h" +#include "ui/ozone/platform/wayland/gpu/drm_render_node_path_finder.h" +#endif + namespace mojo { // static ui::ozone::mojom::WaylandOverlayConfigPtr @@ -68,15 +74,11 @@ bool supports_acquire_fence, bool supports_non_backed_solid_color_buffers) { supported_buffer_formats_with_modifiers_ = buffer_formats_with_modifiers; - -#if defined(WAYLAND_GBM) - if (!supports_dma_buf) - set_gbm_device(nullptr); -#endif supports_viewporter_ = supports_viewporter; supports_acquire_fence_ = supports_acquire_fence; supports_non_backed_solid_color_buffers_ = supports_non_backed_solid_color_buffers; + supports_dmabuf_ = supports_dma_buf; BindHostInterface(std::move(remote_host)); @@ -269,6 +271,40 @@ base::Unretained(this), widget, buffer_id)); } +#if defined(WAYLAND_GBM) +GbmDevice* WaylandBufferManagerGpu::GetGbmDevice() { + if (!supports_dmabuf_) + return nullptr; + + if (gbm_device_ || use_fake_gbm_device_for_test_) + return gbm_device_.get(); + + DrmRenderNodePathFinder path_finder; + const base::FilePath drm_node_path = path_finder.GetDrmRenderNodePath(); + if (drm_node_path.empty()) { + supports_dmabuf_ = false; + LOG(WARNING) << "Failed to find drm render node path."; + return nullptr; + } + + DrmRenderNodeHandle handle; + if (!handle.Initialize(drm_node_path)) { + supports_dmabuf_ = false; + LOG(WARNING) << "Failed to initialize drm render node handle."; + return nullptr; + } + + gbm_device_ = CreateGbmDevice(handle.PassFD().release()); + if (!gbm_device_) { + supports_dmabuf_ = false; + LOG(WARNING) << "Failed to initialize gbm device."; + return nullptr; + } + + return gbm_device_.get(); +} +#endif // defined(WAYLAND_GBM) + void WaylandBufferManagerGpu::AddBindingWaylandBufferManagerGpu( mojo::PendingReceiver<ozone::mojom::WaylandBufferManagerGpu> receiver) { receiver_set_.Add(this, std::move(receiver));
diff --git a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h index 3d6dde8..e72846d5 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h +++ b/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h
@@ -20,16 +20,13 @@ #include "ui/ozone/platform/wayland/common/wayland_util.h" #include "ui/ozone/public/mojom/wayland/wayland_buffer_manager.mojom.h" -#if defined(WAYLAND_GBM) -#include "ui/gfx/linux/gbm_device.h" // nogncheck -#endif - namespace gfx { enum class SwapResult; } // namespace gfx namespace ui { +class GbmDevice; class WaylandConnection; class WaylandSurfaceGpu; class WaylandWindow; @@ -135,10 +132,7 @@ #if defined(WAYLAND_GBM) // Returns a gbm_device based on a DRM render node. - GbmDevice* gbm_device() const { return gbm_device_.get(); } - void set_gbm_device(std::unique_ptr<GbmDevice> gbm_device) { - gbm_device_ = std::move(gbm_device); - } + GbmDevice* GetGbmDevice(); #endif bool supports_acquire_fence() const { return supports_acquire_fence_; } @@ -159,6 +153,12 @@ uint32_t AllocateBufferID(); private: + FRIEND_TEST_ALL_PREFIXES(WaylandSurfaceFactoryTest, CreateSurfaceCheckGbm); + FRIEND_TEST_ALL_PREFIXES(WaylandSurfaceFactoryTest, + GbmSurfacelessWaylandCommitOverlaysCallbacksTest); + FRIEND_TEST_ALL_PREFIXES(WaylandSurfaceFactoryTest, + GbmSurfacelessWaylandGroupOnSubmissionCallbacksTest); + void CreateDmabufBasedBufferInternal(base::ScopedFD dmabuf_fd, gfx::Size size, const std::vector<uint32_t>& strides, @@ -201,6 +201,10 @@ #if defined(WAYLAND_GBM) // A DRM render node based gbm device. std::unique_ptr<GbmDevice> gbm_device_; + // When set, avoids creating a real gbm_device. Instead, tests that set + // this variable to true must set own instance of the GbmDevice. See the + // CreateSurfaceCheckGbm for example. + bool use_fake_gbm_device_for_test_ = false; #endif // Whether Wayland server allows buffer submission with acquire fence. bool supports_acquire_fence_ = false; @@ -213,6 +217,10 @@ // image via a wayland protocol. bool supports_non_backed_solid_color_buffers_ = false; + // Determines whether Wayland server supports Wayland protocols that allow to + // export wl_buffers backed by dmabuf. + bool supports_dmabuf_ = false; + mojo::ReceiverSet<ozone::mojom::WaylandBufferManagerGpu> receiver_set_; // A pointer to a WaylandBufferManagerHost object, which always lives on a
diff --git a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc index 327c515..486846f 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc +++ b/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
@@ -92,7 +92,7 @@ } else { #if defined(WAYLAND_GBM) // If there is a gbm device available, use surfaceless gl surface. - if (!buffer_manager_->gbm_device()) + if (!buffer_manager_->GetGbmDevice()) return nullptr; return gl::InitializeGLSurface( new GbmSurfacelessWayland(buffer_manager_, window));
diff --git a/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc b/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc index c2c082df..683bf496 100644 --- a/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc +++ b/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc
@@ -230,7 +230,9 @@ // SwapCompletionCallbacks run. gl::SetGLImplementation(gl::kGLImplementationEGLGLES2); - buffer_manager_gpu_->set_gbm_device(std::make_unique<MockGbmDevice>()); + buffer_manager_gpu_->use_fake_gbm_device_for_test_ = true; + buffer_manager_gpu_->gbm_device_ = std::make_unique<MockGbmDevice>(); + buffer_manager_gpu_->supports_dmabuf_ = true; auto* gl_ozone = surface_factory_->GetGLOzone( gl::GLImplementationParts(gl::kGLImplementationEGLGLES2)); @@ -476,7 +478,9 @@ // SwapCompletionCallbacks. gl::SetGLImplementation(gl::kGLImplementationEGLGLES2); - buffer_manager_gpu_->set_gbm_device(std::make_unique<MockGbmDevice>()); + buffer_manager_gpu_->use_fake_gbm_device_for_test_ = true; + buffer_manager_gpu_->gbm_device_ = std::make_unique<MockGbmDevice>(); + buffer_manager_gpu_->supports_dmabuf_ = true; auto* gl_ozone = surface_factory_->GetGLOzone( gl::GLImplementationParts(gl::kGLImplementationEGLGLES2)); @@ -777,9 +781,11 @@ TEST_P(WaylandSurfaceFactoryTest, CreateSurfaceCheckGbm) { gl::SetGLImplementation(gl::kGLImplementationEGLGLES2); + buffer_manager_gpu_->use_fake_gbm_device_for_test_ = true; + // When gbm is not available, only canvas can be created with viz process // used. - EXPECT_FALSE(buffer_manager_gpu_->gbm_device()); + EXPECT_FALSE(buffer_manager_gpu_->GetGbmDevice()); auto* gl_ozone = surface_factory_->GetGLOzone( gl::GLImplementationParts(gl::kGLImplementationEGLGLES2)); @@ -788,14 +794,23 @@ EXPECT_FALSE(gl_surface); // Now, set gbm. - buffer_manager_gpu_->set_gbm_device(std::make_unique<MockGbmDevice>()); + buffer_manager_gpu_->gbm_device_ = std::make_unique<MockGbmDevice>(); + // It's still impossible to create the device if supports_dmabuf is false. + EXPECT_FALSE(buffer_manager_gpu_->GetGbmDevice()); + gl_surface = gl_ozone->CreateSurfacelessViewGLSurface(widget_); + EXPECT_FALSE(gl_surface); + + // Now set supports_dmabuf. + buffer_manager_gpu_->supports_dmabuf_ = true; + EXPECT_TRUE(buffer_manager_gpu_->GetGbmDevice()); gl_surface = gl_ozone->CreateSurfacelessViewGLSurface(widget_); EXPECT_TRUE(gl_surface); // Reset gbm now. WaylandConnectionProxy can reset it when zwp is not // available. And factory must behave the same way as previously. - buffer_manager_gpu_->set_gbm_device(nullptr); + buffer_manager_gpu_->gbm_device_ = nullptr; + EXPECT_FALSE(buffer_manager_gpu_->GetGbmDevice()); gl_surface = gl_ozone->CreateSurfacelessViewGLSurface(widget_); EXPECT_FALSE(gl_surface); }
diff --git a/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/ui/ozone/platform/wayland/ozone_platform_wayland.cc index f518d83..f50b2348 100644 --- a/ui/ozone/platform/wayland/ozone_platform_wayland.cc +++ b/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -23,6 +23,7 @@ #include "ui/events/devices/device_data_manager.h" #include "ui/events/event.h" #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h" +#include "ui/gfx/buffer_format_util.h" #include "ui/gfx/linux/client_native_pixmap_dmabuf.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/common/features.h" @@ -55,13 +56,6 @@ #include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h" #endif -#include "ui/gfx/buffer_format_util.h" - -#if defined(WAYLAND_GBM) -#include "ui/gfx/linux/gbm_wrapper.h" // nogncheck -#include "ui/ozone/platform/wayland/gpu/drm_render_node_handle.h" -#endif - #if BUILDFLAG(USE_GTK) #include "ui/ozone/platform/wayland/host/linux_ui_delegate_wayland.h" // nogncheck #endif @@ -252,22 +246,6 @@ surface_factory_ = std::make_unique<WaylandSurfaceFactory>( connection_.get(), buffer_manager_.get()); overlay_manager_ = std::make_unique<WaylandOverlayManager>(); -#if defined(WAYLAND_GBM) - const base::FilePath drm_node_path = path_finder_.GetDrmRenderNodePath(); - if (drm_node_path.empty()) { - LOG(WARNING) << "Failed to find drm render node path."; - } else { - DrmRenderNodeHandle handle; - if (!handle.Initialize(drm_node_path)) { - LOG(WARNING) << "Failed to initialize drm render node handle."; - } else { - auto gbm = CreateGbmDevice(handle.PassFD().release()); - if (!gbm) - LOG(WARNING) << "Failed to initialize gbm device."; - buffer_manager_->set_gbm_device(std::move(gbm)); - } - } -#endif } const PlatformProperties& GetPlatformProperties() override {
diff --git a/ui/views/animation/widget_fade_animator.cc b/ui/views/animation/widget_fade_animator.cc index cea896e..f86d878 100644 --- a/ui/views/animation/widget_fade_animator.cc +++ b/ui/views/animation/widget_fade_animator.cc
@@ -32,11 +32,9 @@ } void WidgetFadeAnimator::FadeOut() { - if (IsFadingOut()) + if (IsFadingOut() || !widget_) return; - DCHECK(widget_); - // If the widget is already hidden, then there is no current animation and // nothing to do. If the animation is close-on-hide, however, we should still // close the widget.
diff --git a/ui/webui/resources/BUILD.gn b/ui/webui/resources/BUILD.gn index d82af449..bc53229 100644 --- a/ui/webui/resources/BUILD.gn +++ b/ui/webui/resources/BUILD.gn
@@ -201,6 +201,7 @@ root_dir = preprocessed_folder out_dir = preprocessed_folder composite = true + tsconfig_base = "tsconfig_base.json" in_files = [ "cr_components/iph_bubble/iph_bubble.ts",
diff --git a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js index 10d54e96..a8750cc 100644 --- a/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js +++ b/ui/webui/resources/cr_components/chromeos/bluetooth/bluetooth_pairing_ui.js
@@ -167,6 +167,11 @@ this.devicePairingHandler_; /** + * @private {?chromeos.bluetoothConfig.mojom.BluetoothDeviceProperties} + */ + this.queuedDevicePendingPairing_; + + /** * @private {?chromeos.bluetoothConfig.mojom.DevicePairingDelegateReceiver} */ this.pairingDelegateReceiver_ = null; @@ -208,16 +213,29 @@ * @private */ onPairDevice_(event) { - // Pairing delegate should only be available after call to pair device - // is made. This delegate is set to null after pair request is made and - // returned, allowing for multiple pairing events in the same discovery - // session, but only one pairing event at a time. - assert(!this.pairingDelegateReceiver_); + if (!event.detail.device) { + return; + } + // If a pairing operation is currently underway, close it and queue + // the current device to be paired after pairDevice_() promise is + // returned. + if (this.pairingDelegateReceiver_) { + this.queuedDevicePendingPairing_ = event.detail.device; + this.pairingDelegateReceiver_.$.close(); + return; + } + this.pairDevice_(event.detail.device); + } + /** + * @param {!chromeos.bluetoothConfig.mojom.BluetoothDeviceProperties} device + * @private + */ + pairDevice_(device) { this.pairingDelegateReceiver_ = new chromeos.bluetoothConfig.mojom.DevicePairingDelegateReceiver(this); - this.devicePendingPairing_ = event.detail.device; + this.devicePendingPairing_ = device; assert(this.devicePendingPairing_); this.lastFailedPairingDeviceId_ = ''; @@ -236,16 +254,17 @@ * @private */ handlePairDeviceResult_(result) { - this.pairingDelegateReceiver_.$.close(); - this.pairingDelegateReceiver_ = null; + if (this.pairingDelegateReceiver_) { + this.pairingDelegateReceiver_.$.close(); + this.pairingDelegateReceiver_ = null; + } + this.pairingAuthType_ = null; if (this.keyEnteredReceiver_) { this.keyEnteredReceiver_.close(); this.keyEnteredReceiver_ = null; } - this.pairingAuthType_ = null; - if (result === chromeos.bluetoothConfig.mojom.PairingResult.kSuccess) { this.dispatchEvent(new CustomEvent('finished', { bubbles: true, @@ -257,6 +276,11 @@ this.selectedPageId_ = BluetoothPairingSubpageId.DEVICE_SELECTION_PAGE; this.lastFailedPairingDeviceId_ = this.devicePendingPairing_.id; this.devicePendingPairing_ = null; + + if (this.queuedDevicePendingPairing_) { + this.pairDevice_(this.queuedDevicePendingPairing_); + this.queuedDevicePendingPairing_ = null; + } } /** @override */
diff --git a/ui/webui/resources/cr_components/iph_bubble/BUILD.gn b/ui/webui/resources/cr_components/iph_bubble/BUILD.gn index 6983459..b8c2d7ef 100644 --- a/ui/webui/resources/cr_components/iph_bubble/BUILD.gn +++ b/ui/webui/resources/cr_components/iph_bubble/BUILD.gn
@@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//third_party/closure_compiler/compile_js.gni") import("//tools/polymer/html_to_js.gni") html_to_js("web_components") {
diff --git a/ui/webui/resources/cr_components/iph_bubble/iph_bubble.html b/ui/webui/resources/cr_components/iph_bubble/iph_bubble.html index 78405240..6c6596a 100644 --- a/ui/webui/resources/cr_components/iph_bubble/iph_bubble.html +++ b/ui/webui/resources/cr_components/iph_bubble/iph_bubble.html
@@ -1,14 +1,52 @@ <style> :host { - display: none; - opacity: 0; position: absolute; z-index: 1; } - :host([open]) { - display: block; - opacity: 1; + .arrow { + background-color: var(--iph-bubble-background); + height: 16px; + position: absolute; + transform: rotate(-45deg); + width: 16px; + z-index: -1; + } + + /* Turns the arrow direction downwards, when the bubble is placed above + * the anchor element */ + :host([position=above]) .arrow { + border-bottom-left-radius: 2px; + bottom: -8px; + left: calc(50% - 8px); + } + + /* Turns the arrow direction upwards, when the bubble is placed below + * the anchor element */ + :host([position=below]) .arrow { + border-top-right-radius: 2px; + left: calc(50% - 8px); + top: -8px; + } + + /* Turns the arrow direction to the right, when the bubble is placed to the + * left of the anchor element */ + :host([position=left]) .arrow { + border-bottom-right-radius: 2px; + right: -8px; + top: calc(50% - 8px); + } + + /* Turns the arrow direction to the left, when the bubble is placed to the + * right of the anchor element */ + :host([position=right]) .arrow { + border-top-left-radius: 2px; + left: -8px; + top: calc(50% - 8px); + } + + .body { + font-size: 14px; } .iph-bubble { @@ -21,11 +59,21 @@ width: 362px; } - .body { - font-size: 14px; + .iph-bubble-container { + display: none; + opacity: 0; + } + + :host([open]) .iph-bubble-container + { + display: block; + opacity: 1; } </style> -<div class="iph-bubble"> - <div class="body">[[body]]</div> -</div> \ No newline at end of file +<div class="iph-bubble-container"> + <div class="iph-bubble"> + <div class="body">[[body]]</div> + <div class="arrow"></div> + </div> +</div>
diff --git a/ui/webui/resources/cr_components/iph_bubble/iph_bubble.ts b/ui/webui/resources/cr_components/iph_bubble/iph_bubble.ts index 110e736..521385a 100644 --- a/ui/webui/resources/cr_components/iph_bubble/iph_bubble.ts +++ b/ui/webui/resources/cr_components/iph_bubble/iph_bubble.ts
@@ -5,10 +5,18 @@ * @fileoverview A bubble for displaying in-product help. This is a WIP, do not * use. */ +import {assert} from '//resources/js/assert.m.js'; import {html, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; const ANCHOR_HIGHLIGHT_CLASS = 'iph-anchor-highlight'; +enum Position { + Above = 'above', + Below = 'below', + Left = 'left', + Right = 'right', +} + export interface IPHBubbleElement { open: boolean; _setOpen(open: boolean): void; @@ -31,10 +39,7 @@ * must be a sibling of the iph. If this property is not set, * then the iph will be anchored to the parent node containing it. */ - anchorId: { - type: String, - value: '', - }, + anchorId: {type: String, value: ''}, /** * The main promo text. Required. @@ -50,10 +55,18 @@ value: false, reflectToAttribute: true, }, + + /** + * Determines position relative to the anchor element, and where the + * bubble's arrow points. Must be one of 'above', 'below', 'left' or + * 'right'. Required. + */ + position: {type: Position, value: Position.Above}, }; } - anchorId?: string; + anchorId: string; + position: Position; /** * HTMLElement corresponding to |this.anchorId|. @@ -70,6 +83,7 @@ // Reset the aria-hidden attribute as screen readers need to access the // contents of an opened bubble. this.removeAttribute('aria-hidden'); + this.updatePosition_(); this.highlightAnchor_(); this._setOpen(true); } @@ -100,6 +114,57 @@ } /** + * Sets the bubble position, as relative to that of the anchor element and + * |this.position|. + */ + private updatePosition_() { + assert(Object.values(Position).includes(this.position)); + if (!this.anchorElement_) { + return; + } + // Inclusive of 8px visible arrow and 8px margin. + const offset = 16; + const parentRect = this.offsetParent!.getBoundingClientRect(); + const anchorRect = this.anchorElement_.getBoundingClientRect(); + const anchorLeft = anchorRect.left - parentRect.left; + const anchorTop = anchorRect.top - parentRect.top; + let iphLeft: string, iphTop: string, iphTransform: string; + switch (this.position) { + case Position.Above: + // Anchor the iph bubble to the top center of the anchor element. + iphTop = `${anchorTop - offset}px`; + iphLeft = `${anchorLeft + anchorRect.width / 2}px`; + // Horizontally center the iph bubble. + iphTransform = `translate(-50%, -100%)`; + break; + case Position.Below: + // Anchor the iph bubble to the bottom center of the anchor element. + iphTop = `${anchorTop + anchorRect.height + offset}px`; + iphLeft = `${anchorLeft + anchorRect.width / 2}px`; + // Horizontally center the iph bubble. + iphTransform = `translateX(-50%)`; + break; + case Position.Left: + // Anchor the iph bubble to the center left of the anchor element. + iphTop = `${anchorTop + anchorRect.height / 2}px`; + iphLeft = `${anchorLeft - offset}px`; + // Vertically center the iph bubble. + iphTransform = `translate(-100%, -50%)`; + break; + case Position.Right: + // Anchor the iph bubble to the center right of the anchor element. + iphTop = `${anchorTop + anchorRect.height / 2}px`; + iphLeft = `${anchorLeft + anchorRect.width + offset}px`; + // Vertically center the iph bubble. + iphTransform = `translateY(-50%)`; + break; + } + this.style.top = iphTop; + this.style.left = iphLeft; + this.style.transform = iphTransform; + } + + /** * Styles the anchor element to appear highlighted while the bubble is open. */ private highlightAnchor_() {
diff --git a/ui/webui/resources/tsconfig_base.json b/ui/webui/resources/tsconfig_base.json new file mode 100644 index 0000000..0ad4628 --- /dev/null +++ b/ui/webui/resources/tsconfig_base.json
@@ -0,0 +1,6 @@ +{ + "extends": "../../../tools/typescript/tsconfig_base.json", + "compilerOptions": { + "strictPropertyInitialization": false + } +}