diff --git a/AUTHORS b/AUTHORS index d077d64e..bbfb909 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -288,6 +288,7 @@ Donghee Na <corona10@gmail.com> Dong-hee Na <donghee.na92@gmail.com> Dongie Agnir <dongie.agnir@gmail.com> +Dongjun Kim <deejay.kim@navercorp.com> Dongjun Kim <djmix.kim@samsung.com> Dongseong Hwang <dongseong.hwang@intel.com> Dongwoo Joshua Im <dw.im@samsung.com>
diff --git a/DEPS b/DEPS index 28cc6b8..0aded74 100644 --- a/DEPS +++ b/DEPS
@@ -228,11 +228,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': 'addccaf9cfb6fa66f5a8b007e52def5d0cf7d7be', + 'skia_revision': '9cd9d0f3de06099dff988c4f9abdcd5eb61633c3', # 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': 'f2f38b7d2a93678921f5f772f784cdd9a3962674', + 'v8_revision': '016798114a416a357e12b76d00ce57fb45637090', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -244,7 +244,7 @@ # 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': 'dcfc0a6e2d8440695e44745126747e4c8aed6cf6', + 'swiftshader_revision': '1bc8669c8b787df9d30e954a3300d925d581d38a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -347,7 +347,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': 'a0b92db396d85781c1bef7fbbaff3dd1b7057b81', + 'dawn_revision': '8e957160b1540712f996266595b8eb11458f239a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -1003,7 +1003,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a806594b95a39141fdbf1f359087a44ffb2deaaf', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a992238bf0f33c9a180afd79a08d3b0bc40b0fde', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -1389,7 +1389,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'a6966e3445f5dc2a0d9f735b8c689c5078e4c33e', + Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b846a827ab0b47d0299bc3776d1fb5c067c50d94', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1478,7 +1478,7 @@ 'packages': [ { 'package': 'fuchsia/third_party/aemu/linux-amd64', - 'version': 'XXuqQyUTKH3AEKtaMdRvFnqYJNahJ64RJtSsAz1fBEAC' + 'version': 'pwQrKzu72NdWp0pJ1seKkyxCFkbmgu1lFXdvWjQcDMkC' }, ], 'condition': 'host_os == "linux" and checkout_fuchsia', @@ -1618,10 +1618,10 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '827cad9e402b63bbe38787456115bcb681a8a152', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '6881e0cd401986aa80bdbf132ca4ab434bc1d7d7', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '26da66e2987afd8fb426c8b83f7b96d500c3fb01', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'df7156965b4bb30fb4b606f6b12bb0a949f3962f', + Var('webrtc_git') + '/src.git' + '@' + '49c9b4ec3748a7f8e37865f44a89c1be8ed6dd8c', 'src/third_party/libgifcodec': Var('skia_git') + '/libgifcodec' + '@'+ Var('libgifcodec_revision'), @@ -1682,7 +1682,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3ec09248df7f10ee4eb1add6475efb57be79d994', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1097ffdceae6ff5ef5da4fbaec9187c1a9934586', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn index b1850ac..fe9d70e2 100644 --- a/android_webview/BUILD.gn +++ b/android_webview/BUILD.gn
@@ -19,6 +19,10 @@ import("//tools/v8_context_snapshot/v8_context_snapshot.gni") import("//weblayer/variables.gni") +if (android_64bit_target_cpu && skip_secondary_abi_for_cq) { + assert(current_toolchain != android_secondary_abi_toolchain) +} + if (enable_resource_allowlist_generation) { system_webview_pak_allowlist = "$target_gen_dir/system_webview_pak_allowlist.txt" @@ -34,11 +38,18 @@ template("standalone_system_webview_apk_tmpl") { system_webview_apk_or_module_tmpl(target_name) { forward_variables_from(invoker, "*") - android_manifest = system_webview_android_manifest - android_manifest_dep = - "//android_webview/nonembedded:system_webview_manifest" deps = upstream_only_webview_deps min_sdk_version = 21 + if (android_64bit_target_cpu && defined(include_32_bit_webview) && + !include_32_bit_webview) { + android_manifest = system_webview_64_android_manifest + android_manifest_dep = + "//android_webview/nonembedded:system_webview_64_manifest" + } else { + android_manifest = system_webview_android_manifest + android_manifest_dep = + "//android_webview/nonembedded:system_webview_manifest" + } } } @@ -172,9 +183,6 @@ template("trichrome_webview_tmpl") { system_webview_apk_or_module_tmpl(target_name) { forward_variables_from(invoker, "*") - android_manifest = trichrome_webview_android_manifest - android_manifest_dep = - "//android_webview/nonembedded:trichrome_webview_manifest" min_sdk_version = 29 deps = upstream_only_webview_deps @@ -197,6 +205,9 @@ is_64_bit_browser = false include_64_bit_webview = true } + android_manifest = trichrome_webview_android_manifest + android_manifest_dep = + "//android_webview/nonembedded:trichrome_webview_manifest" static_library_provider = "//chrome/android:trichrome_library_apk" } } @@ -210,6 +221,9 @@ } is_64_bit_browser = true include_32_bit_webview = false + android_manifest = trichrome_webview_64_android_manifest + android_manifest_dep = + "//android_webview/nonembedded:trichrome_webview_64_manifest" static_library_provider = "//chrome/android:trichrome_library_64_apk" } } @@ -229,6 +243,10 @@ include_64_bit_webview = true } + android_manifest = trichrome_webview_android_manifest + android_manifest_dep = + "//android_webview/nonembedded:trichrome_webview_manifest" + if (_verify_android_configuration) { expected_android_manifest = "expectations/trichrome_webview_bundle.AndroidManifest.expected" @@ -260,6 +278,9 @@ bundle_target = ":trichrome_webview_64_bundle" is_64_bit_browser = true include_32_bit_webview = false + android_manifest = trichrome_webview_64_android_manifest + android_manifest_dep = + "//android_webview/nonembedded:trichrome_webview_64_manifest" static_library_provider = "//chrome/android:trichrome_library_64_apk" } }
diff --git a/android_webview/browser/aw_browser_terminator.cc b/android_webview/browser/aw_browser_terminator.cc index 43923eb..b507ed4 100644 --- a/android_webview/browser/aw_browser_terminator.cc +++ b/android_webview/browser/aw_browser_terminator.cc
@@ -12,6 +12,7 @@ #include "android_webview/common/aw_descriptors.h" #include "base/android/scoped_java_ref.h" #include "base/logging.h" +#include "base/metrics/histogram_functions.h" #include "base/strings/stringprintf.h" #include "components/crash/content/browser/crash_metrics_reporter_android.h" #include "components/crash/core/app/crashpad.h" @@ -34,6 +35,19 @@ namespace { +constexpr char kRenderProcessGoneHistogramName[] = + "Android.WebView.OnRenderProcessGoneResult"; + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class RenderProcessGoneResult { + kJavaException = 0, + kCrashNotHandled = 1, + kKillNotHandled = 2, + kAllWebViewsHandled = 3, + kMaxValue = kAllWebViewsHandled, +}; + void GetJavaWebContentsForRenderProcess( content::RenderProcessHost* rph, std::vector<ScopedJavaGlobalRef<jobject>>* java_web_contents) { @@ -70,11 +84,16 @@ switch (delegate->OnRenderProcessGone(child_process_pid, crashed)) { case AwRenderProcessGoneDelegate::RenderProcessGoneResult::kException: + base::UmaHistogramEnumeration(kRenderProcessGoneHistogramName, + RenderProcessGoneResult::kJavaException); // Let the exception propagate back to the message loop. base::CurrentUIThread::Get()->Abort(); return; case AwRenderProcessGoneDelegate::RenderProcessGoneResult::kUnhandled: if (crashed) { + base::UmaHistogramEnumeration( + kRenderProcessGoneHistogramName, + RenderProcessGoneResult::kCrashNotHandled); // Keeps this log unchanged, CTS test uses it to detect crash. std::string message = base::StringPrintf( "Render process (%d)'s crash wasn't handled by all associated " @@ -82,6 +101,9 @@ child_process_pid); crash_reporter::CrashWithoutDumping(message); } else { + base::UmaHistogramEnumeration( + kRenderProcessGoneHistogramName, + RenderProcessGoneResult::kKillNotHandled); // The render process was most likely killed for OOM or switching // WebView provider, to make WebView backward compatible, kills the // browser process instead of triggering crash. @@ -93,9 +115,14 @@ NOTREACHED(); break; case AwRenderProcessGoneDelegate::RenderProcessGoneResult::kHandled: + // Don't log UMA yet. This WebView may be handled, but we need to wait + // until we're out of the loop to know if all WebViews were handled. break; } } + // If we reached this point, it means the crash was handled for all WebViews. + base::UmaHistogramEnumeration(kRenderProcessGoneHistogramName, + RenderProcessGoneResult::kAllWebViewsHandled); // By this point we have moved the minidump to the crash directory, so it can // now be copied and uploaded.
diff --git a/android_webview/nonembedded/BUILD.gn b/android_webview/nonembedded/BUILD.gn index dd576ba..296ac6d 100644 --- a/android_webview/nonembedded/BUILD.gn +++ b/android_webview/nonembedded/BUILD.gn
@@ -245,6 +245,22 @@ } if (android_64bit_target_cpu) { + jinja_template("system_webview_64_manifest") { + input = "java/AndroidManifest.xml" + output = system_webview_64_android_manifest + variables = _webview_jinja_variables + [ "use32bitAbi=" ] + } + + jinja_template("trichrome_webview_64_manifest") { + input = "java/AndroidManifest.xml" + output = trichrome_webview_64_android_manifest + variables = trichrome_jinja_variables + _webview_jinja_variables + [ + "use32bitAbi=", + "trichrome_version=$trichrome_64_version_code", + "library=libmonochrome_64.so", + ] + } + jinja_template("trichrome_webview_64_32_manifest") { input = "java/AndroidManifest.xml" output = trichrome_webview_64_32_android_manifest
diff --git a/android_webview/test/components/crx_smoke_tests.py b/android_webview/test/components/crx_smoke_tests.py index 3484aa2..dbd4fb2 100644 --- a/android_webview/test/components/crx_smoke_tests.py +++ b/android_webview/test/components/crx_smoke_tests.py
@@ -11,6 +11,7 @@ import zipfile from collections import namedtuple +from devil.android import logcat_monitor from py_utils.tempfile_ext import NamedTemporaryDirectory from telemetry.testing import serially_executed_browser_test_case @@ -28,12 +29,21 @@ '--enable-features=WebViewAppsPackageNamesAllowlist', '--vmodule=*_allowlist_component_*=2']) } +_LOGCAT_FILTERS = [ + 'chromium:v', + 'cr_*:v', + 'DEBUG:I', + 'StrictMode:D', + 'WebView*:v' +] + class WebViewCrxSmokeTests( serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase): _device = None _device_components_dir = None + _logcat_monitor = None @classmethod def Name(cls): @@ -76,9 +86,23 @@ assert cls._finder_options.webview_package_name, ( '--webview-package-name is required') + + cls.SetBrowserOptions(cls._finder_options) cls._device_components_dir = ('/data/data/%s/app_webview/components' % cls._finder_options.webview_package_name) - cls.SetBrowserOptions(cls._finder_options) + + logcat_output_dir = ( + os.path.dirname(cls._typ_runner.args.write_full_results_to or '') or + os.getcwd()) + + # Set up a logcat monitor + cls._logcat_monitor = logcat_monitor.LogcatMonitor( + cls._device.adb, + output_file=os.path.join(logcat_output_dir, + '%s_logcat.txt' % cls.Name()), + filter_specs=_LOGCAT_FILTERS) + cls._logcat_monitor.Start() + cls._MaybeClearOutComponentsDir() component_id = _COMPONENT_NAME_TO_DATA.get( cls._finder_options.component_name).component_id @@ -156,6 +180,11 @@ browser_tab.action_runner.WaitForJavaScriptCondition( 'window.webview_smoke_test_harness.test_succeeded', timeout=300) + @classmethod + def TearDownProcess(cls): + super(WebViewCrxSmokeTests, cls).TearDownProcess() + cls._logcat_monitor.Stop() + def load_tests(*_): return serially_executed_browser_test_case.LoadAllTestsInModule(sys.modules[__name__])
diff --git a/android_webview/test/components/run_webview_component_smoketest.py b/android_webview/test/components/run_webview_component_smoketest.py index f4b8675f..f238507 100755 --- a/android_webview/test/components/run_webview_component_smoketest.py +++ b/android_webview/test/components/run_webview_component_smoketest.py
@@ -14,10 +14,15 @@ os.pardir, os.pardir, os.pardir) + +BUILD_ANDROID = os.path.join(SRC_DIR, 'build', 'android') PERF_DIR = os.path.join(SRC_DIR, 'tools', 'perf') PY_UTILS_DIR = os.path.join( SRC_DIR, 'third_party', 'catapult', 'common', 'py_utils') +if BUILD_ANDROID not in sys.path: + sys.path.append(BUILD_ANDROID) + if PERF_DIR not in sys.path: sys.path.append(PERF_DIR)
diff --git a/android_webview/tools/remove_preinstalled_webview.py b/android_webview/tools/remove_preinstalled_webview.py index b9eeb23..fb7b973 100755 --- a/android_webview/tools/remove_preinstalled_webview.py +++ b/android_webview/tools/remove_preinstalled_webview.py
@@ -118,4 +118,4 @@ if __name__ == '__main__': - sys.exit(main()) + main()
diff --git a/android_webview/variables.gni b/android_webview/variables.gni index b7a576c..4e053942 100644 --- a/android_webview/variables.gni +++ b/android_webview/variables.gni
@@ -16,8 +16,12 @@ system_webview_android_manifest = "$root_gen_dir/android_webview/system_webview_apk/AndroidManifest.xml" +system_webview_64_android_manifest = + "$root_gen_dir/android_webview/system_webview_64_apk/AndroidManifest.xml" trichrome_webview_android_manifest = "$root_gen_dir/android_webview/trichrome_webview_apk/AndroidManifest.xml" +trichrome_webview_64_android_manifest = + "$root_gen_dir/android_webview/trichrome_webview_64_apk/AndroidManifest.xml" trichrome_webview_64_32_android_manifest = "$root_gen_dir/android_webview/trichrome_webview_64_32_apk/AndroidManifest.xml" trichrome_webview_32_android_manifest = "$root_gen_dir/android_webview/trichrome_webview_32_apk/AndroidManifest.xml"
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 5a70048..0b684af 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -706,6 +706,7 @@ "public/cpp/shelf_config.h", "public/cpp/shelf_test_api.h", "public/cpp/split_view_test_api.h", + "public/cpp/style/scoped_light_mode_as_default.h", "public/cpp/window_finder.h", "public/cpp/window_tree_host_lookup.h", "quick_answers/quick_answers_controller_impl.cc", @@ -877,7 +878,6 @@ "style/default_colors.cc", "style/default_colors.h", "style/scoped_light_mode_as_default.cc", - "style/scoped_light_mode_as_default.h", "system/accessibility/accessibility_feature_disable_dialog.cc", "system/accessibility/accessibility_feature_disable_dialog.h", "system/accessibility/accessibility_feature_pod_controller.cc", @@ -2471,9 +2471,7 @@ "wm/workspace/workspace_window_resizer_unittest.cc", "wm/workspace_controller_unittest.cc", ] - configs += [ - "//build/config:precompiled_headers", - ] + configs += [ "//build/config:precompiled_headers" ] deps = [ ":ash",
diff --git a/ash/accessibility/accessibility_controller_impl.cc b/ash/accessibility/accessibility_controller_impl.cc index a3e0e70..a61422f 100644 --- a/ash/accessibility/accessibility_controller_impl.cc +++ b/ash/accessibility/accessibility_controller_impl.cc
@@ -129,9 +129,6 @@ // An array describing the confirmation dialogs for the features which have // them. const FeatureDialogData kFeatureDialogs[] = { - {FeatureType::kDictation, prefs::kDictationAcceleratorDialogHasBeenAccepted, - IDS_ASH_DICTATION_CONFIRMATION_TITLE, IDS_ASH_DICTATION_CONFIRMATION_BODY, - true}, {FeatureType::kFullscreenMagnifier, prefs::kScreenMagnifierAcceleratorDialogHasBeenAccepted, IDS_ASH_SCREEN_MAGNIFIER_TITLE, IDS_ASH_SCREEN_MAGNIFIER_BODY, false}, @@ -807,9 +804,9 @@ return GetFeature(FeatureType::kCursorColor); } -AccessibilityControllerImpl::FeatureWithDialog& -AccessibilityControllerImpl::dictation() const { - return static_cast<FeatureWithDialog&>(GetFeature(FeatureType::kDictation)); +AccessibilityControllerImpl::Feature& AccessibilityControllerImpl::dictation() + const { + return GetFeature(FeatureType::kDictation); } AccessibilityControllerImpl::Feature&
diff --git a/ash/accessibility/accessibility_controller_impl.h b/ash/accessibility/accessibility_controller_impl.h index 376daa9..f7523873 100644 --- a/ash/accessibility/accessibility_controller_impl.h +++ b/ash/accessibility/accessibility_controller_impl.h
@@ -179,7 +179,7 @@ Feature& autoclick() const; Feature& caret_highlight() const; Feature& cursor_highlight() const; - FeatureWithDialog& dictation() const; + Feature& dictation() const; Feature& floating_menu() const; Feature& focus_highlight() const; FeatureWithDialog& fullscreen_magnifier() const;
diff --git a/ash/app_list/paged_view_structure.cc b/ash/app_list/paged_view_structure.cc index 5f08f99..320b0d24 100644 --- a/ash/app_list/paged_view_structure.cc +++ b/ash/app_list/paged_view_structure.cc
@@ -25,13 +25,19 @@ PagedViewStructure::~PagedViewStructure() = default; +void PagedViewStructure::Init(Mode mode) { + mode_ = mode; +} + void PagedViewStructure::LoadFromMetadata() { + const auto* view_model = apps_grid_view_->view_model(); + const size_t tiles_per_page = TilesPerPage(); + pages_.clear(); pages_.emplace_back(); - // When ignoring page breaks, just copy the view model. - if (ignore_page_breaks_) { - auto* view_model = apps_grid_view_->view_model(); + if (mode_ == Mode::kSinglePage) { + // Copy the view model to a single page. pages_[0].reserve(view_model->view_size()); for (int i = 0; i < view_model->view_size(); ++i) { pages_[0].push_back(view_model->view_at(i)); @@ -39,6 +45,16 @@ return; } + if (mode_ == Mode::kFullPages) { + // Copy the view model to N full pages. + for (int i = 0; i < view_model->view_size(); ++i) { + if (pages_.back().size() == tiles_per_page) + pages_.emplace_back(); + pages_.back().push_back(view_model->view_at(i)); + } + return; + } + int model_index = 0; for (size_t i = 0; i < apps_grid_view_->item_list_->item_count(); ++i) { const auto* item = apps_grid_view_->item_list_->item_at(i); @@ -67,7 +83,7 @@ void PagedViewStructure::SaveToMetadata() { // When ignoring page breaks we don't need to add or remove page breaks from // the data model. - if (ignore_page_breaks_) + if (mode_ == Mode::kFullPages || mode_ == Mode::kSinglePage) return; auto* item_list = apps_grid_view_->item_list_; @@ -184,6 +200,15 @@ } GridIndex PagedViewStructure::GetIndexFromModelIndex(int model_index) const { + if (mode_ == Mode::kSinglePage) + return GridIndex(0, model_index); + + if (mode_ == Mode::kFullPages) { + const int tiles_per_page = TilesPerPage(); + return GridIndex(model_index / tiles_per_page, + model_index % tiles_per_page); + } + AppListItemView* view = apps_grid_view_->view_model()->view_at(model_index); for (size_t i = 0; i < pages_.size(); ++i) { auto& page = pages_[i]; @@ -196,6 +221,14 @@ } int PagedViewStructure::GetModelIndexFromIndex(const GridIndex& index) const { + if (mode_ == Mode::kSinglePage) { + DCHECK_EQ(index.page, 0); + return index.slot; + } + + if (mode_ == Mode::kFullPages) + return index.page * TilesPerPage() + index.slot; + auto* view_model = apps_grid_view_->view_model(); if (index.page >= total_pages() || index.slot >= items_on_page(index.page)) return view_model->view_size(); @@ -208,6 +241,11 @@ if (apps_grid_view_->view_model()->view_size() == 0) return GridIndex(0, 0); + if (mode_ == Mode::kSinglePage || mode_ == Mode::kFullPages) { + int view_index = apps_grid_view_->view_model()->view_size() - 1; + return GetIndexFromModelIndex(view_index); + } + int last_page_index = total_pages() - 1; int target_slot = CalculateTargetSlot(pages_.back()); if (target_slot == apps_grid_view_->TilesPerPage()) { @@ -220,6 +258,17 @@ } GridIndex PagedViewStructure::GetLastTargetIndexOfPage(int page_index) const { + if (mode_ == Mode::kSinglePage) { + DCHECK_EQ(page_index, 0); + return GetLastTargetIndex(); + } + + if (mode_ == Mode::kFullPages) { + if (page_index == apps_grid_view_->pagination_model_.total_pages() - 1) + return GetLastTargetIndex(); + return GridIndex(page_index, TilesPerPage() - 1); + } + const int page_size = total_pages(); DCHECK_LT(0, apps_grid_view_->view_model()->view_size()); DCHECK_LE(page_index, page_size); @@ -239,6 +288,9 @@ int PagedViewStructure::GetTargetModelIndexForMove( AppListItemView* moved_view, const GridIndex& index) const { + if (mode_ == Mode::kSinglePage || mode_ == Mode::kFullPages) + return GetModelIndexFromIndex(index); + int target_model_index = 0; const int max_page = std::min(index.page, total_pages()); for (int i = 0; i < max_page; ++i) { @@ -259,11 +311,34 @@ return target_model_index; } -int PagedViewStructure::GetTargetItemIndexForMove( +int PagedViewStructure::GetTargetItemListIndexForMove( AppListItemView* moved_view, const GridIndex& index) const { - // Should only be called from PagedAppsGridView, which uses page breaks. - DCHECK(!ignore_page_breaks_); + if (mode_ == Mode::kFullPages) + return GetModelIndexFromIndex(index); + + if (mode_ == Mode::kSinglePage) { + DCHECK_EQ(index.page, 0); + GridIndex current_index(0, 0); + size_t current_item_index = 0; + + // Skip the leading "page break" items. + const auto* item_list = apps_grid_view_->item_list_; + while (current_item_index < item_list->item_count() && + item_list->item_at(current_item_index)->is_page_break()) { + ++current_item_index; + } + + while (current_item_index < item_list->item_count() && + current_index != index) { + if (!item_list->item_at(current_item_index)->is_page_break()) + ++current_index.slot; + ++current_item_index; + } + DCHECK_EQ(current_index, index); + return current_item_index; + } + GridIndex current_index(0, 0); size_t current_item_index = 0; size_t offset = 0; @@ -308,6 +383,9 @@ bool PagedViewStructure::IsValidReorderTargetIndex( const GridIndex& index) const { + if (mode_ == Mode::kFullPages) + return apps_grid_view_->IsValidIndex(index); + if (apps_grid_view_->IsValidIndex(index)) return true; @@ -321,6 +399,7 @@ } void PagedViewStructure::AppendPage() { + DCHECK_NE(mode_, Mode::kSinglePage); pages_.emplace_back(); } @@ -388,4 +467,8 @@ return changed; } +int PagedViewStructure::TilesPerPage() const { + return apps_grid_view_->TilesPerPage(); +} + } // namespace ash
diff --git a/ash/app_list/paged_view_structure.h b/ash/app_list/paged_view_structure.h index aa59c4e..b628055 100644 --- a/ash/app_list/paged_view_structure.h +++ b/ash/app_list/paged_view_structure.h
@@ -17,7 +17,8 @@ class AppListItemView; struct GridIndex; -// The structure of app list item views in root apps grid view. +// Manages the mapping between AppListItemList index, view model index, and +// visual pages in the apps grid view. class ASH_EXPORT PagedViewStructure { public: using Page = std::vector<AppListItemView*>; @@ -27,6 +28,17 @@ PagedViewStructure(const PagedViewStructure& other); ~PagedViewStructure(); + enum class Mode { + // Paged, with partially full pages created by page break items. + kPartialPages, + // Paged, with all pages full. Used for folders. + kFullPages, + // A single long page. Ignores page breaks in the data model. Used for + // scrollable apps grid. + kSinglePage + }; + void Init(Mode mode); + // Loads the view structure based on the position and page position in the // metadata of item views in the view model. void LoadFromMetadata(); @@ -69,10 +81,10 @@ int GetTargetModelIndexForMove(AppListItemView* moved_view, const GridIndex& index) const; - // Returns the target item index if moving the item view to specified target - // visual index. - int GetTargetItemIndexForMove(AppListItemView* moved_view, - const GridIndex& index) const; + // Returns the target `AppsGridView::item_list_` index if moving the item view + // to specified target visual index. + int GetTargetItemListIndexForMove(AppListItemView* moved_view, + const GridIndex& index) const; // Returns true if the visual index is valid position to which an item view // can be moved. @@ -95,8 +107,6 @@ const Pages& pages() const { return pages_; } - void set_ignore_page_breaks() { ignore_page_breaks_ = true; } - private: // Skips the item view being dragged if it exists in the specified // |page|. @@ -109,16 +119,16 @@ // Removes empty page. Returns true if view structure is changed. bool ClearEmptyPages(); + // Returns TilesPerPage() from `apps_grid_view_`. + int TilesPerPage() const; + + // Not const for tests. + Mode mode_ = Mode::kPartialPages; + // Represents the item views' locations in each page. Pages pages_; AppsGridView* const apps_grid_view_; // Not owned. - - // Ignores page breaks in the data model, resulting in a structure with a - // single long page. - // TODO(crbug.com/1211608): Eliminate ScrollableAppsGridView's dependence on - // this class, then remove this member. - bool ignore_page_breaks_ = false; }; } // namespace ash
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index d737ebd6..c6a38b6 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc
@@ -703,7 +703,7 @@ else AnimateToIdealBounds(); - if (!cancel && !folder_delegate_) + if (!cancel) view_structure_.SaveToMetadata(); if (!cancel) { @@ -711,8 +711,9 @@ // dragged item ends up in a folder. const int model_index = GetModelIndexOfItem(drag_item); if (model_index < view_model_.view_size()) { - pagination_model_.SelectPage(GetIndexFromModelIndex(model_index).page, - false /* animate */); + pagination_model_.SelectPage( + view_structure_.GetIndexFromModelIndex(model_index).page, + false /* animate */); } } @@ -741,7 +742,7 @@ // Since the item is new, its placeholder is conceptually at the back of the // entire apps grid. - reorder_placeholder_ = GetLastTargetIndex(); + reorder_placeholder_ = view_structure_.GetLastTargetIndex(); // Create a new AppListItemView to duplicate the original_drag_view in the // folder's grid view. @@ -767,8 +768,7 @@ // Add drag_view_ to the end of the view_model_. view_model_.Add(drag_view_, view_model_.view_size()); - if (!folder_delegate_) - view_structure_.Add(drag_view_, GetLastTargetIndex()); + view_structure_.Add(drag_view_, view_structure_.GetLastTargetIndex()); drag_start_grid_view_ = drag_point; @@ -944,8 +944,7 @@ view_model_.Add(view.get(), view_model_.view_size()); items_container_->AddChildView(std::move(view)); } - if (!folder_delegate_) - view_structure_.LoadFromMetadata(); + view_structure_.LoadFromMetadata(); UpdateColsAndRowsForFolder(); UpdatePaging(); UpdatePulsingBlockViews(); @@ -1056,14 +1055,14 @@ if (model_index == -1) return GridIndex(); - return GetIndexFromModelIndex(model_index); + return view_structure_.GetIndexFromModelIndex(model_index); } AppListItemView* AppsGridView::GetViewAtIndex(const GridIndex& index) const { if (!IsValidIndex(index)) return nullptr; - const int model_index = GetModelIndexFromIndex(index); + const int model_index = view_structure_.GetModelIndexFromIndex(index); return GetItemViewAt(model_index); } @@ -1117,12 +1116,12 @@ if (i < view_model_.view_size() && view_model_.view_at(i) == drag_view_) continue; - GridIndex view_index = GetIndexFromModelIndex(slot_index); + GridIndex view_index = view_structure_.GetIndexFromModelIndex(slot_index); // Leaves a blank space in the grid for the current reorder placeholder. if (reorder_placeholder_ == view_index) { ++slot_index; - view_index = GetIndexFromModelIndex(slot_index); + view_index = view_structure_.GetIndexFromModelIndex(slot_index); } gfx::Rect tile_slot = GetExpectedTileBounds(view_index); @@ -1413,14 +1412,15 @@ int col = (point.x() - bounds.x() + x_offset - GetGridCenteringOffset().x()) / total_tile_size.width(); col = base::clamp(col, 0, cols_ - 1); + const int selected_page = pagination_model_.selected_page(); drop_target_ = - std::min(GridIndex(pagination_model_.selected_page(), row * cols_ + col), - GetLastTargetIndexOfPage(pagination_model_.selected_page())); + std::min(GridIndex(selected_page, row * cols_ + col), + view_structure_.GetLastTargetIndexOfPage(selected_page)); DCHECK(IsValidReorderTargetIndex(drop_target_)) - << drop_target_.ToString() << " selected page " - << pagination_model_.selected_page() << " row " << row << " col " << col - << " " << GetLastTargetIndexOfPage(drop_target_.page).ToString(); + << drop_target_.ToString() << " selected page " << selected_page + << " row " << row << " col " << col << " " + << view_structure_.GetLastTargetIndexOfPage(drop_target_.page).ToString(); } bool AppsGridView::DragIsCloseToItem(const gfx::Point& point) { @@ -1766,8 +1766,7 @@ else AnimateToIdealBounds(); - if (!folder_delegate_) - view_structure_.SaveToMetadata(); + view_structure_.SaveToMetadata(); // Hide the |current_ghost_view_| after completed drag from within // folder to |apps_grid_view_|. @@ -1808,7 +1807,8 @@ auto* reparented_view_in_root_grid = items_container_->AddChildView( CreateViewForItem(reparented_view->item())); view_model_.Add(reparented_view_in_root_grid, view_model_.view_size()); - view_structure_.Add(reparented_view_in_root_grid, GetLastTargetIndex()); + view_structure_.Add(reparented_view_in_root_grid, + view_structure_.GetLastTargetIndex()); // Set |activated_folder_item_view_| selected so |target_index| will be // computed relative to the open folder. @@ -1841,8 +1841,7 @@ } void AppsGridView::UpdatePagedViewStructure() { - if (!folder_delegate_) - view_structure_.SaveToMetadata(); + view_structure_.SaveToMetadata(); } bool AppsGridView::IsTabletMode() const { @@ -1992,13 +1991,13 @@ ¤t_item_list_index); CHECK(found); - int target_model_index = GetTargetModelIndexForMove(item_view, target); + int target_model_index = + view_structure_.GetTargetModelIndexForMove(item_view, target); size_t target_item_list_index = - GetTargetItemListIndexForMove(item_view, target); + view_structure_.GetTargetItemListIndexForMove(item_view, target); // The same item index does not guarantee the same visual index, so move the // item visual index here. - if (!folder_delegate_) - view_structure_.Move(item_view, target, clear_overflow); + view_structure_.Move(item_view, target, clear_overflow); DVLOG(1) << "MoveItemInModel: view model: " << current_model_index << " -> " << target_model_index << ", item list: " << current_item_list_index @@ -2053,8 +2052,7 @@ CreateViewForItemAtIndex(folder_item_index); new_target_view->SetBoundsRect(target_view_bounds); view_model_.Add(new_target_view.get(), target_model_index); - if (!folder_delegate_) - view_structure_.Add(new_target_view.get(), target_index); + view_structure_.Add(new_target_view.get(), target_index); // If drag view is in front of the position where it will be moved to, we // should skip it. @@ -2080,8 +2078,7 @@ const int model_index = view_model_.GetIndexOfView(item_view); view_model_.Remove(model_index); - if (!folder_delegate_) - view_structure_.Remove(item_view); + view_structure_.Remove(item_view); item_view->title()->SetVisible(false); bounds_animator_->AnimateViewTo(item_view, item_view->bounds()); bounds_animator_->SetAnimationDelegate( @@ -2100,8 +2097,10 @@ AppListFolderItem* source_folder = static_cast<AppListFolderItem*>(item_list_->FindItem(source_folder_id)); - int target_model_index = GetTargetModelIndexForMove(item_view, target); - int target_item_index = GetTargetItemListIndexForMove(item_view, target); + int target_model_index = + view_structure_.GetTargetModelIndexForMove(item_view, target); + int target_item_index = + view_structure_.GetTargetItemListIndexForMove(item_view, target); // Remove the source folder view if there is only 1 item in it, since the // source folder will be deleted after its only child item removed from it. @@ -2138,8 +2137,7 @@ target_position = item_list_->item_at(target_item_index)->position(); model_->MoveItemToFolderAt(reparent_item, "", target_position); view_model_.Move(current_model_index, target_model_index); - if (!folder_delegate_) - view_structure_.Move(item_view, target_override); + view_structure_.Move(item_view, target_override); items_container_->ReorderChildView(item_view, target_model_index); items_container_->NotifyAccessibilityEvent(ax::mojom::Event::kChildrenChanged, true /* send_native_event */); @@ -2209,8 +2207,7 @@ CreateViewForItemAtIndex(new_folder_index); new_folder_view->SetBoundsRect(target_rect); view_model_.Add(new_folder_view.get(), target_model_index); - if (!folder_delegate_) - view_structure_.Add(new_folder_view.get(), target_index); + view_structure_.Add(new_folder_view.get(), target_index); items_container_->AddChildViewAt(std::move(new_folder_view), target_model_index); } else { @@ -2225,8 +2222,7 @@ // Fade out the drag_view_ and delete it when animation ends. int drag_model_index = view_model_.GetIndexOfView(drag_view_); view_model_.Remove(drag_model_index); - if (!folder_delegate_) - view_structure_.Remove(drag_view_); + view_structure_.Remove(drag_view_); bounds_animator_->AnimateViewTo(drag_view_, drag_view_->bounds()); bounds_animator_->SetAnimationDelegate( drag_view_, std::unique_ptr<gfx::AnimationDelegate>( @@ -2280,8 +2276,7 @@ CreateViewForItemAtIndex(last_item_index); last_item_view->SetBoundsRect(folder_rect); view_model_.Add(last_item_view.get(), target_model_index); - if (!folder_delegate_) - view_structure_.Add(last_item_view.get(), target_index); + view_structure_.Add(last_item_view.get(), target_index); items_container_->AddChildViewAt(std::move(last_item_view), target_model_index); } @@ -2290,7 +2285,7 @@ GridIndex start_index(pagination_model_.selected_page(), 0); if (!IsValidIndex(start_index)) return; - int start = GetModelIndexFromIndex(start_index); + int start = view_structure_.GetModelIndexFromIndex(start_index); int end = std::min(view_model_.view_size(), start + TilesPerPage()); for (int i = start; i < end; ++i) GetItemViewAt(i)->CancelContextMenu(); @@ -2299,10 +2294,8 @@ void AppsGridView::DeleteItemViewAtIndex(int index, bool sanitize) { AppListItemView* item_view = GetItemViewAt(index); view_model_.Remove(index); - if (!folder_delegate_) { - view_structure_.Remove(item_view, sanitize /* clear_overflow */, - sanitize /* clear_empty_pages */); - } + view_structure_.Remove(item_view, sanitize /* clear_overflow */, + sanitize /* clear_empty_pages */); if (item_view == drag_view_) drag_view_ = nullptr; delete item_view; @@ -2324,8 +2317,7 @@ items_container_->AddChildViewAt(std::move(view), model_index); } - if (!folder_delegate_) - view_structure_.LoadFromMetadata(); + view_structure_.LoadFromMetadata(); UpdateColsAndRowsForFolder(); UpdatePaging(); UpdatePulsingBlockViews(); @@ -2339,8 +2331,7 @@ if (!item->is_page_break()) DeleteItemViewAtIndex(GetModelIndexOfItem(item), true /* sanitize */); - if (!folder_delegate_) - view_structure_.LoadFromMetadata(); + view_structure_.LoadFromMetadata(); UpdateColsAndRowsForFolder(); UpdatePaging(); UpdatePulsingBlockViews(); @@ -2368,8 +2359,7 @@ ax::mojom::Event::kChildrenChanged, true /* send_native_event */); } - if (!folder_delegate_) - view_structure_.LoadFromMetadata(); + view_structure_.LoadFromMetadata(); UpdateColsAndRowsForFolder(); UpdatePaging(); if (GetWidget() && GetWidget()->IsVisible()) @@ -2445,7 +2435,8 @@ if (model_index >= view_model_.view_size()) return gfx::Rect(GetContentsBounds().CenterPoint(), gfx::Size(1, 1)); - const GridIndex grid_index = GetIndexFromModelIndex(model_index); + const GridIndex grid_index = + view_structure_.GetIndexFromModelIndex(model_index); if (grid_index.page != 0) return gfx::Rect(GetContentsBounds().CenterPoint(), gfx::Size(1, 1)); @@ -2632,14 +2623,12 @@ // the initial move. Clearing the overflow when |target_index| is on a full // page results in the last item being pushed to the next page. MoveItemInModel(selected_view_, target_index, !swap_items /*clear_overflow*/); - if (!folder_delegate_) - view_structure_.SaveToMetadata(); + view_structure_.SaveToMetadata(); if (swap_items) { DCHECK(target_view); MoveItemInModel(target_view, original_selected_view_index); - if (!folder_delegate_) - view_structure_.SaveToMetadata(); + view_structure_.SaveToMetadata(); } int target_page = target_index.page; @@ -2667,14 +2656,12 @@ bool AppsGridView::IsValidIndex(const GridIndex& index) const { return index.page >= 0 && index.page < pagination_model_.total_pages() && index.slot >= 0 && index.slot < TilesPerPage() && - GetModelIndexFromIndex(index) < view_model_.view_size(); + view_structure_.GetModelIndexFromIndex(index) < + view_model_.view_size(); } bool AppsGridView::IsValidReorderTargetIndex(const GridIndex& index) const { - if (!folder_delegate_) - return view_structure_.IsValidReorderTargetIndex(index); - - return IsValidIndex(index); + return view_structure_.IsValidReorderTargetIndex(index); } // TODO(crbug.com/1211608): Move to PagedAppsGridView.
diff --git a/ash/app_list/views/apps_grid_view.h b/ash/app_list/views/apps_grid_view.h index 4d5d6ea..b0f85fb 100644 --- a/ash/app_list/views/apps_grid_view.h +++ b/ash/app_list/views/apps_grid_view.h
@@ -706,29 +706,6 @@ // Update number of columns and rows for apps within a folder. void UpdateColsAndRowsForFolder(); - // Convert between the model index and the visual index. The model index - // is the index of the item in AppListModel. The visual index is the Index - // struct above with page/slot info of where to display the item. - virtual GridIndex GetIndexFromModelIndex(int model_index) const = 0; - virtual int GetModelIndexFromIndex(const GridIndex& index) const = 0; - - // Returns the last possible visual index to add an item view. - virtual GridIndex GetLastTargetIndex() const = 0; - - // Returns the last possible visual index to add an item view in |page|. - virtual GridIndex GetLastTargetIndexOfPage(int page) const = 0; - - // Returns the target model index if moving the item view to specified target - // visual index. - virtual int GetTargetModelIndexForMove(AppListItemView* moved_view, - const GridIndex& index) const = 0; - - // Returns the target `item_list_` index if moving the item view to specified - // target visual index. - virtual size_t GetTargetItemListIndexForMove( - AppListItemView* moved_view, - const GridIndex& index) const = 0; - // Returns true if an item view exists in the visual index. bool IsValidIndex(const GridIndex& index) const;
diff --git a/ash/app_list/views/apps_grid_view_test_api.h b/ash/app_list/views/apps_grid_view_test_api.h index c2f9c4c..836c5bc 100644 --- a/ash/app_list/views/apps_grid_view_test_api.h +++ b/ash/app_list/views/apps_grid_view_test_api.h
@@ -19,7 +19,7 @@ namespace ash { class AppListItemView; -class AppsGridView; +class PagedViewStructure; namespace test { @@ -52,6 +52,10 @@ AppListItemList* GetItemList() { return view_->item_list_; } + PagedViewStructure* GetPagedViewStructure() { + return &view_->view_structure_; + } + private: AppsGridView* view_;
diff --git a/ash/app_list/views/apps_grid_view_unittest.cc b/ash/app_list/views/apps_grid_view_unittest.cc index 1e6ce180..cb0d825 100644 --- a/ash/app_list/views/apps_grid_view_unittest.cc +++ b/ash/app_list/views/apps_grid_view_unittest.cc
@@ -2490,6 +2490,9 @@ const int kTotalItems = 4; TestAppsGridViewFolderDelegate folder_delegate; apps_grid_view_->set_folder_delegate(&folder_delegate); + test::AppsGridViewTestApi(apps_grid_view_) + .GetPagedViewStructure() + ->Init(PagedViewStructure::Mode::kFullPages); model_->PopulateApps(kTotalItems); gfx::Point mouse_from = GetItemRectOnCurrentPageAt(0, 0).CenterPoint(); gfx::Point mouse_to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint();
diff --git a/ash/app_list/views/paged_apps_grid_view.cc b/ash/app_list/views/paged_apps_grid_view.cc index bf1bff8..ec2c628 100644 --- a/ash/app_list/views/paged_apps_grid_view.cc +++ b/ash/app_list/views/paged_apps_grid_view.cc
@@ -182,6 +182,9 @@ contents_view_(contents_view), page_flip_delay_(kPageFlipDelay) { DCHECK(contents_view_); + view_structure_.Init(IsInFolder() ? PagedViewStructure::Mode::kFullPages + : PagedViewStructure::Mode::kPartialPages); + pagination_model_.AddObserver(this); pagination_controller_ = std::make_unique<PaginationController>( @@ -554,59 +557,6 @@ StopPageFlipTimer(); } -GridIndex PagedAppsGridView::GetIndexFromModelIndex(int model_index) const { - if (!IsInFolder()) - return view_structure_.GetIndexFromModelIndex(model_index); - - const int tiles_per_page = TilesPerPage(); - return GridIndex(model_index / tiles_per_page, model_index % tiles_per_page); -} - -int PagedAppsGridView::GetModelIndexFromIndex(const GridIndex& index) const { - if (!IsInFolder()) - return view_structure_.GetModelIndexFromIndex(index); - - return index.page * TilesPerPage() + index.slot; -} - -GridIndex PagedAppsGridView::GetLastTargetIndex() const { - if (!IsInFolder()) - return view_structure_.GetLastTargetIndex(); - - DCHECK_LT(0, view_model()->view_size()); - int view_index = view_model()->view_size() - 1; - return GetIndexFromModelIndex(view_index); -} - -GridIndex PagedAppsGridView::GetLastTargetIndexOfPage(int page) const { - if (!IsInFolder()) - return view_structure_.GetLastTargetIndexOfPage(page); - - if (page == pagination_model_.total_pages() - 1) - return GetLastTargetIndex(); - - return GridIndex(page, TilesPerPage() - 1); -} - -int PagedAppsGridView::GetTargetModelIndexForMove( - AppListItemView* moved_view, - const GridIndex& index) const { - if (!IsInFolder()) - return view_structure_.GetTargetModelIndexForMove(moved_view, index); - - return GetModelIndexFromIndex(index); -} - -size_t PagedAppsGridView::GetTargetItemListIndexForMove( - AppListItemView* moved_view, - const GridIndex& index) const { - if (!IsInFolder()) - return view_structure_.GetTargetItemIndexForMove(moved_view, index); - - // Model index is the same as item index for folder. - return GetModelIndexFromIndex(index); -} - void PagedAppsGridView::RecordAppMovingTypeMetrics(AppListAppMovingType type) { UMA_HISTOGRAM_ENUMERATION("Apps.AppListAppMovingType", type, kMaxAppListAppMovingType);
diff --git a/ash/app_list/views/paged_apps_grid_view.h b/ash/app_list/views/paged_apps_grid_view.h index 6b1d772..7ab16c65 100644 --- a/ash/app_list/views/paged_apps_grid_view.h +++ b/ash/app_list/views/paged_apps_grid_view.h
@@ -79,14 +79,6 @@ void MaybeEndCardifiedView() override; void MaybeStartPageFlip() override; void MaybeStopPageFlip() override; - GridIndex GetIndexFromModelIndex(int model_index) const override; - int GetModelIndexFromIndex(const GridIndex& index) const override; - GridIndex GetLastTargetIndex() const override; - GridIndex GetLastTargetIndexOfPage(int page) const override; - int GetTargetModelIndexForMove(AppListItemView* moved_view, - const GridIndex& index) const override; - size_t GetTargetItemListIndexForMove(AppListItemView* moved_view, - const GridIndex& index) const override; void RecordAppMovingTypeMetrics(AppListAppMovingType type) override; // AppListItemView::GridDelegate:
diff --git a/ash/app_list/views/scrollable_apps_grid_view.cc b/ash/app_list/views/scrollable_apps_grid_view.cc index 2c793f13..c96aa82 100644 --- a/ash/app_list/views/scrollable_apps_grid_view.cc +++ b/ash/app_list/views/scrollable_apps_grid_view.cc
@@ -34,7 +34,7 @@ a11y_announcer, view_delegate, folder_delegate) { - view_structure_.set_ignore_page_breaks(); + view_structure_.Init(PagedViewStructure::Mode::kSinglePage); } ScrollableAppsGridView::~ScrollableAppsGridView() { @@ -133,58 +133,6 @@ } } -GridIndex ScrollableAppsGridView::GetIndexFromModelIndex( - int model_index) const { - return GridIndex(0, model_index); -} - -int ScrollableAppsGridView::GetModelIndexFromIndex( - const GridIndex& index) const { - DCHECK_EQ(index.page, 0); - return index.slot; -} - -GridIndex ScrollableAppsGridView::GetLastTargetIndex() const { - DCHECK_GT(view_model()->view_size(), 0); - int view_index = view_model()->view_size() - 1; - return GetIndexFromModelIndex(view_index); -} - -GridIndex ScrollableAppsGridView::GetLastTargetIndexOfPage(int page) const { - DCHECK_EQ(page, 0); - return GetLastTargetIndex(); -} - -int ScrollableAppsGridView::GetTargetModelIndexForMove( - AppListItemView* moved_view, - const GridIndex& index) const { - DCHECK_EQ(index.page, 0); - return GetModelIndexFromIndex(index); -} - -size_t ScrollableAppsGridView::GetTargetItemListIndexForMove( - AppListItemView* moved_view, - const GridIndex& index) const { - DCHECK_EQ(index.page, 0); - GridIndex current_index(0, 0); - size_t current_item_index = 0; - - // Skip the leading "page break" items. - while (current_item_index < item_list()->item_count() && - item_list()->item_at(current_item_index)->is_page_break()) { - ++current_item_index; - } - - while (current_item_index < item_list()->item_count() && - current_index != index) { - if (!item_list()->item_at(current_item_index)->is_page_break()) - ++current_index.slot; - ++current_item_index; - } - DCHECK_EQ(current_index, index); - return current_item_index; -} - void ScrollableAppsGridView::RecordAppMovingTypeMetrics( AppListAppMovingType type) { UMA_HISTOGRAM_ENUMERATION("Apps.AppListBubbleAppMovingType", type,
diff --git a/ash/app_list/views/scrollable_apps_grid_view.h b/ash/app_list/views/scrollable_apps_grid_view.h index 9d2db4b..64a2e08b 100644 --- a/ash/app_list/views/scrollable_apps_grid_view.h +++ b/ash/app_list/views/scrollable_apps_grid_view.h
@@ -39,14 +39,6 @@ int GetPaddingBetweenPages() const override; bool IsScrollAxisVertical() const override; void CalculateIdealBounds() override; - GridIndex GetIndexFromModelIndex(int model_index) const override; - int GetModelIndexFromIndex(const GridIndex& index) const override; - GridIndex GetLastTargetIndex() const override; - GridIndex GetLastTargetIndexOfPage(int page) const override; - int GetTargetModelIndexForMove(AppListItemView* moved_view, - const GridIndex& index) const override; - size_t GetTargetItemListIndexForMove(AppListItemView* moved_view, - const GridIndex& index) const override; void RecordAppMovingTypeMetrics(AppListAppMovingType type) override; // AppListItemView::GridDelegate:
diff --git a/ash/app_list/views/scrollable_apps_grid_view_unittest.cc b/ash/app_list/views/scrollable_apps_grid_view_unittest.cc index 390bea6a..110251f47 100644 --- a/ash/app_list/views/scrollable_apps_grid_view_unittest.cc +++ b/ash/app_list/views/scrollable_apps_grid_view_unittest.cc
@@ -13,9 +13,11 @@ #include "ash/app_list/model/app_list_item.h" #include "ash/app_list/model/app_list_item_list.h" #include "ash/app_list/model/app_list_model.h" +#include "ash/app_list/paged_view_structure.h" #include "ash/app_list/test/app_list_test_helper.h" #include "ash/app_list/test_app_list_client.h" #include "ash/app_list/views/app_list_item_view.h" +#include "ash/app_list/views/apps_grid_view_test_api.h" #include "ash/constants/ash_features.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" @@ -138,27 +140,32 @@ AddAppListItem("ccc"); // App list item index 4, visual index 0,2. ShowAppList(); - // Simulate dragging the last item. auto* view = GetScrollableAppsGridView(); + PagedViewStructure* structure = + test::AppsGridViewTestApi(view).GetPagedViewStructure(); // The last visual index is 0,2. - EXPECT_EQ(GridIndex(0, 2), view->GetLastTargetIndex()); - EXPECT_EQ(GridIndex(0, 2), view->GetLastTargetIndexOfPage(0)); + EXPECT_EQ(GridIndex(0, 2), structure->GetLastTargetIndex()); + EXPECT_EQ(GridIndex(0, 2), structure->GetLastTargetIndexOfPage(0)); // Visual index directly maps to target index in "view model". - EXPECT_EQ(0, view->GetTargetModelIndexForMove(nullptr, GridIndex(0, 0))); - EXPECT_EQ(1, view->GetTargetModelIndexForMove(nullptr, GridIndex(0, 1))); - EXPECT_EQ(2, view->GetTargetModelIndexForMove(nullptr, GridIndex(0, 2))); - EXPECT_EQ(3, view->GetTargetModelIndexForMove(nullptr, GridIndex(0, 3))); + EXPECT_EQ(0, structure->GetTargetModelIndexForMove(nullptr, GridIndex(0, 0))); + EXPECT_EQ(1, structure->GetTargetModelIndexForMove(nullptr, GridIndex(0, 1))); + EXPECT_EQ(2, structure->GetTargetModelIndexForMove(nullptr, GridIndex(0, 2))); + EXPECT_EQ(3, structure->GetTargetModelIndexForMove(nullptr, GridIndex(0, 3))); // Target is the front. - EXPECT_EQ(0u, view->GetTargetItemListIndexForMove(nullptr, GridIndex(0, 0))); + EXPECT_EQ(0, + structure->GetTargetItemListIndexForMove(nullptr, GridIndex(0, 0))); // Target is after "aaa". - EXPECT_EQ(1u, view->GetTargetItemListIndexForMove(nullptr, GridIndex(0, 1))); + EXPECT_EQ(1, + structure->GetTargetItemListIndexForMove(nullptr, GridIndex(0, 1))); // Target is after "aaa" + break + "bbb". - EXPECT_EQ(3u, view->GetTargetItemListIndexForMove(nullptr, GridIndex(0, 2))); + EXPECT_EQ(3, + structure->GetTargetItemListIndexForMove(nullptr, GridIndex(0, 2))); // Target is after "aaa" + break + "bbb" + break + "ccc". - EXPECT_EQ(5u, view->GetTargetItemListIndexForMove(nullptr, GridIndex(0, 3))); + EXPECT_EQ(5, + structure->GetTargetItemListIndexForMove(nullptr, GridIndex(0, 3))); } TEST_F(ScrollableAppsGridViewTest, DragAppAfterScrollingDown) {
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 3120c995..f88153d 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -756,12 +756,6 @@ <message name="IDS_ASH_STATUS_TRAY_ACCESSIBILITY_DICTATION" desc="The label used in the accessibility menu of the system tray to toggle on/off the speak to type feature."> Dictation </message> - <message name="IDS_ASH_DICTATION_CONFIRMATION_TITLE" desc="The title for the modal dialog shown the first time the user enables dictation"> - Dictation - </message> - <message name="IDS_ASH_DICTATION_CONFIRMATION_BODY" desc="The message shown the first time the user enables Dictation, explaining that the audio data will be sent to Google for transcription"> - Dictation sends your voice to Google to allow voice typing in any text field. - </message> <message name="IDS_ASH_DICTATION_LANGUAGE_SUPPORTED_OFFLINE_NUDGE" desc="The message shown for existing Dictation users when their Dictation language has been upgraded in the background to work offline."> <ph name="language">$1<ex>English</ex></ph> speech is now processed locally and works offline. You can change your Dictation language in Settings > Accessibility. </message> @@ -3679,6 +3673,9 @@ <message name="IDS_ASH_PCIE_PERIPHERAL_NOTIFICATION_DEVICE_BLOCKED_BODY" desc="Notification body text that explains to the user that their peripheral is not supported because it is not part of the approved peripherals list."> Only approved Thunderbolt devices are compatible with your Chromebook </message> + <message name="IDS_ASH_PCIE_PERIPHERAL_NOTIFICATION_BILLBOARD_DEVICE" desc="Notification body text that explains to the user that the connected peripheral type (e.g. Thunderbolt peripheral) is not supported."> + The connected peripheral type is not supported + </message> <!-- Shortcut Customization App --> <message name="IDS_ASH_SHORTCUT_CUSTOMIZATION_APP_TITLE" translateable="false" desc="The title of the shortcut customization system web app. Shortcut customization lets users to customize their system shortcuts.">
diff --git a/ash/ash_strings_grd/IDS_ASH_PCIE_PERIPHERAL_NOTIFICATION_BILLBOARD_DEVICE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_PCIE_PERIPHERAL_NOTIFICATION_BILLBOARD_DEVICE.png.sha1 new file mode 100644 index 0000000..28022541 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_PCIE_PERIPHERAL_NOTIFICATION_BILLBOARD_DEVICE.png.sha1
@@ -0,0 +1 @@ +a5f708d004b83fada3eef7b48489195f910d7612 \ No newline at end of file
diff --git a/ash/capture_mode/capture_mode_notification_view.cc b/ash/capture_mode/capture_mode_notification_view.cc index 084476b6..7645731 100644 --- a/ash/capture_mode/capture_mode_notification_view.cc +++ b/ash/capture_mode/capture_mode_notification_view.cc
@@ -7,11 +7,11 @@ #include "ash/constants/ash_features.h" #include "ash/public/cpp/assistant/assistant_state.h" #include "ash/public/cpp/clipboard_history_controller.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_provider.h" -#include "ash/style/scoped_light_mode_as_default.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "ui/base/l10n/l10n_util.h" #include "ui/chromeos/events/keyboard_layout_util.h"
diff --git a/ash/clipboard/clipboard_history_controller_impl.cc b/ash/clipboard/clipboard_history_controller_impl.cc index b1122e9..8f2ac3b 100644 --- a/ash/clipboard/clipboard_history_controller_impl.cc +++ b/ash/clipboard/clipboard_history_controller_impl.cc
@@ -16,10 +16,10 @@ #include "ash/constants/ash_features.h" #include "ash/display/display_util.h" #include "ash/public/cpp/clipboard_image_model_factory.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/public/cpp/window_tree_host_lookup.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/shell.h" -#include "ash/style/scoped_light_mode_as_default.h" #include "ash/wm/window_util.h" #include "base/bind.h" #include "base/location.h"
diff --git a/ash/clipboard/views/clipboard_history_bitmap_item_view.cc b/ash/clipboard/views/clipboard_history_bitmap_item_view.cc index daf3d94..fb05ed7 100644 --- a/ash/clipboard/views/clipboard_history_bitmap_item_view.cc +++ b/ash/clipboard/views/clipboard_history_bitmap_item_view.cc
@@ -9,8 +9,8 @@ #include "ash/clipboard/clipboard_history_util.h" #include "ash/clipboard/views/clipboard_history_delete_button.h" #include "ash/clipboard/views/clipboard_history_view_constants.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/style/ash_color_provider.h" -#include "ash/style/scoped_light_mode_as_default.h" #include "base/bind.h" #include "base/containers/contains.h" #include "base/time/time.h"
diff --git a/ash/clipboard/views/clipboard_history_delete_button.cc b/ash/clipboard/views/clipboard_history_delete_button.cc index cf7c4cc..f2f2243c 100644 --- a/ash/clipboard/views/clipboard_history_delete_button.cc +++ b/ash/clipboard/views/clipboard_history_delete_button.cc
@@ -6,9 +6,9 @@ #include "ash/clipboard/views/clipboard_history_item_view.h" #include "ash/clipboard/views/clipboard_history_view_constants.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/style/ash_color_provider.h" -#include "ash/style/scoped_light_mode_as_default.h" #include "base/bind.h" #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/layer.h"
diff --git a/ash/clipboard/views/clipboard_history_file_item_view.cc b/ash/clipboard/views/clipboard_history_file_item_view.cc index 145251e..a58c3e9 100644 --- a/ash/clipboard/views/clipboard_history_file_item_view.cc +++ b/ash/clipboard/views/clipboard_history_file_item_view.cc
@@ -6,7 +6,7 @@ #include <array> -#include "ash/style/scoped_light_mode_as_default.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ui/views/controls/image_view.h" #include "ui/views/view_class_properties.h"
diff --git a/ash/clipboard/views/clipboard_history_label.cc b/ash/clipboard/views/clipboard_history_label.cc index 17c78bd5..13d8ba93 100644 --- a/ash/clipboard/views/clipboard_history_label.cc +++ b/ash/clipboard/views/clipboard_history_label.cc
@@ -5,8 +5,8 @@ #include "ash/clipboard/views/clipboard_history_label.h" #include "ash/clipboard/views/clipboard_history_view_constants.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/style/ash_color_provider.h" -#include "ash/style/scoped_light_mode_as_default.h" namespace ash { ClipboardHistoryLabel::ClipboardHistoryLabel(const std::u16string& text)
diff --git a/ash/clipboard/views/clipboard_history_main_button.cc b/ash/clipboard/views/clipboard_history_main_button.cc index 29d7b4ce..27107dce 100644 --- a/ash/clipboard/views/clipboard_history_main_button.cc +++ b/ash/clipboard/views/clipboard_history_main_button.cc
@@ -5,8 +5,8 @@ #include "ash/clipboard/views/clipboard_history_main_button.h" #include "ash/clipboard/views/clipboard_history_item_view.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/style/ash_color_provider.h" -#include "ash/style/scoped_light_mode_as_default.h" #include "base/bind.h" #include "ui/gfx/canvas.h" #include "ui/views/accessibility/view_accessibility.h"
diff --git a/ash/components/pcie_peripheral/BUILD.gn b/ash/components/pcie_peripheral/BUILD.gn index 65d0ce8..b85fcaf 100644 --- a/ash/components/pcie_peripheral/BUILD.gn +++ b/ash/components/pcie_peripheral/BUILD.gn
@@ -13,6 +13,7 @@ "//base", "//chromeos/dbus/pciguard", "//chromeos/dbus/typecd", + "//services/device/public/mojom:usb", ] sources = [
diff --git a/ash/components/pcie_peripheral/DEPS b/ash/components/pcie_peripheral/DEPS index e5e976a..339b943 100644 --- a/ash/components/pcie_peripheral/DEPS +++ b/ash/components/pcie_peripheral/DEPS
@@ -4,4 +4,5 @@ "+base", "+chromeos/dbus", "+testing", + "+services/device/public", ] \ No newline at end of file
diff --git a/ash/components/pcie_peripheral/pcie_peripheral_manager.cc b/ash/components/pcie_peripheral/pcie_peripheral_manager.cc index dbd50c2a..aca73c2b 100644 --- a/ash/components/pcie_peripheral/pcie_peripheral_manager.cc +++ b/ash/components/pcie_peripheral/pcie_peripheral_manager.cc
@@ -5,13 +5,19 @@ #include "ash/components/pcie_peripheral/pcie_peripheral_manager.h" #include "base/callback_helpers.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/metrics/histogram_functions.h" +#include "services/device/public/mojom/usb_device.mojom.h" namespace ash { namespace { PciePeripheralManager* g_instance = nullptr; +const int kBillboardDeviceClassCode = 17; +constexpr char thunderbolt_file_path[] = "/sys/bus/thunderbolt/devices/0-0"; + void RecordConnectivityMetric( PciePeripheralManager::PciePeripheralConnectivityResults results) { base::UmaHistogramEnumeration("Ash.PciePeripheral.ConnectivityResults", @@ -65,6 +71,11 @@ observer.OnPeripheralBlockedReceived(); } +void PciePeripheralManager::NotifyBillboardDeviceReceived() { + for (auto& observer : observer_list_) + observer.OnBillboardDeviceConnected(); +} + void PciePeripheralManager::OnThunderboltDeviceConnected( bool is_thunderbolt_only) { if (is_guest_profile_) { @@ -100,11 +111,29 @@ PciePeripheralConnectivityResults::kPeripheralBlocked); } +void PciePeripheralManager::OnDeviceConnected( + device::mojom::UsbDeviceInfo* device) { + if (device->class_code == kBillboardDeviceClassCode && + !CheckIfThunderboltFilepathExists()) { + NotifyBillboardDeviceReceived(); + RecordConnectivityMetric( + PciePeripheralConnectivityResults::kBillboardDevice); + } +} + void PciePeripheralManager::SetPcieTunnelingAllowedState( bool is_pcie_tunneling_allowed) { is_pcie_tunneling_allowed_ = is_pcie_tunneling_allowed; } +void PciePeripheralManager::SetRootPrefixForTesting(const std::string& prefix) { + root_prefix_ = prefix; +} + +bool PciePeripheralManager::CheckIfThunderboltFilepathExists() { + return base::PathExists(base::FilePath(root_prefix_ + thunderbolt_file_path)); +} + // static void PciePeripheralManager::Initialize(bool is_guest_profile, bool is_pcie_tunneling_allowed) {
diff --git a/ash/components/pcie_peripheral/pcie_peripheral_manager.h b/ash/components/pcie_peripheral/pcie_peripheral_manager.h index 805586e..974fcb45 100644 --- a/ash/components/pcie_peripheral/pcie_peripheral_manager.h +++ b/ash/components/pcie_peripheral/pcie_peripheral_manager.h
@@ -13,6 +13,12 @@ #include "chromeos/dbus/pciguard/pciguard_client.h" #include "chromeos/dbus/typecd/typecd_client.h" +namespace device { +namespace mojom { +class UsbDeviceInfo; +} // namespace mojom +} // namespace device + namespace ash { // This class is responsible for listening to TypeCd and Pciguard D-Bus calls @@ -41,6 +47,11 @@ // recently plugged in Thunderbolt/USB4 device is in the block list. The // block list is specified by the Pciguard Daemon. virtual void OnPeripheralBlockedReceived() = 0; + + // Called to notify observers, primarily notification controllers, that the + // recently plugged in Thunderbolt/USB4 device is a billboard device that is + // not supported by the board. + virtual void OnBillboardDeviceConnected() = 0; }; // These values are persisted to logs. Entries should not be renumbered and @@ -52,7 +63,8 @@ kAltModeFallbackDueToPciguard = 3, kAltModeFallbackInGuestSession = 4, kPeripheralBlocked = 5, - kMaxValue = kPeripheralBlocked, + kBillboardDevice = 6, + kMaxValue = kBillboardDevice, }; // Sets the global instance. Must be called before any calls to Get(). @@ -72,6 +84,8 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); + void OnDeviceConnected(device::mojom::UsbDeviceInfo* device); + private: friend class PciePeripheralManagerTest; @@ -91,6 +105,14 @@ void NotifyLimitedPerformancePeripheralReceived(); void NotifyGuestModeNotificationReceived(bool is_thunderbolt_only); void NotifyPeripheralBlockedReceived(); + void NotifyBillboardDeviceReceived(); + + // Called by unit tests to set up root_prefix_ for simulating the existence + // of a system folder. + void SetRootPrefixForTesting(const std::string& prefix); + + // Checks if the board supports Thunderbolt. + bool CheckIfThunderboltFilepathExists(); const bool is_guest_profile_; // Pcie tunneling refers to allowing Thunderbolt/USB4 peripherals to run at @@ -100,6 +122,8 @@ // in a restricted state (e.g. certain devices are Thunderbolt only). bool is_pcie_tunneling_allowed_; base::ObserverList<Observer> observer_list_; + + std::string root_prefix_ = ""; }; } // namespace ash
diff --git a/ash/components/pcie_peripheral/pcie_peripheral_manager_unittest.cc b/ash/components/pcie_peripheral/pcie_peripheral_manager_unittest.cc index fa3d0650..f3f6d82f 100644 --- a/ash/components/pcie_peripheral/pcie_peripheral_manager_unittest.cc +++ b/ash/components/pcie_peripheral/pcie_peripheral_manager_unittest.cc
@@ -6,13 +6,25 @@ #include <memory> +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" #include "base/test/metrics/histogram_tester.h" #include "chromeos/dbus/pciguard/fake_pciguard_client.h" #include "chromeos/dbus/pciguard/pciguard_client.h" #include "chromeos/dbus/typecd/fake_typecd_client.h" #include "chromeos/dbus/typecd/typecd_client.h" +#include "services/device/public/cpp/test/fake_usb_device_info.h" #include "testing/gtest/include/gtest/gtest.h" +namespace { +const int kUsbConfigWithInterfaces = 1; +const int kBillboardDeviceClassCode = 17; +const int kNonBillboardDeviceClassCode = 16; +constexpr char thunderbolt_path_for_testing[] = + "/tmp/tbt/sys/bus/thunderbolt/devices/0-0"; +constexpr char root_prefix_for_testing[] = "/tmp/tbt"; +} // namespace + namespace ash { class FakeObserver : public PciePeripheralManager::Observer { @@ -32,6 +44,10 @@ return num_peripheral_blocked_notification_calls_; } + size_t num_billboard_notification_calls() const { + return num_billboard_notification_calls_; + } + bool is_current_guest_device_tbt_only() const { return is_current_guest_device_tbt_only_; } @@ -50,10 +66,15 @@ ++num_peripheral_blocked_notification_calls_; } + void OnBillboardDeviceConnected() override { + ++num_billboard_notification_calls_; + } + private: size_t num_limited_performance_notification_calls_ = 0u; size_t num_guest_notification_calls_ = 0u; size_t num_peripheral_blocked_notification_calls_ = 0u; + size_t num_billboard_notification_calls_ = 0u; bool is_current_guest_device_tbt_only_ = false; }; @@ -74,6 +95,8 @@ chromeos::PciguardClient::InitializeFake(); fake_pciguard_client_ = static_cast<chromeos::FakePciguardClient*>( chromeos::PciguardClient::Get()); + + base::DeletePathRecursively(base::FilePath(thunderbolt_path_for_testing)); } void InitializeManager(bool is_guest_session, @@ -83,6 +106,7 @@ manager_ = PciePeripheralManager::Get(); manager_->AddObserver(&fake_observer_); + manager_->SetRootPrefixForTesting(root_prefix_for_testing); } void TearDown() override { @@ -90,6 +114,7 @@ PciePeripheralManager::Shutdown(); chromeos::TypecdClient::Shutdown(); chromeos::PciguardClient::Shutdown(); + base::DeletePathRecursively(base::FilePath(thunderbolt_path_for_testing)); } chromeos::FakeTypecdClient* fake_typecd_client() { @@ -112,6 +137,10 @@ return fake_observer_.num_peripheral_blocked_notification_calls(); } + size_t GetNumBillboardNotificationObserverCalls() { + return fake_observer_.num_billboard_notification_calls(); + } + bool GetIsCurrentGuestDeviceTbtOnly() { return fake_observer_.is_current_guest_device_tbt_only(); } @@ -125,11 +154,39 @@ FakeObserver fake_observer_; }; +scoped_refptr<device::FakeUsbDeviceInfo> CreateTestDeviceOfClass( + uint8_t device_class) { + auto config = device::mojom::UsbConfigurationInfo::New(); + config->configuration_value = kUsbConfigWithInterfaces; + + auto alternate = device::mojom::UsbAlternateInterfaceInfo::New(); + alternate->alternate_setting = 0; + alternate->class_code = device_class; + alternate->subclass_code = 0xff; + alternate->protocol_code = 0xff; + + auto interface = device::mojom::UsbInterfaceInfo::New(); + interface->interface_number = 0; + interface->alternates.push_back(std::move(alternate)); + + config->interfaces.push_back(std::move(interface)); + + std::vector<device::mojom::UsbConfigurationInfoPtr> configs; + configs.push_back(std::move(config)); + + scoped_refptr<device::FakeUsbDeviceInfo> device = + base::MakeRefCounted<device::FakeUsbDeviceInfo>( + /*vendor_id=*/0, /*product_id=*/1, device_class, std::move(configs)); + device->SetActiveConfig(kUsbConfigWithInterfaces); + return device; +} + TEST_F(PciePeripheralManagerTest, InitialTest) { InitializeManager(/*is_guest_profile=*/false, /*is_pcie_tunneling_allowed=*/false); EXPECT_EQ(0u, GetNumLimitedPerformanceObserverCalls()); EXPECT_EQ(0u, GetNumGuestModeNotificationObserverCalls()); + EXPECT_EQ(0u, GetNumBillboardNotificationObserverCalls()); EXPECT_FALSE(GetIsCurrentGuestDeviceTbtOnly()); } @@ -308,4 +365,62 @@ 1); } +TEST_F(PciePeripheralManagerTest, BillboardDevice) { + InitializeManager(/*is_guest_profile=*/false, + /*is_pcie_tunneling_allowed=*/true); + + EXPECT_EQ(0u, GetNumLimitedPerformanceObserverCalls()); + EXPECT_EQ(0u, GetNumGuestModeNotificationObserverCalls()); + EXPECT_EQ(0u, GetNumPeripheralBlockedNotificationObserverCalls()); + EXPECT_EQ(0u, GetNumBillboardNotificationObserverCalls()); + + // Simulate connecting a billboard device. + const auto fake_device = CreateTestDeviceOfClass(kBillboardDeviceClassCode); + const auto device = fake_device->GetDeviceInfo().Clone(); + PciePeripheralManager::Get()->OnDeviceConnected(device.get()); + + EXPECT_EQ(0u, GetNumLimitedPerformanceObserverCalls()); + EXPECT_EQ(0u, GetNumGuestModeNotificationObserverCalls()); + EXPECT_EQ(0u, GetNumPeripheralBlockedNotificationObserverCalls()); + EXPECT_EQ(1u, GetNumBillboardNotificationObserverCalls()); + + histogram_tester_.ExpectBucketCount( + "Ash.PciePeripheral.ConnectivityResults", + PciePeripheralManager::PciePeripheralConnectivityResults:: + kBillboardDevice, + 1); + + // Connect a non-billboard device. There should be no notification. + const auto fake_device_1 = + CreateTestDeviceOfClass(kNonBillboardDeviceClassCode); + const auto device_1 = fake_device_1->GetDeviceInfo().Clone(); + PciePeripheralManager::Get()->OnDeviceConnected(device_1.get()); + + EXPECT_EQ(0u, GetNumLimitedPerformanceObserverCalls()); + EXPECT_EQ(0u, GetNumGuestModeNotificationObserverCalls()); + EXPECT_EQ(0u, GetNumPeripheralBlockedNotificationObserverCalls()); + EXPECT_EQ(1u, GetNumBillboardNotificationObserverCalls()); + + // Fake a board that supports Thunderbolt. + auto thunderbolt_directory = std::make_unique<base::ScopedTempDir>(); + EXPECT_TRUE(thunderbolt_directory->CreateUniqueTempDirUnderPath( + base::FilePath(thunderbolt_path_for_testing))); + + // Connect a billboard device. There should be no notification. + const auto fake_device_2 = CreateTestDeviceOfClass(kBillboardDeviceClassCode); + const auto device_2 = fake_device_2->GetDeviceInfo().Clone(); + PciePeripheralManager::Get()->OnDeviceConnected(device_2.get()); + + EXPECT_EQ(0u, GetNumLimitedPerformanceObserverCalls()); + EXPECT_EQ(0u, GetNumGuestModeNotificationObserverCalls()); + EXPECT_EQ(0u, GetNumPeripheralBlockedNotificationObserverCalls()); + EXPECT_EQ(1u, GetNumBillboardNotificationObserverCalls()); + + histogram_tester_.ExpectBucketCount( + "Ash.PciePeripheral.ConnectivityResults", + PciePeripheralManager::PciePeripheralConnectivityResults:: + kBillboardDevice, + 1); +} + } // namespace ash
diff --git a/ash/style/scoped_light_mode_as_default.h b/ash/public/cpp/style/scoped_light_mode_as_default.h similarity index 84% rename from ash/style/scoped_light_mode_as_default.h rename to ash/public/cpp/style/scoped_light_mode_as_default.h index f572af3..28e3204 100644 --- a/ash/style/scoped_light_mode_as_default.h +++ b/ash/public/cpp/style/scoped_light_mode_as_default.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 ASH_STYLE_SCOPED_LIGHT_MODE_AS_DEFAULT_H_ -#define ASH_STYLE_SCOPED_LIGHT_MODE_AS_DEFAULT_H_ +#ifndef ASH_PUBLIC_CPP_STYLE_SCOPED_LIGHT_MODE_AS_DEFAULT_H_ +#define ASH_PUBLIC_CPP_STYLE_SCOPED_LIGHT_MODE_AS_DEFAULT_H_ #include "ash/ash_export.h" @@ -29,4 +29,4 @@ } // namespace ash -#endif // ASH_STYLE_SCOPED_LIGHT_MODE_AS_DEFAULT_H_ +#endif // ASH_PUBLIC_CPP_STYLE_SCOPED_LIGHT_MODE_AS_DEFAULT_H_
diff --git a/ash/style/scoped_light_mode_as_default.cc b/ash/style/scoped_light_mode_as_default.cc index 933520a..c503167 100644 --- a/ash/style/scoped_light_mode_as_default.cc +++ b/ash/style/scoped_light_mode_as_default.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 "ash/style/scoped_light_mode_as_default.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/style/ash_color_provider.h"
diff --git a/ash/system/accessibility/dictation_button_tray.cc b/ash/system/accessibility/dictation_button_tray.cc index 79af886..a6312a7c 100644 --- a/ash/system/accessibility/dictation_button_tray.cc +++ b/ash/system/accessibility/dictation_button_tray.cc
@@ -118,21 +118,18 @@ Shell::Get()->accessibility_controller()->dictation().enabled(); PrefService* pref_service = Shell::Get()->session_controller()->GetActivePrefService(); - speech::SodaInstaller* soda_installer = speech::SodaInstaller::GetInstance(); - if (!::features::IsExperimentalAccessibilityDictationOfflineEnabled() || - !pref_service || !soda_installer) { + if (!features::IsDictationOfflineAvailableAndEnabled() || !pref_service) { // If we can't get the pref service or soda installer, then simply use // Dictation's enabled state. SetVisiblePreferred(dictation_enabled); return; } - + speech::SodaInstaller* soda_installer = speech::SodaInstaller::GetInstance(); const std::string locale = pref_service->GetString(prefs::kAccessibilityDictationLocale); bool soda_downloading = soda_installer->IsSodaDownloading(speech::GetLanguageCode(locale)); - bool is_visible = dictation_enabled && !soda_downloading; - SetVisiblePreferred(is_visible); + SetVisiblePreferred(dictation_enabled && !soda_downloading); } void DictationButtonTray::CheckDictationStatusAndUpdateIcon() {
diff --git a/ash/system/accessibility/dictation_button_tray_unittest.cc b/ash/system/accessibility/dictation_button_tray_unittest.cc index df2ce93..e29b2757 100644 --- a/ash/system/accessibility/dictation_button_tray_unittest.cc +++ b/ash/system/accessibility/dictation_button_tray_unittest.cc
@@ -6,6 +6,7 @@ #include "ash/accessibility/accessibility_controller_impl.h" #include "ash/accessibility/test_accessibility_controller_client.h" +#include "ash/constants/ash_features.h" #include "ash/display/window_tree_host_manager.h" #include "ash/login_status.h" #include "ash/public/cpp/shelf_types.h" @@ -24,7 +25,11 @@ #include "ash/wm/window_util.h" #include "base/command_line.h" #include "base/test/metrics/user_action_tester.h" +#include "base/test/scoped_feature_list.h" #include "base/time/time.h" +#include "components/soda/soda_installer.h" +#include "components/soda/soda_installer_impl_chromeos.h" +#include "ui/accessibility/accessibility_features.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" @@ -57,10 +62,10 @@ public: DictationButtonTrayTest() = default; ~DictationButtonTrayTest() override = default; + DictationButtonTrayTest(const DictationButtonTrayTest&) = delete; + DictationButtonTrayTest& operator=(const DictationButtonTrayTest&) = delete; - void SetUp() override { - AshTestBase::SetUp(); - } + void SetUp() override { AshTestBase::SetUp(); } protected: views::ImageView* GetImageView(DictationButtonTray* tray) { @@ -69,9 +74,6 @@ void CheckDictationStatusAndUpdateIcon(DictationButtonTray* tray) { tray->CheckDictationStatusAndUpdateIcon(); } - - private: - DISALLOW_COPY_AND_ASSIGN(DictationButtonTrayTest); }; // Ensures that creation doesn't cause any crashes and adds the image icon. @@ -79,7 +81,6 @@ TEST_F(DictationButtonTrayTest, BasicConstruction) { AccessibilityControllerImpl* controller = Shell::Get()->accessibility_controller(); - controller->dictation().SetDialogAccepted(); controller->dictation().SetEnabled(true); EXPECT_TRUE(GetImageView(GetTray())); EXPECT_TRUE(GetTray()->GetVisible()); @@ -90,7 +91,6 @@ AccessibilityControllerImpl* controller = Shell::Get()->accessibility_controller(); TestAccessibilityControllerClient client; - controller->dictation().SetDialogAccepted(); controller->dictation().SetEnabled(true); EXPECT_FALSE(controller->dictation_active()); @@ -105,7 +105,6 @@ TEST_F(DictationButtonTrayTest, ActivatingDictationActivatesButton) { AccessibilityControllerImpl* controller = Shell::Get()->accessibility_controller(); - controller->dictation().SetDialogAccepted(); controller->dictation().SetEnabled(true); Shell::Get()->OnDictationStarted(); EXPECT_TRUE(GetTray()->is_active()); @@ -120,7 +119,6 @@ AccessibilityControllerImpl* controller = Shell::Get()->accessibility_controller(); TestAccessibilityControllerClient client; - controller->dictation().SetDialogAccepted(); controller->dictation().SetEnabled(true); ASSERT_FALSE(controller->dictation_active()); @@ -137,4 +135,53 @@ EXPECT_FALSE(GetTray()->is_active()); } +class DictationButtonTraySodaTest : public DictationButtonTrayTest { + public: + DictationButtonTraySodaTest() = default; + ~DictationButtonTraySodaTest() override = default; + DictationButtonTraySodaTest(const DictationButtonTraySodaTest&) = delete; + DictationButtonTraySodaTest& operator=(const DictationButtonTraySodaTest&) = + delete; + + void SetUp() override { + DictationButtonTrayTest::SetUp(); + scoped_feature_list_.InitWithFeatures( + {::features::kExperimentalAccessibilityDictationOffline, + features::kOnDeviceSpeechRecognition}, + {}); + + // Since this test suite is part of ash unit tests, the + // SodaInstallerImplChromeOS is never created (it's normally created when + // ChromeBrowserMainPartsChromeos initializes). Create it here so that + // calling speech::SodaInstaller::GetInstance) returns a valid instance. + soda_installer_impl_ = + std::make_unique<speech::SodaInstallerImplChromeOS>(); + } + + void TearDown() override { + soda_installer_impl_.reset(); + AshTestBase::TearDown(); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + std::unique_ptr<speech::SodaInstallerImplChromeOS> soda_installer_impl_; +}; + +TEST_F(DictationButtonTraySodaTest, VisiblityChangesWhenSodaInstalled) { + AccessibilityControllerImpl* controller = + Shell::Get()->accessibility_controller(); + TestAccessibilityControllerClient client; + controller->dictation().SetEnabled(true); + + speech::SodaInstaller::GetInstance()->NotifySodaDownloadProgressForTesting( + 50); + GetTray()->UpdateVisibility(); + EXPECT_FALSE(GetTray()->GetVisible()); + + speech::SodaInstaller::GetInstance()->NotifySodaInstalledForTesting(); + GetTray()->UpdateVisibility(); + EXPECT_TRUE(GetTray()->GetVisible()); +} + } // namespace ash
diff --git a/ash/system/accessibility/floating_accessibility_controller_unittest.cc b/ash/system/accessibility/floating_accessibility_controller_unittest.cc index 04d4d90..88f1829 100644 --- a/ash/system/accessibility/floating_accessibility_controller_unittest.cc +++ b/ash/system/accessibility/floating_accessibility_controller_unittest.cc
@@ -387,8 +387,6 @@ {FloatingAccessibilityView::ButtonId::kVirtualKeyboard, AccessibilityControllerImpl::kVirtualKeyboard}}; - accessibility_controller()->dictation().SetDialogAccepted(); - gfx::Rect original_bounds = GetMenuViewBounds(); for (FeatureWithButton feature : kFeatureButtons) { @@ -492,7 +490,6 @@ } TEST_F(FloatingAccessibilityControllerTest, ShowingAlreadyEnabledFeatures) { - accessibility_controller()->dictation().SetDialogAccepted(); accessibility_controller()->select_to_speak().SetEnabled(true); accessibility_controller()->dictation().SetEnabled(true); accessibility_controller()->virtual_keyboard().SetEnabled(true);
diff --git a/ash/system/accessibility/tray_accessibility.cc b/ash/system/accessibility/tray_accessibility.cc index 8abe68b5..fb2ce601 100644 --- a/ash/system/accessibility/tray_accessibility.cc +++ b/ash/system/accessibility/tray_accessibility.cc
@@ -86,7 +86,7 @@ } AccessibilityDetailedView::~AccessibilityDetailedView() { - if (features::IsExperimentalAccessibilityDictationOfflineEnabled()) + if (features::IsDictationOfflineAvailableAndEnabled()) speech::SodaInstaller::GetInstance()->RemoveObserver(this); } @@ -539,7 +539,7 @@ } void AccessibilityDetailedView::UpdateSodaInstallerObserverStatus() { - if (!features::IsExperimentalAccessibilityDictationOfflineEnabled()) + if (!features::IsDictationOfflineAvailableAndEnabled()) return; bool dictation_enabled =
diff --git a/ash/system/accessibility/tray_accessibility_unittest.cc b/ash/system/accessibility/tray_accessibility_unittest.cc index 86778c6..4d95acd 100644 --- a/ash/system/accessibility/tray_accessibility_unittest.cc +++ b/ash/system/accessibility/tray_accessibility_unittest.cc
@@ -8,6 +8,7 @@ #include "ash/accessibility/accessibility_controller_impl.h" #include "ash/accessibility/accessibility_observer.h" #include "ash/accessibility/magnifier/docked_magnifier_controller.h" +#include "ash/constants/ash_features.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/system/tray/detailed_view_delegate.h" @@ -45,9 +46,6 @@ } void EnableDictation(bool enabled) { - if (enabled) { - Shell::Get()->accessibility_controller()->dictation().SetDialogAccepted(); - } Shell::Get()->accessibility_controller()->dictation().SetEnabled(enabled); } @@ -109,11 +107,13 @@ // SodaInstallerImplChromeOS is never created (it's normally created when // ChromeBrowserMainPartsChromeos initializes). Create it here so that // calling speech::SodaInstaller::GetInstance() returns a valid instance. + scoped_feature_list_.InitWithFeatures( + {::features::kExperimentalAccessibilityDictationOffline, + ash::features::kOnDeviceSpeechRecognition}, + {}); soda_installer_impl_ = std::make_unique<speech::SodaInstallerImplChromeOS>(); speech::SodaInstaller::GetInstance()->UninstallSodaForTesting(); - scoped_feature_list_.InitAndEnableFeature( - features::kExperimentalAccessibilityDictationOffline); } void TearDown() override { @@ -637,7 +637,6 @@ // Confirms that the check item toggles dictation. EXPECT_FALSE(accessibility_controller->dictation().enabled()); - Shell::Get()->accessibility_controller()->dictation().SetDialogAccepted(); CreateDetailedMenu(); ClickDictationOnDetailMenu();
diff --git a/ash/system/holding_space/holding_space_drag_util.cc b/ash/system/holding_space/holding_space_drag_util.cc index 8db66b1..c20701e 100644 --- a/ash/system/holding_space/holding_space_drag_util.cc +++ b/ash/system/holding_space/holding_space_drag_util.cc
@@ -11,8 +11,8 @@ #include "ash/public/cpp/holding_space/holding_space_image.h" #include "ash/public/cpp/holding_space/holding_space_item.h" #include "ash/public/cpp/rounded_image_view.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/style/ash_color_provider.h" -#include "ash/style/scoped_light_mode_as_default.h" #include "ash/system/holding_space/holding_space_item_view.h" #include "base/containers/adapters.h" #include "base/i18n/rtl.h"
diff --git a/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.cc b/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.cc index 9c34e05..6302f53 100644 --- a/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.cc +++ b/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.cc
@@ -42,6 +42,8 @@ "cros_pcie_peripheral_guest_mode_not_supported_notifcation_id"; const char kPciePeripheralDeviceBlockedNotificationId[] = "cros_pcie_peripheral_device_blocked_notifcation_id"; +const char kPciePeripheralBillboardDeviceNotificationId[] = + "cros_pcie_peripheral_billboard_device_notifcation_id"; // Represents the buttons in the notification. enum ButtonIndex { kSettings, kLearnMore }; @@ -124,6 +126,12 @@ RemoveNotification(kPciePeripheralDeviceBlockedNotificationId); } +void OnBillboardNotificationClicked() { + NewWindowDelegate::GetInstance()->NewTabWithUrl( + GURL(kLearnMoreHelpUrl), /*from_user_interaction=*/true); + RemoveNotification(kPciePeripheralBillboardDeviceNotificationId); +} + // We only display notifications for active user sessions (signed-in/guest with // desktop ready). Also do not show notifications in signin or lock screen. bool ShouldDisplayNotification() { @@ -152,6 +160,27 @@ ash::PciePeripheralManager::Get()->AddObserver(this); } +void PciePeripheralNotificationController::NotifyBillboardDevice() { + std::unique_ptr<message_center::Notification> notification = + CreateSystemNotification( + message_center::NOTIFICATION_TYPE_SIMPLE, + kPciePeripheralBillboardDeviceNotificationId, + /*title=*/std::u16string(), + l10n_util::GetStringUTF16( + IDS_ASH_PCIE_PERIPHERAL_NOTIFICATION_BILLBOARD_DEVICE), + /*display_source=*/std::u16string(), GURL(), + message_center::NotifierId( + message_center::NotifierType::SYSTEM_COMPONENT, + kNotifierPciePeripheral), + message_center::RichNotificationData(), + base::MakeRefCounted<message_center::HandleNotificationClickDelegate>( + base::BindRepeating(&OnBillboardNotificationClicked)), + kSettingsIcon, + message_center::SystemNotificationWarningLevel::CRITICAL_WARNING); + + message_center_->AddNotification(std::move(notification)); +} + void PciePeripheralNotificationController::NotifyLimitedPerformance() { // Don't show the notification if the user has already clicked on the // notification three times. @@ -256,6 +285,10 @@ NotifyPeripheralBlockedNotification(); } +void PciePeripheralNotificationController::OnBillboardDeviceConnected() { + NotifyBillboardDevice(); +} + // static void PciePeripheralNotificationController::RegisterProfilePrefs( PrefRegistrySimple* registry) {
diff --git a/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.h b/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.h index eb01248a..2f461ac6 100644 --- a/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.h +++ b/ash/system/pcie_peripheral/pcie_peripheral_notification_controller.h
@@ -43,6 +43,7 @@ void OnLimitedPerformancePeripheralReceived() override; void OnGuestModeNotificationReceived(bool is_thunderbolt_only) override; void OnPeripheralBlockedReceived() override; + void OnBillboardDeviceConnected() override; // Call to show a notification to indicate that the recently plugged in // Thunderbolt/USB4 peripheral performance is limited. @@ -56,6 +57,10 @@ // Thunderbolt/USB4 peripheral is not allowed due to security reasons. void NotifyPeripheralBlockedNotification(); + // Call to show a notification that a billboard device that was connected + // is not supported by the board. + void NotifyBillboardDevice(); + private: friend class PciePeripheralNotificationControllerTest;
diff --git a/ash/system/pcie_peripheral/pcie_peripheral_notification_controller_unittest.cc b/ash/system/pcie_peripheral/pcie_peripheral_notification_controller_unittest.cc index 14114d0..e5351cce 100644 --- a/ash/system/pcie_peripheral/pcie_peripheral_notification_controller_unittest.cc +++ b/ash/system/pcie_peripheral/pcie_peripheral_notification_controller_unittest.cc
@@ -34,6 +34,8 @@ "cros_pcie_peripheral_guest_mode_not_supported_notifcation_id"; const char kPciePeripheralDeviceBlockedNotificationId[] = "cros_pcie_peripheral_device_blocked_notifcation_id"; +const char kPciePeripheralBillboardDeviceNotificationId[] = + "cros_pcie_peripheral_billboard_device_notifcation_id"; const char kLearnMoreHelpUrl[] = "https://www.support.google.com/chromebook?p=connect_thblt_usb4_accy"; @@ -89,6 +91,11 @@ kPciePeripheralDeviceBlockedNotificationId); } + message_center::Notification* GetBillboardDeviceNotification() { + return MessageCenter::Get()->FindVisibleNotificationById( + kPciePeripheralBillboardDeviceNotificationId); + } + int GetNumOsPrivacySettingsOpened() { return GetSystemTrayClient()->show_os_settings_privacy_and_security_count(); } @@ -153,7 +160,7 @@ controller()->NotifyGuestModeNotification(/*is_thunderbolt_only=*/true); EXPECT_EQ(1u, MessageCenter::Get()->NotificationCount()); - // Click on the notification and expect the Learn More page to page to appear. + // Click on the notification and expect the Learn More page to appear. EXPECT_CALL(new_window_delegate(), NewTabWithUrl) .WillOnce([](const GURL& url, bool from_user_interaction) { EXPECT_EQ(GURL(kLearnMoreHelpUrl), url); @@ -179,7 +186,7 @@ controller()->NotifyGuestModeNotification(/*is_thunderbolt_only=*/false); EXPECT_EQ(1u, MessageCenter::Get()->NotificationCount()); - // Click on the notification and expect the Learn More page to page to appear. + // Click on the notification and expect the Learn More page to appear. EXPECT_CALL(new_window_delegate(), NewTabWithUrl) .WillOnce([](const GURL& url, bool from_user_interaction) { EXPECT_EQ(GURL(kLearnMoreHelpUrl), url); @@ -203,7 +210,7 @@ // This notification has no buttons. EXPECT_EQ(0u, notification->buttons().size()); - // Click on the notification and expect the Learn More page to page to appear. + // Click on the notification and expect the Learn More page to appear. EXPECT_CALL(new_window_delegate(), NewTabWithUrl) .WillOnce([](const GURL& url, bool from_user_interaction) { EXPECT_EQ(GURL(kLearnMoreHelpUrl), url); @@ -214,6 +221,34 @@ EXPECT_EQ(0u, MessageCenter::Get()->NotificationCount()); } +TEST_F(PciePeripheralNotificationControllerTest, BillboardDeviceNotification) { + EXPECT_EQ(0u, MessageCenter::Get()->NotificationCount()); + EXPECT_EQ(3, GetPrefNotificationCount()); + + controller()->NotifyBillboardDevice(); + EXPECT_EQ(1u, MessageCenter::Get()->NotificationCount()); + + message_center::Notification* notification = GetBillboardDeviceNotification(); + ASSERT_TRUE(notification); + + // This notification has no buttons. + EXPECT_EQ(0u, notification->buttons().size()); + + controller()->NotifyBillboardDevice(); + EXPECT_EQ(1u, MessageCenter::Get()->NotificationCount()); + + // Click on the notification and expect the Learn More page to appear. + EXPECT_CALL(new_window_delegate(), NewTabWithUrl) + .WillOnce([](const GURL& url, bool from_user_interaction) { + EXPECT_EQ(GURL(kLearnMoreHelpUrl), url); + EXPECT_TRUE(from_user_interaction); + }); + MessageCenter::Get()->ClickOnNotification( + kPciePeripheralBillboardDeviceNotificationId); + EXPECT_EQ(0u, MessageCenter::Get()->NotificationCount()); + EXPECT_EQ(3, GetPrefNotificationCount()); +} + TEST_F(PciePeripheralNotificationControllerTest, LimitedPerformanceNotificationLearnMoreClick) { EXPECT_EQ(0u, MessageCenter::Get()->NotificationCount());
diff --git a/ash/system/power/power_button_menu_item_view.cc b/ash/system/power/power_button_menu_item_view.cc index e1314205..142b5b0 100644 --- a/ash/system/power/power_button_menu_item_view.cc +++ b/ash/system/power/power_button_menu_item_view.cc
@@ -4,8 +4,8 @@ #include "ash/system/power/power_button_menu_item_view.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/style/ash_color_provider.h" -#include "ash/style/scoped_light_mode_as_default.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font.h"
diff --git a/ash/system/power/power_button_menu_view.cc b/ash/system/power/power_button_menu_view.cc index 749625cc..6e0092d 100644 --- a/ash/system/power/power_button_menu_view.cc +++ b/ash/system/power/power_button_menu_view.cc
@@ -10,12 +10,12 @@ #include "ash/display/screen_orientation_controller.h" #include "ash/login/login_screen_controller.h" #include "ash/public/cpp/new_window_delegate.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_provider.h" -#include "ash/style/scoped_light_mode_as_default.h" #include "ash/system/power/power_button_menu_item_view.h" #include "ash/system/power/power_button_menu_metrics_type.h" #include "ash/system/user/login_status.h"
diff --git a/ash/system/tray/tray_background_view_unittest.cc b/ash/system/tray/tray_background_view_unittest.cc index 68aaa45..8f00011 100644 --- a/ash/system/tray/tray_background_view_unittest.cc +++ b/ash/system/tray/tray_background_view_unittest.cc
@@ -91,7 +91,6 @@ // Set Dictation button to be visible. AccessibilityControllerImpl* controller = Shell::Get()->accessibility_controller(); - controller->dictation().SetDialogAccepted(); controller->dictation().SetEnabled(true); }
diff --git a/ash/webui/scanning/resources/multi_page_scan.html b/ash/webui/scanning/resources/multi_page_scan.html index a61cce3..53c0f20 100644 --- a/ash/webui/scanning/resources/multi_page_scan.html +++ b/ash/webui/scanning/resources/multi_page_scan.html
@@ -49,7 +49,7 @@ <cr-button id="saveButton"> [[i18n('saveButtonLabel')]] </cr-button> - <cr-button id="scanButton" class="action-button"> + <cr-button id="scanButton" class="action-button" on-click="onScanClick_"> [[scanButtonText_]] </cr-button> </div>
diff --git a/ash/webui/scanning/resources/multi_page_scan.js b/ash/webui/scanning/resources/multi_page_scan.js index 2972f02a..b4aa1f84 100644 --- a/ash/webui/scanning/resources/multi_page_scan.js +++ b/ash/webui/scanning/resources/multi_page_scan.js
@@ -41,4 +41,9 @@ this.scanButtonText_ = pluralString; }); }, + + /** @private */ + onScanClick_() { + this.fire('scan-next-page'); + }, });
diff --git a/ash/webui/scanning/resources/scan_preview.js b/ash/webui/scanning/resources/scan_preview.js index a8b1147..09493773 100644 --- a/ash/webui/scanning/resources/scan_preview.js +++ b/ash/webui/scanning/resources/scan_preview.js
@@ -164,7 +164,8 @@ onAppStateChange_() { this.showScannedImages_ = this.appState === AppState.DONE || this.appState === AppState.MULTI_PAGE_NEXT_ACTION; - this.showScanProgress_ = this.appState === AppState.SCANNING; + this.showScanProgress_ = this.appState === AppState.SCANNING || + this.appState === AppState.MULTI_PAGE_SCANNING; this.showCancelingProgress_ = this.appState === AppState.CANCELING; this.showHelperText_ = !this.showScanProgress_ && !this.showCancelingProgress_ && !this.showScannedImages_;
diff --git a/ash/webui/scanning/resources/scanning_app.html b/ash/webui/scanning/resources/scanning_app.html index c588c660b..798c12c 100644 --- a/ash/webui/scanning/resources/scanning_app.html +++ b/ash/webui/scanning/resources/scanning_app.html
@@ -247,7 +247,8 @@ </scan-done-section> </template> <template is="dom-if" if="[[showMultiPageScan_]]"> - <multi-page-scan page-number="[[pageNumber_]]"></multi-page-scan> + <multi-page-scan page-number="[[pageNumber_]]" + on-scan-next-page="onScanNextPage_"></multi-page-scan> </template> </div> </div>
diff --git a/ash/webui/scanning/resources/scanning_app.js b/ash/webui/scanning/resources/scanning_app.js index 7f68798..f1f3b31 100644 --- a/ash/webui/scanning/resources/scanning_app.js +++ b/ash/webui/scanning/resources/scanning_app.js
@@ -35,7 +35,7 @@ import {afterNextRender, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getScanService} from './mojo_interface_provider.js'; -import {AppState, MAX_NUM_SAVED_SCANNERS, ScannerArr, ScannerCapabilitiesResponse, ScannerInfo, ScannerSetting, ScanSettings} from './scanning_app_types.js'; +import {AppState, MAX_NUM_SAVED_SCANNERS, ScannerArr, ScannerCapabilitiesResponse, ScannerInfo, ScannerSetting, ScanSettings, StartMultiPageScanResponse} from './scanning_app_types.js'; import {colorModeFromString, fileTypeFromString, getScannerDisplayName, pageSizeFromString, tokenToString} from './scanning_app_util.js'; import {ScanningBrowserProxy, ScanningBrowserProxyImpl, SelectedPath} from './scanning_browser_proxy.js'; @@ -65,6 +65,9 @@ /** @private {?ash.scanning.mojom.ScanServiceInterface} */ scanService_: null, + /** @private {?ash.scanning.mojom.MultiPageScanControllerInterface} */ + multiPageScanController_: null, + /** @private {!Map<string, !ScannerInfo>} */ scannerInfoMap_: new Map(), @@ -419,8 +422,14 @@ onPageProgress(pageNumber, progressPercent) { assert( this.appState_ === AppState.SCANNING || + this.appState_ === AppState.MULTI_PAGE_SCANNING || this.appState_ === AppState.CANCELING); - this.pageNumber_ = pageNumber; + + // The Scan app increments |this.pageNumber_| itself during a multi-page + // scan. + if (!this.isMultiPageScan_()) { + this.pageNumber_ = pageNumber; + } this.progressPercent_ = progressPercent; }, @@ -431,10 +440,11 @@ onPageComplete(pageData) { assert( this.appState_ === AppState.SCANNING || + this.appState_ === AppState.MULTI_PAGE_SCANNING || this.appState_ === AppState.CANCELING); const blob = new Blob([Uint8Array.from(pageData)], {'type': 'image/png'}); this.push('objectUrls_', URL.createObjectURL(blob)); - if (this.multiPageScanChecked) { + if (this.isMultiPageScan_()) { this.setAppState_(AppState.MULTI_PAGE_NEXT_ACTION); } }, @@ -560,20 +570,6 @@ return; } - const fileType = fileTypeFromString(this.selectedFileType); - const colorMode = colorModeFromString(this.selectedColorMode); - const pageSize = pageSizeFromString(this.selectedPageSize); - const resolution = Number(this.selectedResolution); - - const settings = { - sourceName: this.selectedSource, - scanToPath: {path: this.selectedFilePath}, - fileType: fileType, - colorMode: colorMode, - pageSize: pageSize, - resolutionDpi: resolution, - }; - if (!this.scanJobObserverReceiver_) { this.scanJobObserverReceiver_ = new ash.scanning.mojom.ScanJobObserverReceiver( @@ -583,24 +579,38 @@ (this)); } - this.scanService_ - .startScan( - this.getSelectedScannerToken_(), settings, - this.scanJobObserverReceiver_.$.bindNewPipeAndPassRemote()) - .then( - /*@type {!{success: boolean}}*/ (response) => { - this.onStartScanResponse_(response); - }); + const settings = this.getScanSettings_(); + if (this.isMultiPageScan_()) { + this.scanService_ + .startMultiPageScan( + this.getSelectedScannerToken_(), settings, + this.scanJobObserverReceiver_.$.bindNewPipeAndPassRemote()) + .then( + /*@type {!StartMultiPageScanResponse}*/ + (response) => { + this.onStartMultiPageScanResponse_(response); + }); + } else { + this.scanService_ + .startScan( + this.getSelectedScannerToken_(), settings, + this.scanJobObserverReceiver_.$.bindNewPipeAndPassRemote()) + .then( + /*@type {!{success: boolean}}*/ (response) => { + this.onStartScanResponse_(response); + }); + } + if (this.scanAppStickySettingsEnabled_) { this.saveScanSettings_(); } const scanJobSettingsForMetrics = { sourceType: this.sourceTypeMap_.get(this.selectedSource), - fileType: fileType, - colorMode: colorMode, - pageSize: pageSize, - resolution: resolution, + fileType: settings.fileType, + colorMode: settings.colorMode, + pageSize: settings.pageSize, + resolution: settings.resolutionDpi, }; this.browserProxy_.recordScanJobSettings(scanJobSettingsForMetrics); @@ -628,6 +638,49 @@ this.progressPercent_ = 0; }, + /** + * @param {!StartMultiPageScanResponse} response + * @private + */ + onStartMultiPageScanResponse_(response) { + if (!response.controller) { + this.showToast_('startScanFailedToast'); + return; + } + + this.setAppState_(AppState.SCANNING); + + assert(!this.multiPageScanController_); + this.multiPageScanController_ = response.controller; + this.pageNumber_ = 1; + this.progressPercent_ = 0; + }, + + /** @private */ + onScanNextPage_() { + this.multiPageScanController_ + .scanNextPage(this.getSelectedScannerToken_(), this.getScanSettings_()) + .then( + /*@type {!{success: boolean}}*/ (response) => { + this.onScanNextPageResponse_(response); + }); + }, + + /** + * @param {!{success: boolean}} response + * @private + */ + onScanNextPageResponse_(response) { + if (!response.success) { + this.showToast_('startScanFailedToast'); + return; + } + + this.setAppState_(AppState.MULTI_PAGE_SCANNING); + ++this.pageNumber_; + this.progressPercent_ = 0; + }, + /** @private */ toggleClicked_() { this.$$('#collapse').toggle(); @@ -718,7 +771,9 @@ assert(this.appState_ === AppState.GETTING_SCANNERS); break; case (AppState.MULTI_PAGE_NEXT_ACTION): - assert(this.appState_ === AppState.SCANNING); + assert( + this.appState_ === AppState.SCANNING || + this.appState_ === AppState.MULTI_PAGE_SCANNING); break; } @@ -735,7 +790,8 @@ this.cancelButtonDisabled_ = this.appState_ === AppState.CANCELING; this.showDoneSection_ = this.appState_ === AppState.DONE; this.showMultiPageScan_ = - this.appState_ === AppState.MULTI_PAGE_NEXT_ACTION; + this.appState_ === AppState.MULTI_PAGE_NEXT_ACTION || + this.appState_ === AppState.MULTI_PAGE_SCANNING; this.showScanSettings_ = !this.showDoneSection_ && !this.showMultiPageScan_; // Need to wait for elements to render after updating their disabled and @@ -1072,6 +1128,33 @@ }, /** + * @return {!ash.scanning.mojom.ScanSettings} + * @private + */ + getScanSettings_() { + const fileType = fileTypeFromString(this.selectedFileType); + const colorMode = colorModeFromString(this.selectedColorMode); + const pageSize = pageSizeFromString(this.selectedPageSize); + const resolution = Number(this.selectedResolution); + return { + sourceName: this.selectedSource, + scanToPath: {path: this.selectedFilePath}, + fileType: fileType, + colorMode: colorMode, + pageSize: pageSize, + resolutionDpi: resolution, + }; + }, + + /** + * @return {boolean} + * @private + */ + isMultiPageScan_() { + return this.scanAppMultiPageScanEnabled_ && this.multiPageScanChecked; + }, + + /** * @param {string} sourceName * @private */
diff --git a/ash/webui/scanning/resources/scanning_app_types.js b/ash/webui/scanning/resources/scanning_app_types.js index 059b01a..d1fdf1c 100644 --- a/ash/webui/scanning/resources/scanning_app_types.js +++ b/ash/webui/scanning/resources/scanning_app_types.js
@@ -17,6 +17,7 @@ CANCELING: 7, NO_SCANNERS: 8, MULTI_PAGE_NEXT_ACTION: 9, + MULTI_PAGE_SCANNING: 10, }; /** @@ -77,3 +78,9 @@ * }} */ export let ScanSettings; + +/** + * @typedef {{controller: + ?ash.scanning.mojom.MultiPageScanControllerRemote}} + */ +export let StartMultiPageScanResponse;
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_dialog.html b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_dialog.html index c5a3408..7e6931a 100644 --- a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_dialog.html +++ b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_dialog.html
@@ -11,8 +11,9 @@ </div> <div slot="body"> <div id="acceleratorViewList"> - <template is="dom-repeat" items=[[accelerators]]> - <accelerator-edit-view class="acceleratorItem" accelerator=[[item]]> + <template is="dom-repeat" items=[[acceleratorInfos]]> + <accelerator-edit-view class="acceleratorItem" + accelerator-info=[[item]]> </accelerator-edit-view> </template> </div>
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_dialog.js b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_dialog.js index bccd375..f0d26d3 100644 --- a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_dialog.js +++ b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_dialog.js
@@ -12,6 +12,8 @@ import {html, PolymerElement, flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {AcceleratorInfo} from './shortcut_types.js'; + /** * @fileoverview * 'accelerator-edit-dialog' is a dialog that displays the accelerators for @@ -34,12 +36,8 @@ value: '', }, - /** - * TODO(jimmyxgong): Replace with proper mojom::Accelerator type and - * implement fetching the accelerators for this row. - * @type {!Array<!Object>} - */ - accelerators: { + /** @type {!Array<!AcceleratorInfo>} */ + acceleratorInfos: { type: Array, value: () => {}, },
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.html b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.html index ede9688..a01eb748a 100644 --- a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.html +++ b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.html
@@ -27,7 +27,7 @@ <div id="acceleratorContainer"> <div id="acceleratorView"> <accelerator-view id="acceleratorItem" - accelerator=[[accelerator]] is-editable={{isEditView}}> + accelerator-info=[[acceleratorInfo]] is-editable={{isEditView}}> </accelerator-view> </div> <div id="acceleratorInfoText" hidden=[[!isEditView]]>
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js index 3ccadbd..33189b7 100644 --- a/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js +++ b/ash/webui/shortcut_customization_ui/resources/accelerator_edit_view.js
@@ -12,6 +12,8 @@ import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {AcceleratorInfo} from './shortcut_types.js'; + /** * @fileoverview * 'accelerator-edit-view' is a wrapper component for one accelerator. It is @@ -29,11 +31,8 @@ static get properties() { return { - /** - * TODO(jimmyxgong): Replace with proper mojom::Accelerator type. - * @type {!Object} - */ - accelerator: { + /** @type {!AcceleratorInfo} */ + acceleratorInfo: { type: Object, value: () => {}, },
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_row.html b/ash/webui/shortcut_customization_ui/resources/accelerator_row.html index 4beb238..f25d23c8 100644 --- a/ash/webui/shortcut_customization_ui/resources/accelerator_row.html +++ b/ash/webui/shortcut_customization_ui/resources/accelerator_row.html
@@ -21,8 +21,8 @@ <div id="container"> <div id="descriptionText">[[description]]</div> <div id="acceleratorViewList"> - <template is="dom-repeat" items=[[accelerators]]> - <accelerator-view class="acceleratorItem" accelerator=[[item]]> + <template is="dom-repeat" items=[[acceleratorInfos]]> + <accelerator-view class="acceleratorItem" accelerator-info=[[item]]> </accelerator-view> </template> </div>
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_row.js b/ash/webui/shortcut_customization_ui/resources/accelerator_row.js index 9953cd0..29aeb0e7 100644 --- a/ash/webui/shortcut_customization_ui/resources/accelerator_row.js +++ b/ash/webui/shortcut_customization_ui/resources/accelerator_row.js
@@ -9,6 +9,8 @@ import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {AcceleratorInfo} from './shortcut_types.js'; + /** * @fileoverview * 'accelerator-row' is a wrapper component for one shortcut. It features a @@ -31,12 +33,8 @@ value: '', }, - /** - * TODO(jimmyxgong): Replace with proper mojom::Accelerator type and - * implement fetching the accelerators for this row. - * @type {!Array<!Object>} - */ - accelerators: { + /** @type {!Array<!AcceleratorInfo>} */ + acceleratorInfos: { type: Array, value: () => {}, } @@ -62,7 +60,7 @@ this.dispatchEvent(new CustomEvent( 'show-edit-dialog', {bubbles: true, composed: true, detail: {description: this.description, - accelerators: this.accelerators}}, + accelerators: this.acceleratorInfos}}, )); } }
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_subsection.html b/ash/webui/shortcut_customization_ui/resources/accelerator_subsection.html index 01969a8..71dc2eb5 100644 --- a/ash/webui/shortcut_customization_ui/resources/accelerator_subsection.html +++ b/ash/webui/shortcut_customization_ui/resources/accelerator_subsection.html
@@ -14,7 +14,7 @@ <div id="rowList"> <template is="dom-repeat" items="[[acceleratorContainer]]"> <accelerator-row class="acceleratorRow" description="[[item.description]]" - accelerators="[[item.accelerators]]"> + accelerator-infos="[[item.acceleratorInfos]]"> </accelerator-row> </template> </div>
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_subsection.js b/ash/webui/shortcut_customization_ui/resources/accelerator_subsection.js index 69d64e7..40eb38b4 100644 --- a/ash/webui/shortcut_customization_ui/resources/accelerator_subsection.js +++ b/ash/webui/shortcut_customization_ui/resources/accelerator_subsection.js
@@ -31,7 +31,7 @@ * TODO(jimmyxgong): Fetch the shortcuts and it accelerators with the * mojom::source_id and mojom::subsection_id. This serves as a temporary * way to populate a subsection. - * @type {!Array<!Object>} + * @type {!Array<!{string, !Array<!AcceleratorInfo>}>} */ acceleratorContainer: { type: Array,
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_view.html b/ash/webui/shortcut_customization_ui/resources/accelerator_view.html index 4f973d3b..948096c0 100644 --- a/ash/webui/shortcut_customization_ui/resources/accelerator_view.html +++ b/ash/webui/shortcut_customization_ui/resources/accelerator_view.html
@@ -20,28 +20,32 @@ <template is="dom-repeat" items=[[modifiers_]]> <input-key key=[[item]] key-state="modifier-selected"></input-key> </template> - <input-key key=[[accelerator.key]] key-state="alpha-numeric-selected"> + <input-key key=[[acceleratorInfo.accelerator.key_display]] + key-state="alpha-numeric-selected"> </input-key> </template> <template is="dom-if" if=[[isEditable]]> <div id="editContainer" class="flex-row"> <input-key id="ctrlKey" key="ctrl" - key-state="[[getCtrlState_(pendingAccelerator_.*)]]"> + key-state="[[getCtrlState_(pendingAcceleratorInfo_.accelerator.*)]]"> </input-key> <input-key id="altKey" key="alt" - key-state="[[getAltState_(pendingAccelerator_.*)]]"> + key-state="[[getAltState_(pendingAcceleratorInfo_.*)]]"> </input-key> <input-key id="shiftKey" key="shift" - key-state="[[getShiftState_(pendingAccelerator_.*)]]"> + key-state="[[getShiftState_(pendingAcceleratorInfo_.*)]]"> </input-key> <input-key id="searchKey" key="search" - key-state="[[getSearchState_(pendingAccelerator_.*)]]"> + key-state="[[getSearchState_(pendingAcceleratorInfo_.*)]]" + > </input-key> <!-- TODO(jimmyxgong): Conditionally add this separator based off of the shortcut's layout info. --> <div id="acceleratorSeparator"> + </div> - <input-key id="pendingKey" key="[[getPendingKey_(pendingAccelerator_.*)]]" - key-state="[[getPendingKeyState_(pendingAccelerator_.*)]]"> + <input-key id="pendingKey" + key="[[getPendingKey_(pendingAcceleratorInfo_.*)]]" + key-state= + "[[getPendingKeyState_(pendingAcceleratorInfo_.*)]]"> </input-key> </div> </template>
diff --git a/ash/webui/shortcut_customization_ui/resources/accelerator_view.js b/ash/webui/shortcut_customization_ui/resources/accelerator_view.js index 956bd088..1829daf 100644 --- a/ash/webui/shortcut_customization_ui/resources/accelerator_view.js +++ b/ash/webui/shortcut_customization_ui/resources/accelerator_view.js
@@ -8,9 +8,7 @@ import {assertNotReached} from 'chrome://resources/js/assert.m.js'; import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {Modifier} from './shortcut_types.js'; - - +import {AcceleratorInfo, AcceleratorKeys, AcceleratorState, AcceleratorType, Modifier} from './shortcut_types.js'; const ModifierRawKeys = [ /*Shift=*/16, @@ -48,6 +46,16 @@ } } +/** @return {!AcceleratorInfo} */ +function CreateEmptyAcceleratorInfo() { + return /** @type {!AcceleratorInfo} */ ({ + accelerator: /* @type {!AcceleratorKeys} */( + {modifiers: 0, key: 0, key_display: ''}), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, + }); +} + /** * @fileoverview * 'accelerator-view' is wrapper component for an accelerator. It maintains both @@ -65,22 +73,16 @@ static get properties() { return { - /** - * TODO(jimmyxgong): Update this type to be the actual mojom::accelerator. - * @type{!Object} - */ - accelerator: { + /** @type {!AcceleratorInfo} */ + acceleratorInfo: { type: Object, - value: {}, + value: () => {}, }, - /** - * TODO(jimmyxgong): Update this type to be the actual mojom::accelerator. - * @type{!Object} - */ - pendingAccelerator_: { + /** @type {!AcceleratorInfo} */ + pendingAcceleratorInfo_: { type: Object, - value: {modifiers: 0, key: ''}, + value: () => {}, }, isEditable: { @@ -96,7 +98,7 @@ */ modifiers_: { type: Array, - computed: 'getModifiers_(accelerator)', + computed: 'getModifiers_(acceleratorInfo.accelerator.*)', }, /** @private */ @@ -115,7 +117,7 @@ let modifiers = []; for (const key in Modifier) { const modifier = Modifier[key]; - if (this.accelerator.modifiers & modifier) { + if (this.acceleratorInfo.accelerator.modifiers & modifier) { modifiers.push(GetModifierString(modifier)); } } @@ -156,9 +158,8 @@ if (this.isCapturing_) { return; } - // TODO(jimmyxgong): Update this to the proper mojom::Accelerator type // Disable ChromeOS accelerator handler when starting input capture. - this.pendingAccelerator_ = {modifiers: 0, key: ''}; + this.pendingAcceleratorInfo_ = CreateEmptyAcceleratorInfo(); this.isCapturing_ = true; } @@ -169,7 +170,7 @@ } this.isCapturing_ = false; - this.pendingAccelerator_ = {modifiers: 0, key: ''}; + this.pendingAcceleratorInfo_ = CreateEmptyAcceleratorInfo(); this.isEditable = false; } @@ -204,21 +205,22 @@ if (!this.hasValidModifiers_(e)) { // TODO(jimmyxgong): Fire events for error handling, e.g. Shift cannot be // the only modifier. - this.pendingAccelerator_ = {modifiers: 0, key: ''}; + this.pendingAcceleratorInfo_ = CreateEmptyAcceleratorInfo(); return; } - this.pendingAccelerator_ = this.keystrokeToAccelerator_(e); + this.set('pendingAcceleratorInfo_.accelerator', + this.keystrokeToAccelerator_(e)); } /** * Converts a keystroke event to an Accelerator Object. - * TODO(jimmyxgong): Convert return type to proper mojom::Accelerator type. * @param {!KeyboardEvent} e - * @return {!Object} The keystroke as an Acccelerator object. + * @return {!AcceleratorKeys} The keystroke as an Acccelerator object. * @private */ keystrokeToAccelerator_(e) { - const output = {modifiers: 0, key: ''}; + const output = /** @type {AcceleratorKeys} */({ + modifiers: 0, key: 0, key_display: ''}); if (e.metaKey) { output.modifiers = output.modifiers | Modifier.COMMAND; } @@ -236,7 +238,8 @@ // Only add non-modifier keys as the pending key. if (!this.isModifierKey_(e)) { - output.key = e.key; + output.key_display = e.key; + output.key = e.keyCode; } return output; @@ -289,7 +292,7 @@ * @private */ getModifierState_(modifier) { - if (this.pendingAccelerator_.modifiers & modifier) { + if (this.pendingAcceleratorInfo_.accelerator.modifiers & modifier) { return KeyState.MODIFIER; } return KeyState.NOT_SELECTED; @@ -300,7 +303,7 @@ * @protected */ getPendingKeyState_() { - if (this.pendingAccelerator_.key != '') { + if (this.pendingAcceleratorInfo_.accelerator.key_display != '') { return KeyState.ALPHANUMERIC; } return KeyState.NOT_SELECTED; @@ -311,8 +314,8 @@ * @protected */ getPendingKey_() { - if (this.pendingAccelerator_.key != '') { - return this.pendingAccelerator_.key.toLowerCase(); + if (this.pendingAcceleratorInfo_.accelerator.key_display != '') { + return this.pendingAcceleratorInfo_.accelerator.key_display.toLowerCase(); } // TODO(jimmyxgong): Reset to a localized default empty state. return 'key';
diff --git a/ash/wm/gestures/back_gesture/back_gesture_affordance.cc b/ash/wm/gestures/back_gesture/back_gesture_affordance.cc index 796ea5c..b41e8dc1 100644 --- a/ash/wm/gestures/back_gesture/back_gesture_affordance.cc +++ b/ash/wm/gestures/back_gesture/back_gesture_affordance.cc
@@ -6,10 +6,10 @@ #include "ash/display/screen_orientation_controller.h" #include "ash/public/cpp/shell_window_ids.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "ash/style/ash_color_provider.h" #include "ash/style/default_color_constants.h" #include "ash/style/default_colors.h" -#include "ash/style/scoped_light_mode_as_default.h" #include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/splitview/split_view_divider.h" #include "ash/wm/window_util.h"
diff --git a/base/barrier_callback.h b/base/barrier_callback.h index e5e1557..37ae6f0 100644 --- a/base/barrier_callback.h +++ b/base/barrier_callback.h
@@ -16,7 +16,7 @@ namespace base { -namespace { +namespace internal { template <typename T> class BarrierCallbackInfo { @@ -53,7 +53,7 @@ CHECK(false); } -} // namespace +} // namespace internal // BarrierCallback<T> is an analog of BarrierClosure for which each `Run()` // invocation takes a `T` as an argument. After `num_callbacks` such @@ -76,11 +76,11 @@ OnceCallback<void(std::vector<T>)> done_callback) { if (num_callbacks == 0) { std::move(done_callback).Run({}); - return BindRepeating(&ShouldNeverRun<T>); + return BindRepeating(&internal::ShouldNeverRun<T>); } - return BindRepeating(&BarrierCallbackInfo<T>::Run, - std::make_unique<BarrierCallbackInfo<T>>( + return BindRepeating(&internal::BarrierCallbackInfo<T>::Run, + std::make_unique<internal::BarrierCallbackInfo<T>>( num_callbacks, std::move(done_callback))); }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 94e1dc8..1e92da8 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -314,6 +314,7 @@ # .o files built with different compiler versions harder. if (!is_win || is_clang) { cflags += [ "-fno-ident" ] + asmflags += [ "-fno-ident" ] } # In general, Windows is totally different, but all the other builds share
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index c7ae5140..d40565a 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -6.20210803.0.1 +6.20210803.3.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index c7ae5140..d40565a 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -6.20210803.0.1 +6.20210803.3.1
diff --git a/build/lacros/lacros_resource_sizes.py b/build/lacros/lacros_resource_sizes.py index bf791c6..f761662 100755 --- a/build/lacros/lacros_resource_sizes.py +++ b/build/lacros/lacros_resource_sizes.py
@@ -98,7 +98,8 @@ title='File: chrome', track_stripped=True, track_compressed=True), - _Group(paths=['crashpad_handler'], title='File: crashpad_handler'), + _Group(paths=['chrome_crashpad_handler'], + title='File: chrome_crashpad_handler'), _Group(paths=['icudtl.dat'], title='File: icudtl.dat'), _Group(paths=['nacl_helper'], title='File: nacl_helper'), _Group(paths=['nacl_irt_x86_64.nexe'], title='File: nacl_irt_x86_64.nexe'),
diff --git a/build/lacros/test_runner.py b/build/lacros/test_runner.py index aad200b7..4c7f7fc 100755 --- a/build/lacros/test_runner.py +++ b/build/lacros/test_runner.py
@@ -71,7 +71,8 @@ 'prebuilt_ash_chrome') # Number of seconds to wait for ash-chrome to start. -ASH_CHROME_TIMEOUT_SECONDS = 10 +ASH_CHROME_TIMEOUT_SECONDS = ( + 300 if os.environ.get('ASH_WRAPPER', None) else 10) # List of targets that require ash-chrome as a Wayland server in order to run. _TARGETS_REQUIRE_ASH_CHROME = [ @@ -322,6 +323,15 @@ if enable_mojo_crosapi: ash_cmd.append(lacros_mojo_socket_arg) + # Users can specify a wrapper for the ash binary to do things like + # attaching debuggers. For example, this will open a new terminal window + # and run GDB. + # $ export ASH_WRAPPER="gnome-terminal -- gdb --ex=r --args" + ash_wrapper = os.environ.get('ASH_WRAPPER', None) + if ash_wrapper: + logging.info('Running ash with "ASH_WRAPPER": %s', ash_wrapper) + ash_cmd = list(ash_wrapper.split()) + ash_cmd + ash_process_has_started = False total_tries = 3 num_tries = 0
diff --git a/build/lacros/test_runner_test.py b/build/lacros/test_runner_test.py index 1a4403f..7e821009 100755 --- a/build/lacros/test_runner_test.py +++ b/build/lacros/test_runner_test.py
@@ -186,6 +186,33 @@ ['./url_unittests', '--gtest_filter=Suite.Test']) self.assertFalse(mock_download.called) + @mock.patch.dict(os.environ, {'ASH_WRAPPER': 'gdb --args'}, clear=False) + @mock.patch.object(os, + 'listdir', + return_value=['wayland-0', 'wayland-0.lock']) + @mock.patch.object(tempfile, + 'mkdtemp', + side_effect=['/tmp/xdg', '/tmp/ash-data']) + @mock.patch.object(os.environ, 'copy', side_effect=[{}, {}]) + @mock.patch.object(os.path, 'exists', return_value=True) + @mock.patch.object(os.path, 'isfile', return_value=True) + @mock.patch.object(test_runner, + '_GetLatestVersionOfAshChrome', + return_value='793554') + @mock.patch.object(test_runner, '_DownloadAshChromeIfNecessary') + @mock.patch.object(subprocess, 'Popen', return_value=mock.Mock()) + # Tests that, when the ASH_WRAPPER environment variable is set, it forwards + # the commands to the invocation of ash. + def test_ash_wrapper(self, mock_popen, *_): + args = [ + 'script_name', 'test', './browser_tests', '--gtest_filter=Suite.Test' + ] + with mock.patch.object(sys, 'argv', args): + test_runner.Main() + ash_args = mock_popen.call_args_list[0][0][0] + self.assertTrue(ash_args[2].endswith('test_ash_chrome')) + self.assertEqual(['gdb', '--args'], ash_args[:2]) + if __name__ == '__main__': unittest.main()
diff --git a/cc/input/compositor_input_interfaces.h b/cc/input/compositor_input_interfaces.h index d5bbaed..dcbd420b 100644 --- a/cc/input/compositor_input_interfaces.h +++ b/cc/input/compositor_input_interfaces.h
@@ -65,6 +65,9 @@ // completed. virtual void ScrollOffsetAnimationFinished() = 0; + // Called to inform the input handler when prefers-reduced-motion changes. + virtual void SetPrefersReducedMotion(bool prefers_reduced_motion) = 0; + // Returns true if we're currently in a "gesture" (user-initiated) scroll. // That is, between a GestureScrollBegin and a GestureScrollEnd. Note, a // GestureScrollEnd is deferred if the gesture ended but we're still
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h index 87762f5a..e5e555b 100644 --- a/cc/input/input_handler.h +++ b/cc/input/input_handler.h
@@ -106,6 +106,7 @@ virtual void WillShutdown() = 0; virtual void Animate(base::TimeTicks time) = 0; virtual void ReconcileElasticOverscrollAndRootScroll() = 0; + virtual void SetPrefersReducedMotion(bool prefers_reduced_motion) = 0; virtual void UpdateRootLayerStateForSynchronousInputHandler( const gfx::ScrollOffset& total_scroll_offset, const gfx::ScrollOffset& max_scroll_offset, @@ -352,6 +353,7 @@ EventsMetricsManager::ScopedMonitor::DoneCallback done_callback) = 0; virtual ScrollElasticityHelper* CreateScrollElasticityHelper() = 0; + virtual void DestroyScrollElasticityHelper() = 0; // Called by the single-threaded UI Compositor to get or set the scroll offset // on the impl side. Returns false if |element_id| isn't in the active tree.
diff --git a/cc/input/threaded_input_handler.cc b/cc/input/threaded_input_handler.cc index 3b8e9b0..872bf40 100644 --- a/cc/input/threaded_input_handler.cc +++ b/cc/input/threaded_input_handler.cc
@@ -77,6 +77,7 @@ void ThreadedInputHandler::BindToClient(InputHandlerClient* client) { DCHECK(input_handler_client_ == nullptr); input_handler_client_ = client; + input_handler_client_->SetPrefersReducedMotion(prefers_reduced_motion_); } InputHandler::ScrollStatus ThreadedInputHandler::ScrollBegin( @@ -871,6 +872,12 @@ return scroll_elasticity_helper_.get(); } +void ThreadedInputHandler::DestroyScrollElasticityHelper() { + // Remove any stretch before destroying helper. + scroll_elasticity_helper_->SetStretchAmount(gfx::Vector2dF()); + scroll_elasticity_helper_.reset(); +} + bool ThreadedInputHandler::GetScrollOffsetForLayer(ElementId element_id, gfx::ScrollOffset* offset) { ScrollTree& scroll_tree = GetScrollTree(); @@ -1121,6 +1128,16 @@ } } +void ThreadedInputHandler::SetPrefersReducedMotion( + bool prefers_reduced_motion) { + if (prefers_reduced_motion_ == prefers_reduced_motion) + return; + prefers_reduced_motion_ = prefers_reduced_motion; + + if (input_handler_client_) + input_handler_client_->SetPrefersReducedMotion(prefers_reduced_motion_); +} + bool ThreadedInputHandler::IsCurrentlyScrolling() const { return CurrentlyScrollingNode(); }
diff --git a/cc/input/threaded_input_handler.h b/cc/input/threaded_input_handler.h index d7ae575..eb3b6d5 100644 --- a/cc/input/threaded_input_handler.h +++ b/cc/input/threaded_input_handler.h
@@ -91,6 +91,7 @@ GetScopedEventMetricsMonitor( EventsMetricsManager::ScopedMonitor::DoneCallback done_callback) override; ScrollElasticityHelper* CreateScrollElasticityHelper() override; + void DestroyScrollElasticityHelper() override; bool GetScrollOffsetForLayer(ElementId element_id, gfx::ScrollOffset* offset) override; bool ScrollLayerTo(ElementId element_id, @@ -118,6 +119,7 @@ void DidUnregisterScrollbar(ElementId scroll_element_id, ScrollbarOrientation orientation) override; void ScrollOffsetAnimationFinished() override; + void SetPrefersReducedMotion(bool prefers_reduced_motion) override; bool IsCurrentlyScrolling() const override; ActivelyScrollingType GetActivelyScrollingType() const override; @@ -444,6 +446,8 @@ bool has_scrolled_by_precisiontouchpad_ = false; bool has_scrolled_by_scrollbar_ = false; + bool prefers_reduced_motion_ = false; + // Must be the last member to ensure this is destroyed first in the // destruction order and invalidates all weak pointers. base::WeakPtrFactory<ThreadedInputHandler> weak_factory_{this};
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index fba2325..e4895ee 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -1430,6 +1430,13 @@ SetNeedsCommit(); } +void LayerTreeHost::SetPrefersReducedMotion(bool prefers_reduced_motion) { + if (prefers_reduced_motion_ == prefers_reduced_motion) + return; + prefers_reduced_motion_ = prefers_reduced_motion; + SetNeedsCommit(); +} + void LayerTreeHost::SetExternalPageScaleFactor( float page_scale_factor, bool is_external_pinch_gesture_active) { @@ -1741,6 +1748,7 @@ host_impl->SetDebugState(debug_state_); host_impl->SetVisualDeviceViewportSize(visual_device_viewport_size_); host_impl->set_viewport_mobile_optimized(is_viewport_mobile_optimized_); + host_impl->SetPrefersReducedMotion(prefers_reduced_motion_); } Layer* LayerTreeHost::LayerByElementId(ElementId element_id) const {
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 02b0cb3..48b503c 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h
@@ -444,6 +444,8 @@ // Returns if the viewport is considered to be mobile optimized. bool IsMobileOptimized() const; + void SetPrefersReducedMotion(bool prefers_reduced_motion); + void SetBrowserControlsParams(const BrowserControlsParams& params); void SetBrowserControlsShownRatio(float top_ratio, float bottom_ratio); @@ -915,6 +917,7 @@ // <meta name="viewport" content="initial-scale=1.0"> bool is_viewport_mobile_optimized_ = false; + bool prefers_reduced_motion_ = false; bool have_scroll_event_handlers_ = false; EventListenerProperties event_listener_properties_ [static_cast<size_t>(EventListenerClass::kLast) + 1];
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index e1a99c0..8029fe6 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -3983,6 +3983,7 @@ void LayerTreeHostImpl::BindToInputHandler( std::unique_ptr<InputDelegateForCompositor> delegate) { input_delegate_ = std::move(delegate); + input_delegate_->SetPrefersReducedMotion(prefers_reduced_motion_); } void LayerTreeHostImpl::SetVisualDeviceViewportSize( @@ -3994,6 +3995,15 @@ return visual_device_viewport_size_; } +void LayerTreeHostImpl::SetPrefersReducedMotion(bool prefers_reduced_motion) { + if (prefers_reduced_motion_ == prefers_reduced_motion) + return; + + prefers_reduced_motion_ = prefers_reduced_motion; + if (input_delegate_) + input_delegate_->SetPrefersReducedMotion(prefers_reduced_motion_); +} + ScrollTree& LayerTreeHostImpl::GetScrollTree() const { return active_tree_->property_trees()->scroll_tree; }
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 8e0337d5..70afde0 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -403,6 +403,8 @@ return is_viewport_mobile_optimized_; } + void SetPrefersReducedMotion(bool prefers_reduced_motion); + // Updates registered ElementIds present in |changed_list|. Call this after // changing the property trees for the |changed_list| trees. void UpdateElements(ElementListType changed_list); @@ -1170,6 +1172,8 @@ // <meta name="viewport" content="initial-scale=1.0"> bool is_viewport_mobile_optimized_ = false; + bool prefers_reduced_motion_ = false; + std::unique_ptr<PendingTreeRasterDurationHistogramTimer> pending_tree_raster_duration_timer_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 9c8a3cc..2889909 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -928,6 +928,7 @@ void WillShutdown() override {} void Animate(base::TimeTicks time) override {} void ReconcileElasticOverscrollAndRootScroll() override {} + void SetPrefersReducedMotion(bool prefers_reduced_motion) override {} void UpdateRootLayerStateForSynchronousInputHandler( const gfx::ScrollOffset& total_scroll_offset, const gfx::ScrollOffset& max_scroll_offset,
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index 3d1e49d..b0d0479 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -1766,6 +1766,8 @@ } } + void SetPrefersReducedMotion(bool prefers_reduced_motion) override {} + void UpdateRootLayerStateForSynchronousInputHandler( const gfx::ScrollOffset& total_scroll_offset, const gfx::ScrollOffset& max_scroll_offset, @@ -2234,6 +2236,7 @@ void WillShutdown() override {} void Animate(base::TimeTicks) override {} + void SetPrefersReducedMotion(bool prefers_reduced_motion) override {} void UpdateRootLayerStateForSynchronousInputHandler( const gfx::ScrollOffset& total_scroll_offset, const gfx::ScrollOffset& max_scroll_offset,
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index d5c1afa9e..452a6fc 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -273,6 +273,8 @@ "//chrome/common:buildflags", ] + data_deps += [ "//components/crash/core/app:chrome_crashpad_handler" ] + ldflags = [] # Chrome OS debug builds for arm need to pass --long-plt to the linker. @@ -1681,8 +1683,8 @@ deps = [ ":angle_egl_symbols", ":angle_gles_symbols", + ":chrome_crashpad_symbols", ":chrome_symbols", - ":crashpad_symbols", ":swiftshader_egl_symbols", ":swiftshader_gles_symbols", ] @@ -1705,8 +1707,8 @@ deps = [ ":chrome" ] } - extract_symbols("crashpad_symbols") { - binary = "$root_out_dir/crashpad_handler" + extract_symbols("chrome_crashpad_symbols") { + binary = "$root_out_dir/chrome_crashpad_handler" if (current_cpu == "x86") { # GYP used "ia32" so keep that naming for back-compat. @@ -1715,7 +1717,7 @@ symbol_file = "$root_out_dir/crashpad.breakpad.$current_cpu" } - deps = [ "//third_party/crashpad/crashpad/handler:crashpad_handler" ] + deps = [ "//components/crash/core/app:chrome_crashpad_handler" ] } extract_symbols("swiftshader_egl_symbols") { binary = "$root_out_dir/swiftshader/libEGL.so"
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index a8d88ea..b932289c 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -2737,23 +2737,40 @@ ] } -jinja_template("monochrome_public_test_ar_apk_manifest") { - input = "javatests/AndroidManifest_monochrome.xml" - includes = [ - "java/AndroidManifest.xml", - "java/AndroidManifest_monochrome.xml", - "javatests/AndroidManifest.xml", - "//android_webview/nonembedded/java/AndroidManifest.xml", - ] +template("monochrome_public_test_ar_apk_manifest_tmpl") { + jinja_template(target_name) { + forward_variables_from(invoker, "*") + input = "javatests/AndroidManifest_monochrome.xml" + includes = [ + "java/AndroidManifest.xml", + "java/AndroidManifest_monochrome.xml", + "javatests/AndroidManifest.xml", + "//android_webview/nonembedded/java/AndroidManifest.xml", + ] + variables = chrome_public_jinja_variables + + monochrome_android_manifest_jinja_variables + + [ + "target_sdk_version=$android_sdk_version", + "test_manifest_package=$chrome_public_test_manifest_package", + "webview_library=$webview_library_name", + "include_arcore_manifest_flag=$enable_arcore", + ] + } +} + +monochrome_public_test_ar_apk_manifest_tmpl( + "monochrome_public_test_ar_apk_manifest") { output = monochrome_public_test_ar_apk_manifest - variables = chrome_public_jinja_variables + - monochrome_android_manifest_jinja_variables + - [ - "target_sdk_version=$android_sdk_version", - "test_manifest_package=$chrome_public_test_manifest_package", - "webview_library=libmonochrome.so", - "include_arcore_manifest_flag=$enable_arcore", - ] + webview_library_name = "libmonochrome.so" +} + +if (android_64bit_target_cpu && skip_secondary_abi_for_cq) { + monochrome_public_test_ar_64_apk_manifest = "$root_gen_dir/monochrome_public_test_ar_64_apk_manifest/AndroidManifest.xml" + monochrome_public_test_ar_apk_manifest_tmpl( + "monochrome_public_test_ar_64_apk_manifest") { + output = monochrome_public_test_ar_64_apk_manifest + webview_library_name = "libmonochrome_64.so" + } } template("chrome_test_apk_tmpl") { @@ -2811,6 +2828,7 @@ "data_deps", "is_64_bit_browser", "include_64_bit_webview", + "include_32_bit_webview", "loadable_modules", "min_sdk_version", "proguard_configs", @@ -2927,14 +2945,21 @@ if (enable_arcore) { monochrome_test_apk_tmpl("monochrome_public_test_ar_apk") { apk_name = "MonochromePublicTestAr" - android_manifest = monochrome_public_test_ar_apk_manifest - android_manifest_dep = ":monochrome_public_test_ar_apk_manifest" min_sdk_version = 24 target_sdk_version = android_sdk_version + android_manifest = monochrome_public_test_ar_apk_manifest + android_manifest_dep = ":monochrome_public_test_ar_apk_manifest" if (android_64bit_target_cpu) { - is_64_bit_browser = false - include_64_bit_webview = true + if (skip_secondary_abi_for_cq) { + android_manifest = monochrome_public_test_ar_64_apk_manifest + android_manifest_dep = ":monochrome_public_test_ar_64_apk_manifest" + is_64_bit_browser = true + include_32_bit_webview = false + } else { + is_64_bit_browser = false + include_64_bit_webview = true + } } # This is where we would add the shared_libraries entry for @@ -2964,9 +2989,13 @@ "target_out_dir") + "/com_google_ar_core_java/jni" # We store this as a separate .so in the APK and only load as needed. - if (android_64bit_target_cpu && !skip_secondary_abi_for_cq) { - secondary_abi_loadable_modules = - [ "$_libarcore_dir/armeabi-v7a/libarcore_sdk_c.so" ] + if (android_64bit_target_cpu) { + if (skip_secondary_abi_for_cq) { + loadable_modules = [ "$_libarcore_dir/arm64-v8a/libarcore_sdk_c.so" ] + } else { + secondary_abi_loadable_modules = + [ "$_libarcore_dir/armeabi-v7a/libarcore_sdk_c.so" ] + } } else { loadable_modules = [ "$_libarcore_dir/armeabi-v7a/libarcore_sdk_c.so" ] }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBottomsheetTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBottomsheetTest.java index 241a0fd..bcf32d5 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBottomsheetTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBottomsheetTest.java
@@ -265,6 +265,7 @@ @Test @MediumTest + @DisabledTest(message = "https://crbug.com/1236142") public void testHandleHeader() throws Exception { AutofillAssistantTestService testService = new AutofillAssistantTestService( Collections.singletonList(makeScript(RESIZE_LAYOUT_VIEWPORT, HANDLE_HEADER, true))); @@ -289,6 +290,7 @@ @Test @MediumTest + @DisabledTest(message = "https://crbug.com/1236142") public void testHandleHeaderCarousels() { AutofillAssistantTestService testService = new AutofillAssistantTestService(Collections.singletonList(
diff --git a/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/BLEAdvert.java b/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/BLEAdvert.java index b831009..ebd7717 100644 --- a/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/BLEAdvert.java +++ b/chrome/android/features/cablev2_authenticator/java/src/org/chromium/chrome/browser/webauth/authenticator/BLEAdvert.java
@@ -15,7 +15,6 @@ import org.chromium.base.annotations.CalledByNative; import java.io.Closeable; -import java.nio.ByteBuffer; import java.util.UUID; class BLEAdvert implements Closeable { @@ -30,6 +29,15 @@ BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser(); + if (advertiser == null) { + // It's possible for the Bluetooth adapter to have been disabled + // between the previous check and now (crbug.com/123454675). Due to + // the narrowness of this corner case we don't attempt to watch the + // adapter in case it is reenabled. Instead the advert is lost and + // the transaction won't work. + return; + } + mCallback = new AdvertiseCallback() { @Override public void onStartFailure(int errorCode) { @@ -68,8 +76,11 @@ BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser(); - Log.i(TAG, "stopping advertising"); - advertiser.stopAdvertising(mCallback); + // The Bluetooth adapter may have been disabled during the transaction. + if (advertiser != null) { + Log.i(TAG, "stopping advertising"); + advertiser.stopAdvertising(mCallback); + } mCallback = null; } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java index 3f43f5a..82f75b2a 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogView.java
@@ -67,7 +67,6 @@ private final Context mContext; private final int mToolbarHeight; - private final int mUngroupBarHeight; private final float mTabGridCardPadding; private View mBackgroundFrame; private View mAnimationCardView; @@ -112,8 +111,6 @@ mTabGridCardPadding = TabUiThemeProvider.getTabCardPaddingDimension(mContext); mToolbarHeight = (int) mContext.getResources().getDimension(R.dimen.tab_group_toolbar_height); - mUngroupBarHeight = - (int) mContext.getResources().getDimension(R.dimen.bottom_sheet_peek_height); mBackgroundDrawableColor = ContextCompat.getColor(mContext, R.color.tab_grid_dialog_background_color); @@ -174,6 +171,7 @@ updateDialogWithOrientation(mContext.getResources().getConfiguration().orientation); prepareAnimation(); + mDialogContainerView.setClipToOutline(true); } private void prepareAnimation() {
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java index a1d2efc..2d46570d 100644 --- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java +++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceMediator.java
@@ -674,7 +674,7 @@ private void updatePromoCardPadding(View promoCard) { MarginLayoutParams layoutParams = promoCard.getLayoutParams() == null - ? new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT) + ? new MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT) : (MarginLayoutParams) promoCard.getLayoutParams(); layoutParams.bottomMargin = isSuggestionsVisible() ? 0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java index f2e83ac..cb8d08d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java
@@ -29,6 +29,7 @@ import org.chromium.chrome.browser.night_mode.GlobalNightModeStateProviderHolder; import org.chromium.chrome.browser.night_mode.NightModeStateProvider; import org.chromium.chrome.browser.night_mode.NightModeUtils; +import org.chromium.chrome.browser.theme.ThemeUtils; import org.chromium.chrome.browser.ui.theme.ColorDelegateImpl; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogManagerHolder; @@ -176,9 +177,10 @@ protected void applyThemeOverlays() { setTheme(R.style.ColorOverlay_ChromiumAndroid); - if (CachedFeatureFlags.isEnabled(ChromeFeatureList.DYNAMIC_COLOR_ANDROID)) { + if (supportsDynamicColors()) { new ColorDelegateImpl().applyDynamicColorsIfAvailable(this); } + // Try to enable browser overscroll when content overscroll is enabled for consistency. This // needs to be in a cached feature because activity startup happens before native is // initialized. Unfortunately content overscroll is read in renderer threads, and these two @@ -191,6 +193,14 @@ } } + /** + * Returns whether the activity supports dynamic colors. For most activities this is only true + * if full dynamic colors are enabled. + */ + protected boolean supportsDynamicColors() { + return ThemeUtils.ENABLE_FULL_DYNAMIC_COLORS.getValue(); + } + // NightModeStateProvider.Observer implementation. @Override public void onNightModeStateChanged() {
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 b28f56b0..a34cfc7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -2629,6 +2629,11 @@ } } + @Override + protected boolean supportsDynamicColors() { + return CachedFeatureFlags.isEnabled(ChromeFeatureList.DYNAMIC_COLOR_ANDROID); + } + /** * Reports that a new tab launcher shortcut was selected or an action equivalent to a shortcut * was performed.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java index bd461886..2eba5b1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil; import org.chromium.chrome.browser.tasks.tab_management.PriceTrackingUtilities; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; +import org.chromium.chrome.browser.theme.ThemeUtils; import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; import java.util.ArrayList; @@ -153,6 +154,7 @@ add(TabUiFeatureUtilities.SKIP_SLOW_ZOOMING); add(TabUiFeatureUtilities.TAB_GRID_LAYOUT_ANDROID_NEW_TAB_TILE); add(TabUiFeatureUtilities.THUMBNAIL_ASPECT_RATIO); + add(ThemeUtils.ENABLE_FULL_DYNAMIC_COLORS); } }; tryToCatchMissingParameters(fieldTrialsToCache);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java index 50e535ed..400bb028 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -1284,8 +1284,7 @@ * @return The amount of overlap of padding values that can be removed (in pixels). */ public float getInBarRelatedSearchesRedundantPadding() { - return mContext.getResources().getDimension( - R.dimen.related_searches_in_bar_redundant_padding); + return getRelatedSearchesInBarControl().getRedundantPadding(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/RelatedSearchesControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/RelatedSearchesControl.java index 61a7ed0..3c2feb9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/RelatedSearchesControl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/RelatedSearchesControl.java
@@ -139,7 +139,21 @@ * @return The View height in pixels. */ public float getHeightPx() { - return mIsVisible ? mHeightPx : 0f; + return !mIsVisible || mControlView == null ? 0f : mHeightPx; + } + + /** + * Returns the amount of padding that is redundant between the Related Searches carousel that is + * shown in the Bar with the content above it. The content above has its own padding that + * provides a space between it and the bottom of the Bar. So when the Bar grows to include the + * Related Searches (which has its own padding above and below) there is redundant padding. + * @return The amount of overlap of padding values that can be removed (in pixels). + */ + public float getRedundantPadding() { + return !mIsVisible || mControlView == null + ? 0f + : mContext.getResources().getDimension( + R.dimen.related_searches_in_bar_redundant_padding); } /** Returns the ID of the view, or {@code INVALID_VIEW_ID} if there's no view. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java index 45f1726..8624994 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java
@@ -218,8 +218,8 @@ @Override public PageInfoSubpageController createHistoryController( - PageInfoMainController mainController, PageInfoRowView rowView, String host) { - return new PageInfoHistoryController(mainController, rowView, this, host); + PageInfoMainController mainController, PageInfoRowView rowView) { + return new PageInfoHistoryController(mainController, rowView, this); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoHistoryController.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoHistoryController.java index ec05607c..cb7f4553 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoHistoryController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/PageInfoHistoryController.java
@@ -48,12 +48,12 @@ private long mLastVisitedTimestamp; public PageInfoHistoryController(PageInfoMainController mainController, PageInfoRowView rowView, - PageInfoControllerDelegate delegate, String host) { + PageInfoControllerDelegate delegate) { mMainController = mainController; mRowView = rowView; mDelegate = delegate; mTitle = mRowView.getContext().getResources().getString(R.string.page_info_history_title); - mHost = host; + mHost = mainController.getURL().getHost(); mHistoryProvider = sProviderForTests != null ? sProviderForTests : new BrowsingHistoryBridge(Profile.getLastUsedRegularProfile());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java index 635768f8..7f2e84a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/AccountChooserDialog.java
@@ -25,8 +25,10 @@ import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; + import androidx.appcompat.app.AlertDialog; import androidx.appcompat.content.res.AppCompatResources; + import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.NativeMethods; import org.chromium.chrome.R; @@ -112,12 +114,12 @@ LayoutInflater inflater = LayoutInflater.from(getContext()); convertView = inflater.inflate(R.layout.account_chooser_dialog_item, parent, false); - convertView.setOnClickListener(view -> { - mCredential = mCredentials[position]; - if (mDialog != null) mDialog.dismiss(); - }); - convertView.setSelected(false); } + convertView.setSelected(false); + convertView.setOnClickListener(view -> { + mCredential = mCredentials[position]; + if (mDialog != null) mDialog.dismiss(); + }); convertView.setTag(position); Credential credential = getItem(position);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java index da70cda..b9bbd00 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr/WebXrVrTransitionTest.java
@@ -36,6 +36,7 @@ import org.chromium.base.test.params.ParameterizedRunner; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.Restriction; import org.chromium.base.test.util.UrlUtils; @@ -162,6 +163,7 @@ @Restriction({RESTRICTION_TYPE_DEVICE_DAYDREAM, RESTRICTION_TYPE_VR_DON_ENABLED}) @CommandLineFlags.Add({"enable-features=WebXR"}) @XrActivityRestriction({XrActivityRestriction.SupportedActivity.ALL}) + @DisabledTest(message = "https://crbug.com/1236093") public void testPresentationPromiseUnresolvedDuringDon_WebXr() { presentationPromiseUnresolvedDuringDonImpl(
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 0f436cd..d92671a 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -5693,4 +5693,12 @@ 1x </message> + <!-- Dictation accessibility feature confirmation dialog --> + <message name="IDS_ACCESSIBILITY_DICTATION_CONFIRMATION_TITLE" desc="The title for the modal dialog shown the first time the user enables dictation. Only displayed if the user is using network speech recognition."> + Dictation + </message> + <message name="IDS_ACCESSIBILITY_DICTATION_CONFIRMATION_TEXT" desc="The message shown the first time the user enables Dictation, explaining that the audio data will be sent to Google for transcription. Only displayed if the user is using network speech recognition."> + Dictation sends your voice to Google to allow voice typing in any text field. + </message> + </grit-part>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ACCESSIBILITY_DICTATION_CONFIRMATION_TEXT.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ACCESSIBILITY_DICTATION_CONFIRMATION_TEXT.png.sha1 new file mode 100644 index 0000000..b3f1aa4 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_ACCESSIBILITY_DICTATION_CONFIRMATION_TEXT.png.sha1
@@ -0,0 +1 @@ +bfe54f6363a1c2a0d42421b9ae7b90f1756bf80f \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ACCESSIBILITY_DICTATION_CONFIRMATION_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ACCESSIBILITY_DICTATION_CONFIRMATION_TITLE.png.sha1 new file mode 100644 index 0000000..b3f1aa4 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_ACCESSIBILITY_DICTATION_CONFIRMATION_TITLE.png.sha1
@@ -0,0 +1 @@ +bfe54f6363a1c2a0d42421b9ae7b90f1756bf80f \ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index bec2f33..e62b323 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -10246,6 +10246,9 @@ <message name="IDS_DESKTOP_MEDIA_PICKER_MULTIPLE_SCREEN_NAME" desc="Name for screens in the desktop media picker UI when there are multiple monitors."> {SCREEN_INDEX, plural, =1{Screen #} other{Screen #}} </message> + <message name="IDS_DESKTOP_MEDIA_PICKER_MANAGED" desc="Text to display when picker choices have been limited by enterprise policies."> + Options for sharing are managed by your organization. + </message> <if expr="toolkit_views"> <message name="IDS_DESKTOP_MEDIA_PICKER_SOURCE_TYPE_THIS_TAB" desc="Text for one of the dialog-tabs on the media picker dialog. This dialog-tab controls sharing the current tab."> This Tab
diff --git a/chrome/app/generated_resources_grd/IDS_DESKTOP_MEDIA_PICKER_MANAGED.png.sha1 b/chrome/app/generated_resources_grd/IDS_DESKTOP_MEDIA_PICKER_MANAGED.png.sha1 new file mode 100644 index 0000000..1c431f64 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DESKTOP_MEDIA_PICKER_MANAGED.png.sha1
@@ -0,0 +1 @@ +5b6dfb5e2ddf242f6bc60867b11f8eaaeb1c88a1 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index c7f02460..b26d2b08 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -723,6 +723,8 @@ "media/webrtc/native_desktop_media_list.h", "media/webrtc/permission_bubble_media_access_handler.cc", "media/webrtc/permission_bubble_media_access_handler.h", + "media/webrtc/same_origin_observer.cc", + "media/webrtc/same_origin_observer.h", "media/webrtc/webrtc_event_log_history.cc", "media/webrtc/webrtc_event_log_history.h", "media/webrtc/webrtc_event_log_manager.cc", @@ -1866,7 +1868,7 @@ "//chrome/services/file_util/public/mojom", "//components/account_id", "//components/autofill/core/browser", - "//components/enterprise/common/proto:download_item_reroute_info_proto", + "//components/enterprise/common:download_item_reroute_info", "//components/nacl/common:buildflags", "//components/optimization_guide:machine_learning_tflite_buildflags", "//components/page_info", @@ -3467,6 +3469,8 @@ "apps/app_service/publishers/extension_apps.h", "apps/app_service/publishers/extension_apps_base.cc", "apps/app_service/publishers/extension_apps_base.h", + "apps/app_service/publishers/extension_apps_util.cc", + "apps/app_service/publishers/extension_apps_util.h", "apps/apps_fetcher_service/apps_fetcher_service.cc", "apps/apps_fetcher_service/apps_fetcher_service.h", "apps/apps_fetcher_service/apps_fetcher_service_factory.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index a0253cc..c3124d3 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -2141,6 +2141,13 @@ base::size(kLensContextMenuTranslateHideRemoveIcon), nullptr}, }; +const FeatureEntry::FeatureParam kDynamicColorFull[] = { + {"dynamic_color_full", "true"}}; + +const FeatureEntry::FeatureVariation kDynamicColorAndroidVariations[] = { + {"(Full)", kDynamicColorFull, base::size(kDynamicColorFull), nullptr}, +}; + #endif // defined(OS_ANDROID) const FeatureEntry::FeatureParam kLazyFrameLoadingAutomatic[] = { @@ -4033,7 +4040,7 @@ kOsAndroid, FEATURE_VALUE_TYPE(feed::kInterestFeedV2ClicksAndViewsConditionalUpload)}, #endif // OS_ANDROID - {"PasswordImport", flag_descriptions::kPasswordImportName, + {"password-import", flag_descriptions::kPasswordImportName, flag_descriptions::kPasswordImportDescription, kOsAll, FEATURE_VALUE_TYPE(password_manager::features::kPasswordImport)}, {"enable-force-dark", flag_descriptions::kForceWebContentsDarkModeName, @@ -7190,7 +7197,7 @@ flag_descriptions::kContinuousSearchDescription, kOsAndroid, FEATURE_WITH_PARAMS_VALUE_TYPE(features::kContinuousSearch, kContinuousSearchFeatureVariations, - "ContinuousSearchVariations")}, + "ContinuousSearchNavigation")}, {"enable-experimental-accessibility-labels", flag_descriptions::kExperimentalAccessibilityLabelsName, @@ -7672,7 +7679,9 @@ #if defined(OS_ANDROID) {"dynamic-color-android", flag_descriptions::kDynamicColorAndroidName, flag_descriptions::kDynamicColorAndroidDescription, kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kDynamicColorAndroid)}, + FEATURE_WITH_PARAMS_VALUE_TYPE(chrome::android::kDynamicColorAndroid, + kDynamicColorAndroidVariations, + "AndroidDynamicColor")}, #endif // defined(OS_ANDROID) #if defined(OS_WIN)
diff --git a/chrome/browser/android/customtabs/detached_resource_request.cc b/chrome/browser/android/customtabs/detached_resource_request.cc index 0dae6aef..ea9b50b6 100644 --- a/chrome/browser/android/customtabs/detached_resource_request.cc +++ b/chrome/browser/android/customtabs/detached_resource_request.cc
@@ -134,7 +134,6 @@ static_cast<int>(blink::mojom::ResourceType::kSubResource); resource_request->do_not_prompt_for_login = true; resource_request->enable_load_timing = false; - resource_request->report_raw_headers = false; url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request), traffic_annotation);
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 24f7d51..e597ba77 100644 --- a/chrome/browser/apps/app_service/publishers/extension_apps_base.cc +++ b/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
@@ -20,6 +20,7 @@ #include "chrome/browser/apps/app_service/app_service_proxy_factory.h" #include "chrome/browser/apps/app_service/extension_uninstaller.h" #include "chrome/browser/apps/app_service/launch_utils.h" +#include "chrome/browser/apps/app_service/publishers/extension_apps_util.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_uninstall_dialog.h" #include "chrome/browser/extensions/extension_util.h" @@ -79,21 +80,6 @@ } } -extensions::UninstallReason GetUninstallReason( - apps::mojom::UninstallSource uninstall_source) { - switch (uninstall_source) { - case apps::mojom::UninstallSource::kUnknown: - NOTREACHED(); - FALLTHROUGH; - case apps::mojom::UninstallSource::kAppList: - case apps::mojom::UninstallSource::kAppManagement: - case apps::mojom::UninstallSource::kShelf: - return extensions::UNINSTALL_REASON_USER_INITIATED; - case apps::mojom::UninstallSource::kMigration: - return extensions::UNINSTALL_REASON_MIGRATED; - } -} - ash::ShelfLaunchSource ConvertLaunchSource( apps::mojom::LaunchSource launch_source) { switch (launch_source) { @@ -503,8 +489,8 @@ std::u16string error; extensions::ExtensionSystem::Get(profile()) ->extension_service() - ->UninstallExtension(app_id, GetUninstallReason(uninstall_source), - &error); + ->UninstallExtension( + app_id, GetExtensionUninstallReason(uninstall_source), &error); if (!report_abuse) { UMA_HISTOGRAM_ENUMERATION(
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_util.cc b/chrome/browser/apps/app_service/publishers/extension_apps_util.cc new file mode 100644 index 0000000..0d353b82 --- /dev/null +++ b/chrome/browser/apps/app_service/publishers/extension_apps_util.cc
@@ -0,0 +1,24 @@ +// 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/apps/app_service/publishers/extension_apps_util.h" + +namespace apps { + +extensions::UninstallReason GetExtensionUninstallReason( + apps::mojom::UninstallSource uninstall_source) { + switch (uninstall_source) { + case apps::mojom::UninstallSource::kUnknown: + // We assume if the reason is unknown that it's user inititated. + return extensions::UNINSTALL_REASON_USER_INITIATED; + case apps::mojom::UninstallSource::kAppList: + case apps::mojom::UninstallSource::kAppManagement: + case apps::mojom::UninstallSource::kShelf: + return extensions::UNINSTALL_REASON_USER_INITIATED; + case apps::mojom::UninstallSource::kMigration: + return extensions::UNINSTALL_REASON_MIGRATED; + } +} + +} // namespace apps
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_util.h b/chrome/browser/apps/app_service/publishers/extension_apps_util.h new file mode 100644 index 0000000..b53f596 --- /dev/null +++ b/chrome/browser/apps/app_service/publishers/extension_apps_util.h
@@ -0,0 +1,19 @@ +// 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_APPS_APP_SERVICE_PUBLISHERS_EXTENSION_APPS_UTIL_H_ +#define CHROME_BROWSER_APPS_APP_SERVICE_PUBLISHERS_EXTENSION_APPS_UTIL_H_ + +#include "components/services/app_service/public/mojom/types.mojom.h" +#include "extensions/browser/uninstall_reason.h" + +namespace apps { + +// Converts an apps UninstallSource to an extension uninstall reason. +extensions::UninstallReason GetExtensionUninstallReason( + apps::mojom::UninstallSource uninstall_source); + +} // namespace apps + +#endif // CHROME_BROWSER_APPS_APP_SERVICE_PUBLISHERS_EXTENSION_APPS_UTIL_H_
diff --git a/chrome/browser/apps/platform_apps/platform_app_launch.cc b/chrome/browser/apps/platform_apps/platform_app_launch.cc index ef508e4..16b0650d 100644 --- a/chrome/browser/apps/platform_apps/platform_app_launch.cc +++ b/chrome/browser/apps/platform_apps/platform_app_launch.cc
@@ -17,6 +17,14 @@ #include "extensions/common/constants.h" #include "extensions/common/extension.h" +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/web_applications/extension_status_utils.h" +#include "chrome/common/webui_url_constants.h" +#endif // defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) + namespace apps { namespace { @@ -114,6 +122,28 @@ return app_tab != nullptr; } +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) +bool OpenDeprecatedApplicationPrompt(Profile* profile, + const std::string& app_id) { + if (!extensions::IsExtensionUnsupportedDeprecatedApp(profile, app_id)) + return false; + + Browser::CreateParams create_params(profile, /*user_gesture=*/false); + Browser* browser = Browser::Create(create_params); + + NavigateParams params(browser, GURL(chrome::kChromeUIAppsURL), + ui::PAGE_TRANSITION_AUTO_TOPLEVEL); + params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + params.tabstrip_add_types = TabStripModel::ADD_ACTIVE; + Navigate(¶ms); + + browser->window()->Show(); + + // TODO(crbug.com/1225779): Show the deprecated apps dialog. + return true; +} +#endif // defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) + bool OpenExtensionApplicationWithReenablePrompt( Profile* profile, const std::string& app_id,
diff --git a/chrome/browser/apps/platform_apps/platform_app_launch.h b/chrome/browser/apps/platform_apps/platform_app_launch.h index 5381782..66e74df 100644 --- a/chrome/browser/apps/platform_apps/platform_app_launch.h +++ b/chrome/browser/apps/platform_apps/platform_app_launch.h
@@ -7,6 +7,8 @@ #include <string> +#include "build/build_config.h" + class GURL; class Profile; @@ -34,6 +36,14 @@ // and false otherwise. bool OpenExtensionApplicationTab(Profile* profile, const std::string& app_id); +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) +// Opens the deprecated Chrome Apps flow if |app_id| refers to a Chrome App and +// Chrome Apps are deprecated on the |profile|. Returns true if that was the +// case, or false otherwise. +bool OpenDeprecatedApplicationPrompt(Profile* profile, + const std::string& app_id); +#endif + // Tries to open |app_id|, and prompts the user if the app is disabled. Returns // true if the app was successfully opened and false otherwise. // Handles the case If |app_id| is a disabled or terminated platform app.
diff --git a/chrome/browser/ash/accessibility/accessibility_manager.cc b/chrome/browser/ash/accessibility/accessibility_manager.cc index 9806b78e..bc9c306f 100644 --- a/chrome/browser/ash/accessibility/accessibility_manager.cc +++ b/chrome/browser/ash/accessibility/accessibility_manager.cc
@@ -60,6 +60,7 @@ #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" #include "chrome/grit/browser_resources.h" +#include "chrome/grit/generated_resources.h" #include "chromeos/dbus/power/power_manager_client.h" #include "chromeos/dbus/upstart/upstart_client.h" #include "components/language/core/browser/pref_names.h" @@ -89,6 +90,7 @@ #include "ui/accessibility/ax_enum_util.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/base/ime/chromeos/extension_ime_util.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/widget_observer.h" @@ -874,7 +876,8 @@ locale); } - if (triggered_by_user && !enabled) { + if (triggered_by_user && !enabled && + features::IsDictationOfflineAvailableAndEnabled()) { // Note: This should not be called at start-up or it will // push back SODA deletion each time start-up occurs with dictation // disabled. @@ -883,10 +886,16 @@ } if (enabled) { + const std::string locale = + profile_->GetPrefs()->GetString(prefs::kAccessibilityDictationLocale); + if (triggered_by_user && ShouldShowNetworkDictationDialog(locale)) { + // Only show the Dictation dialog if Dictation was enabled by the user. + ShowNetworkDictationDialog(); + } + // TODO(crbug.com/1173135): Call MaybeInstallSoda when the dictation locale // pref changes. - MaybeInstallSoda( - profile_->GetPrefs()->GetString(prefs::kAccessibilityDictationLocale)); + MaybeInstallSoda(locale); } } @@ -1850,12 +1859,57 @@ extension_misc::kChromeVoxExtensionId, std::move(event)); } -void AccessibilityManager::MaybeInstallSoda(const std::string& locale) { - if (!::features::IsExperimentalAccessibilityDictationOfflineEnabled()) - return; +bool AccessibilityManager::ShouldShowNetworkDictationDialog( + const std::string& locale) { + if (profile_->GetPrefs()->GetBoolean( + prefs::kDictationAcceleratorDialogHasBeenAccepted)) { + return false; + } - // TODO(crbug.com/1173135): Check whether SODA is available on this device by - // checking (IsEnabled(ash::features::kOnDeviceSpeechRecognition)). + if (!features::IsDictationOfflineAvailableAndEnabled()) + return true; + + speech::SodaInstaller* soda_installer = speech::SodaInstaller::GetInstance(); + std::vector<std::string> supported_languages = + soda_installer->GetAvailableLanguages(); + if (std::find(supported_languages.begin(), supported_languages.end(), + locale) == supported_languages.end()) { + // Show the dialog for languages not supported by SODA. + return true; + } + + return false; +} + +void AccessibilityManager::ShowNetworkDictationDialog() { + const std::u16string title = + l10n_util::GetStringUTF16(IDS_ACCESSIBILITY_DICTATION_CONFIRMATION_TITLE); + const std::u16string text = + l10n_util::GetStringUTF16(IDS_ACCESSIBILITY_DICTATION_CONFIRMATION_TEXT); + AccessibilityController::Get()->ShowConfirmationDialog( + title, text, + base::BindOnce(&AccessibilityManager::OnNetworkDictationDialogAccepted, + base::Unretained(this)), + base::BindOnce(&AccessibilityManager::OnNetworkDictationDialogDismissed, + base::Unretained(this)), + base::BindOnce(&AccessibilityManager::OnNetworkDictationDialogDismissed, + base::Unretained(this))); +} + +void AccessibilityManager::OnNetworkDictationDialogAccepted() { + profile_->GetPrefs()->SetBoolean( + prefs::kDictationAcceleratorDialogHasBeenAccepted, true); +} + +void AccessibilityManager::OnNetworkDictationDialogDismissed() { + SetDictationEnabled(false); +} + +void AccessibilityManager::MaybeInstallSoda(const std::string& locale) { + if (!features::IsDictationOfflineAvailableAndEnabled()) { + return; + } + speech::SodaInstaller* soda_installer = speech::SodaInstaller::GetInstance(); if (soda_installer->IsSodaInstalled(speech::GetLanguageCode(locale)) || soda_installer->IsSodaDownloading(speech::GetLanguageCode(locale)))
diff --git a/chrome/browser/ash/accessibility/accessibility_manager.h b/chrome/browser/ash/accessibility/accessibility_manager.h index 68301013..3cad4c1 100644 --- a/chrome/browser/ash/accessibility/accessibility_manager.h +++ b/chrome/browser/ash/accessibility/accessibility_manager.h
@@ -460,6 +460,10 @@ // ProfileObserver: void OnProfileWillBeDestroyed(Profile* profile) override; + bool ShouldShowNetworkDictationDialog(const std::string& locale); + void ShowNetworkDictationDialog(); + void OnNetworkDictationDialogAccepted(); + void OnNetworkDictationDialogDismissed(); void MaybeInstallSoda(const std::string& locale); // Profile which has the current a11y context. @@ -544,6 +548,8 @@ friend class DictationTest; friend class SwitchAccessTest; friend class AccessibilityManagerTest; + friend class AccessibilityManagerDictationDialogTest; + friend class AccessibilityManagerNoOnDeviceSpeechRecognitionTest; DISALLOW_COPY_AND_ASSIGN(AccessibilityManager); };
diff --git a/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc b/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc index 1cb878a6..bfb72011 100644 --- a/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc +++ b/chrome/browser/ash/accessibility/accessibility_manager_browsertest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ash/accessibility/accessibility_manager.h" +#include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/test/accessibility_controller_test_api.h" #include "base/bind.h" @@ -39,6 +40,7 @@ #include "ui/base/ime/chromeos/component_extension_ime_manager.h" #include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/ime/chromeos/input_method_manager.h" +#include "ui/base/ui_base_switches.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" namespace extension_ime_util = chromeos::extension_ime_util; @@ -283,12 +285,20 @@ void SetUpOnMainThread() override { default_autoclick_delay_ = GetAutoclickDelay(); + // For general AccessibilityManagerTests, pretend that the Dictation + // confirmation dialog has been accepted so that it doesn't interfere with + // tests. There is a dedicated test suite to exercise the logic for the + // dialog. + GetActiveUserPrefs()->SetBoolean( + prefs::kDictationAcceleratorDialogHasBeenAccepted, true); MixinBasedInProcessBrowserTest::SetUpOnMainThread(); } void SetUpCommandLine(base::CommandLine* command_line) override { - scoped_feature_list_.InitAndEnableFeature( - features::kExperimentalAccessibilityDictationOffline); + scoped_feature_list_.InitWithFeatures( + {::features::kExperimentalAccessibilityDictationOffline, + ash::features::kOnDeviceSpeechRecognition}, + {}); MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line); } @@ -299,6 +309,11 @@ const AccountId test_account_id_ = AccountId::FromUserEmailGaiaId(kTestUserName, kTestUserGaiaId); + bool ShouldShowNetworkDictationDialog(const std::string& locale) { + return AccessibilityManager::Get()->ShouldShowNetworkDictationDialog( + locale); + } + private: ui::ScopedAnimationDurationScaleMode disable_animations_; base::test::ScopedFeatureList scoped_feature_list_; @@ -623,6 +638,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, SodaDownload) { UninstallSodaForTesting(); EXPECT_FALSE(IsSodaDownloading()); + EXPECT_FALSE(ShouldShowNetworkDictationDialog("en-US")); SetDictationEnabled(true); EXPECT_TRUE(IsSodaDownloading()); speech::SodaInstaller::GetInstance()->NotifySodaInstalledForTesting(); @@ -633,6 +649,7 @@ IN_PROC_BROWSER_TEST_F(AccessibilityManagerTest, SodaError) { UninstallSodaForTesting(); EXPECT_FALSE(IsSodaDownloading()); + EXPECT_FALSE(ShouldShowNetworkDictationDialog("en-US")); SetDictationEnabled(true); EXPECT_TRUE(IsSodaDownloading()); speech::SodaInstaller::GetInstance()->NotifySodaErrorForTesting(); @@ -640,6 +657,159 @@ UninstallSodaForTesting(); } +class AccessibilityManagerDictationDialogTest + : public AccessibilityManagerTest { + protected: + AccessibilityManagerDictationDialogTest() + : disable_animations_( + ui::ScopedAnimationDurationScaleMode::ZERO_DURATION) {} + ~AccessibilityManagerDictationDialogTest() override = default; + AccessibilityManagerDictationDialogTest( + const AccessibilityManagerDictationDialogTest&) = delete; + AccessibilityManagerDictationDialogTest& operator=( + const AccessibilityManagerDictationDialogTest&) = delete; + + void SetUpOnMainThread() override { + // Ensure the dialog has not been accepted yet. + GetActiveUserPrefs()->SetBoolean( + prefs::kDictationAcceleratorDialogHasBeenAccepted, false); + MixinBasedInProcessBrowserTest::SetUpOnMainThread(); + } + + void SetUpCommandLine(base::CommandLine* command_line) override { + // Set the device language to one that is not supported by SODA on Chrome + // OS. This will force Dictation to show the confirmation dialog when + // enabled. + locale_ = "it-IT"; + command_line->AppendSwitchASCII(::switches::kLang, locale_); + AccessibilityManagerTest::SetUpCommandLine(command_line); + } + + std::string locale() { return locale_; } + + void AcceptDialog() { + AccessibilityManager::Get()->OnNetworkDictationDialogAccepted(); + } + + void DismissDialog() { + AccessibilityManager::Get()->OnNetworkDictationDialogDismissed(); + } + + private: + std::string locale_; + ui::ScopedAnimationDurationScaleMode disable_animations_; +}; + +IN_PROC_BROWSER_TEST_F(AccessibilityManagerDictationDialogTest, + ShouldShowNetworkDictationDialog) { + // The dialog should be shown for languages not supported by SODA. Currently, + // the only supported language is English. + EXPECT_FALSE(ShouldShowNetworkDictationDialog("en-US")); + EXPECT_TRUE(ShouldShowNetworkDictationDialog("")); + EXPECT_TRUE(ShouldShowNetworkDictationDialog("fr-FR")); + EXPECT_TRUE(ShouldShowNetworkDictationDialog("ja-JP")); + + PrefService* prefs = GetActiveUserPrefs(); + prefs->SetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted, true); + // If we have already shown the dialog, then we never need to do so again. + EXPECT_FALSE(ShouldShowNetworkDictationDialog("fr-FR")); +} + +IN_PROC_BROWSER_TEST_F(AccessibilityManagerDictationDialogTest, DismissDialog) { + PrefService* prefs = GetActiveUserPrefs(); + EXPECT_FALSE( + prefs->GetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted)); + EXPECT_TRUE(ShouldShowNetworkDictationDialog(locale())); + + SetDictationEnabled(true); + EXPECT_TRUE(IsDictationEnabled()); + + // Dismissing the dialog should turn Dictation off. + DismissDialog(); + EXPECT_FALSE(IsDictationEnabled()); + EXPECT_FALSE( + prefs->GetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted)); + EXPECT_TRUE(ShouldShowNetworkDictationDialog(locale())); +} + +IN_PROC_BROWSER_TEST_F(AccessibilityManagerDictationDialogTest, AcceptDialog) { + PrefService* prefs = GetActiveUserPrefs(); + EXPECT_FALSE( + prefs->GetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted)); + EXPECT_TRUE(ShouldShowNetworkDictationDialog(locale())); + + SetDictationEnabled(true); + EXPECT_TRUE(IsDictationEnabled()); + EXPECT_FALSE( + prefs->GetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted)); + + // Accepting the dialog should keep Dictation on and change the pref that + // tracks whether or not the dialog has been accepted. + AcceptDialog(); + EXPECT_TRUE(IsDictationEnabled()); + EXPECT_TRUE( + prefs->GetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted)); + EXPECT_FALSE(ShouldShowNetworkDictationDialog(locale())); +} + +IN_PROC_BROWSER_TEST_F(AccessibilityManagerDictationDialogTest, + DialogNotShownAfterAccepted) { + PrefService* prefs = GetActiveUserPrefs(); + // Pretend that the dialog was already accepted. + AcceptDialog(); + EXPECT_TRUE( + prefs->GetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted)); + EXPECT_FALSE(ShouldShowNetworkDictationDialog(locale())); + + // Once the dialog has been accepted, we should not show it again. + SetDictationEnabled(true); + EXPECT_TRUE(IsDictationEnabled()); + EXPECT_TRUE( + prefs->GetBoolean(prefs::kDictationAcceleratorDialogHasBeenAccepted)); + EXPECT_FALSE(ShouldShowNetworkDictationDialog(locale())); +} + +class AccessibilityManagerNoOnDeviceSpeechRecognitionTest + : public MixinBasedInProcessBrowserTest { + protected: + AccessibilityManagerNoOnDeviceSpeechRecognitionTest() + : disable_animations_( + ui::ScopedAnimationDurationScaleMode::ZERO_DURATION) {} + ~AccessibilityManagerNoOnDeviceSpeechRecognitionTest() override = default; + AccessibilityManagerNoOnDeviceSpeechRecognitionTest( + const AccessibilityManagerNoOnDeviceSpeechRecognitionTest&) = delete; + AccessibilityManagerNoOnDeviceSpeechRecognitionTest& operator=( + const AccessibilityManagerNoOnDeviceSpeechRecognitionTest&) = delete; + + void SetUpCommandLine(base::CommandLine* command_line) override { + std::vector<base::Feature> enabled_features = { + ::features::kExperimentalAccessibilityDictationOffline}; + // Disable on-device speech recognition. + std::vector<base::Feature> disabled_features = { + ash::features::kOnDeviceSpeechRecognition}; + scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features); + MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line); + } + + bool ShouldShowNetworkDictationDialog(const std::string& locale) { + return AccessibilityManager::Get()->ShouldShowNetworkDictationDialog( + locale); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + ui::ScopedAnimationDurationScaleMode disable_animations_; +}; + +IN_PROC_BROWSER_TEST_F(AccessibilityManagerNoOnDeviceSpeechRecognitionTest, + ShouldShowNetworkDictationDialog) { + // The dialog should be shown for all languages if SODA is unavailable. + EXPECT_TRUE(ShouldShowNetworkDictationDialog("en-US")); + EXPECT_TRUE(ShouldShowNetworkDictationDialog("")); + EXPECT_TRUE(ShouldShowNetworkDictationDialog("fr-FR")); + EXPECT_TRUE(ShouldShowNetworkDictationDialog("ja-JP")); +} + // For signin screen to user session accessibility manager tests. class AccessibilityManagerLoginTest : public OobeBaseTest { protected:
diff --git a/chrome/browser/ash/accessibility/dictation.cc b/chrome/browser/ash/accessibility/dictation.cc index 857deed..df6efd3 100644 --- a/chrome/browser/ash/accessibility/dictation.cc +++ b/chrome/browser/ash/accessibility/dictation.cc
@@ -213,7 +213,7 @@ // By default these languages are not supported offline. supported_locales[locale] = false; } - if (features::IsExperimentalAccessibilityDictationOfflineEnabled()) { + if (features::IsDictationOfflineAvailableAndEnabled()) { std::vector<std::string> offline_languages = speech::SodaInstaller::GetInstance()->GetAvailableLanguages(); for (auto language : offline_languages) { @@ -267,16 +267,16 @@ base::UmaHistogramSparse("Accessibility.CrosDictation.Language", base::HashMetricName(locale)); - speech::SodaInstaller* soda_installer = speech::SodaInstaller::GetInstance(); - if (features::IsExperimentalAccessibilityDictationOfflineEnabled() && - (soda_installer->IsSodaDownloading(speech::GetLanguageCode(locale)))) { + if (features::IsDictationOfflineAvailableAndEnabled() && + speech::SodaInstaller::GetInstance()->IsSodaDownloading( + speech::GetLanguageCode(locale))) { // Don't allow Dictation to be used while SODA is downloading. audio::SoundsManager::Get()->Play( static_cast<int>(Sound::kDictationCancel)); return false; } - if (features::IsExperimentalAccessibilityDictationOfflineEnabled() && + if (features::IsDictationOfflineAvailableAndEnabled() && OnDeviceSpeechRecognizer::IsOnDeviceSpeechRecognizerAvailable(locale)) { // On-device recognition is behind a flag and then only available if // SODA is installed on-device.
diff --git a/chrome/browser/ash/accessibility/dictation_browsertest.cc b/chrome/browser/ash/accessibility/dictation_browsertest.cc index 2d514b74..18669879 100644 --- a/chrome/browser/ash/accessibility/dictation_browsertest.cc +++ b/chrome/browser/ash/accessibility/dictation_browsertest.cc
@@ -7,14 +7,18 @@ #include <memory> #include "ash/accessibility/accessibility_controller_impl.h" +#include "ash/constants/ash_features.h" +#include "ash/constants/ash_pref_names.h" #include "ash/shell.h" #include "base/strings/utf_string_conversions.h" #include "base/timer/timer.h" #include "chrome/browser/ash/accessibility/accessibility_manager.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/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.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_test.h" @@ -41,6 +45,10 @@ const int kShortNoSpeechTimeoutInSeconds = 5; const int kVeryShortNoSpeechTimeoutInSeconds = 2; +PrefService* GetActiveUserPrefs() { + return ProfileManager::GetActiveUserProfile()->GetPrefs(); +} + } // namespace enum DictationListeningTestVariant { @@ -89,17 +97,19 @@ std::vector<base::Feature> disabled_features; if (GetParam().first == kTestWithLongerListening) { enabled_features.push_back( - features::kExperimentalAccessibilityDictationListening); + ::features::kExperimentalAccessibilityDictationListening); } else { disabled_features.push_back( - features::kExperimentalAccessibilityDictationListening); + ::features::kExperimentalAccessibilityDictationListening); } if (GetParam().second == kOnDeviceRecognition) { enabled_features.push_back( - features::kExperimentalAccessibilityDictationOffline); + ::features::kExperimentalAccessibilityDictationOffline); + enabled_features.push_back(ash::features::kOnDeviceSpeechRecognition); } else { disabled_features.push_back( - features::kExperimentalAccessibilityDictationOffline); + ::features::kExperimentalAccessibilityDictationOffline); + disabled_features.push_back(ash::features::kOnDeviceSpeechRecognition); } scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features); } @@ -110,15 +120,15 @@ // initializes (which is when the global SodaInstaller gets created). // Lastly, do this before Dictation is enabled so that we don't initiate a // SODA download when Dictation is enabled. - speech::SodaInstaller::GetInstance()->NotifySodaInstalledForTesting(); + if (GetParam().second == kOnDeviceRecognition) { + speech::SodaInstaller::GetInstance()->NotifySodaInstalledForTesting(); + } ui::IMEBridge::Get()->SetInputContextHandler(input_context_handler_.get()); generator_ = std::make_unique<ui::test::EventGenerator>( ash::Shell::Get()->GetPrimaryRootWindow()); - ash::Shell::Get() - ->accessibility_controller() - ->dictation() - .SetDialogAccepted(); + GetActiveUserPrefs()->SetBoolean( + prefs::kDictationAcceleratorDialogHasBeenAccepted, true); ash::Shell::Get()->accessibility_controller()->dictation().SetEnabled(true); if (GetParam().second == kOnDeviceRecognition) { // Replaces normal CrosSpeechRecognitionService with a fake one.
diff --git a/chrome/browser/ash/crosapi/BUILD.gn b/chrome/browser/ash/crosapi/BUILD.gn index eba3ff6c..75d28c6 100644 --- a/chrome/browser/ash/crosapi/BUILD.gn +++ b/chrome/browser/ash/crosapi/BUILD.gn
@@ -164,6 +164,7 @@ "browser_loader_unittest.cc", "browser_manager_unittest.cc", "browser_util_unittest.cc", + "download_controller_ash_unittest.cc", "keystore_service_ash_unittest.cc", "local_printer_ash_unittest.cc", "message_center_ash_unittest.cc",
diff --git a/chrome/browser/ash/crosapi/download_controller_ash.cc b/chrome/browser/ash/crosapi/download_controller_ash.cc index 0212e638..095dae2 100644 --- a/chrome/browser/ash/crosapi/download_controller_ash.cc +++ b/chrome/browser/ash/crosapi/download_controller_ash.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ash/crosapi/download_controller_ash.h" +#include "mojo/public/cpp/bindings/callback_helpers.h" + namespace crosapi { DownloadControllerAsh::DownloadControllerAsh() = default; @@ -46,6 +48,59 @@ observers_.RemoveObserver(observer); } +void DownloadControllerAsh::GetAllDownloads( + mojom::DownloadControllerClient::GetAllDownloadsCallback callback) { + if (clients_.empty()) { + std::move(callback).Run({}); + return; + } + + // This callback will be invoked by each Lacros client to aggregate all + // downloads, sort them chronologically by start time, and ultimately provide + // them to the original `callback`. + auto aggregating_downloads_callback = base::BindRepeating( + [](mojom::DownloadControllerClient::GetAllDownloadsCallback& callback, + size_t& num_clients_still_working, + std::vector<mojom::DownloadItemPtr>& aggregated_downloads, + std::vector<mojom::DownloadItemPtr> client_downloads) { + DCHECK_GT(num_clients_still_working, 0u); + + // Aggregate downloads from each Lacros client. + for (auto& download : client_downloads) + aggregated_downloads.push_back(std::move(download)); + + --num_clients_still_working; + if (num_clients_still_working != 0u) + return; + + // Sort aggregated downloads chronologically by start time. + std::sort(aggregated_downloads.begin(), aggregated_downloads.end(), + [](const auto& a, const auto& b) { + return a->start_time.value_or(base::Time()) < + b->start_time.value_or(base::Time()); + }); + + std::move(callback).Run(std::move(aggregated_downloads)); + }, + base::OwnedRef(std::move(callback)), + base::OwnedRef(size_t(clients_.size())), + base::OwnedRef(std::vector<mojom::DownloadItemPtr>())); + + // Aggregate downloads from each Lacros `client`. Note that if the `client` is + // not of a supported `version` or if the connection is dropped before the + // `client` returns a response, it will not contribute any downloads. + for (auto& client : clients_) { + const uint32_t version = client.version(); + if (mojom::DownloadControllerClient::kGetAllDownloadsMinVersion > version) { + aggregating_downloads_callback.Run(std::vector<mojom::DownloadItemPtr>()); + continue; + } + client->GetAllDownloads(mojo::WrapCallbackWithDefaultInvokeIfNotRun( + base::BindOnce(aggregating_downloads_callback), + /*default_invoke_args=*/std::vector<mojom::DownloadItemPtr>())); + } +} + void DownloadControllerAsh::Pause(const std::string& download_guid) { for (auto& client : clients_) client->Pause(download_guid);
diff --git a/chrome/browser/ash/crosapi/download_controller_ash.h b/chrome/browser/ash/crosapi/download_controller_ash.h index 506885d..43e4a42 100644 --- a/chrome/browser/ash/crosapi/download_controller_ash.h +++ b/chrome/browser/ash/crosapi/download_controller_ash.h
@@ -48,6 +48,12 @@ void AddObserver(DownloadControllerObserver* observer); void RemoveObserver(DownloadControllerObserver* observer); + // Asynchronously returns all downloads from each Lacros client via the + // specified `callback`, no matter the type or state. Downloads are sorted + // chronologically by start time. + void GetAllDownloads( + mojom::DownloadControllerClient::GetAllDownloadsCallback callback); + // Pauses the download associated with the specified `download_guid`. This // method will ultimately invoke `download::DownloadItem::Pause()`. void Pause(const std::string& download_guid);
diff --git a/chrome/browser/ash/crosapi/download_controller_ash_unittest.cc b/chrome/browser/ash/crosapi/download_controller_ash_unittest.cc new file mode 100644 index 0000000..6d6acc2 --- /dev/null +++ b/chrome/browser/ash/crosapi/download_controller_ash_unittest.cc
@@ -0,0 +1,138 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/crosapi/download_controller_ash.h" + +#include <string> +#include <vector> + +#include "base/run_loop.h" +#include "base/test/bind.h" +#include "base/test/task_environment.h" +#include "chromeos/crosapi/mojom/download_controller.mojom.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace crosapi { + +// Helpers --------------------------------------------------------------------- + +mojom::DownloadItemPtr CreateDownloadItemWithStartTimeOffset( + base::TimeDelta start_time_offset) { + auto download = mojom::DownloadItem::New(); + download->start_time = base::Time::Now() + start_time_offset; + return download; +} + +bool IsSortedChronologicallyByStartTime( + const std::vector<mojom::DownloadItemPtr>& downloads) { + for (size_t i = 1; i < downloads.size(); ++i) { + if (downloads[i]->start_time.value_or(base::Time()) < + downloads[i - 1]->start_time.value_or(base::Time())) { + return false; + } + } + return true; +} + +// Mocks ----------------------------------------------------------------------- + +class MockDownloadControllerClient : public mojom::DownloadControllerClient { + public: + MOCK_METHOD(void, + GetAllDownloads, + (mojom::DownloadControllerClient::GetAllDownloadsCallback), + (override)); + MOCK_METHOD(void, Pause, (const std::string& download_guid), (override)); + MOCK_METHOD(void, + Resume, + (const std::string& download_guid, bool user_resume), + (override)); + MOCK_METHOD(void, + Cancel, + (const std::string& download_guid, bool user_cancel), + (override)); + MOCK_METHOD(void, + SetOpenWhenComplete, + (const std::string& download_guid, bool open_when_complete), + (override)); +}; + +// DownloadControllerAshTest --------------------------------------------------- + +class DownloadControllerAshTest : public testing::Test { + public: + DownloadControllerAsh* download_controller_ash() { + return &download_controller_ash_; + } + + private: + base::test::SingleThreadTaskEnvironment task_environment_; + DownloadControllerAsh download_controller_ash_; +}; + +// Tests ----------------------------------------------------------------------- + +TEST_F(DownloadControllerAshTest, GetAllDownloads_NoBoundClients) { + // Invoke `GetAllDownloads()` with no clients bound. + base::RunLoop run_loop; + download_controller_ash()->GetAllDownloads(base::BindLambdaForTesting( + [&](std::vector<mojom::DownloadItemPtr> downloads) { + EXPECT_EQ(downloads.size(), 0u); + run_loop.Quit(); + })); + run_loop.Run(); +} + +TEST_F(DownloadControllerAshTest, GetAllDownloads_MultipleBoundClients) { + // Bind `client1`. + testing::NiceMock<MockDownloadControllerClient> client1; + mojo::Receiver<mojom::DownloadControllerClient> client1_receiver{&client1}; + download_controller_ash()->BindClient( + client1_receiver.BindNewPipeAndPassRemoteWithVersion()); + + // Mock `client1` response for `GetAllDownloads()`. + EXPECT_CALL(client1, GetAllDownloads) + .WillOnce(testing::Invoke( + [](mojom::DownloadControllerClient::GetAllDownloadsCallback + callback) { + std::vector<mojom::DownloadItemPtr> downloads; + downloads.push_back(CreateDownloadItemWithStartTimeOffset( + base::TimeDelta::FromMinutes(10))); + downloads.push_back(CreateDownloadItemWithStartTimeOffset( + -base::TimeDelta::FromMinutes(10))); + std::move(callback).Run(std::move(downloads)); + })); + + // Bind `client2`. + testing::NiceMock<MockDownloadControllerClient> client2; + mojo::Receiver<mojom::DownloadControllerClient> client2_receiver{&client2}; + download_controller_ash()->BindClient( + client2_receiver.BindNewPipeAndPassRemoteWithVersion()); + + // Mock `client2` response for `GetAllDownloads()`. + EXPECT_CALL(client2, GetAllDownloads) + .WillOnce(testing::Invoke( + [](mojom::DownloadControllerClient::GetAllDownloadsCallback + callback) { + std::vector<mojom::DownloadItemPtr> downloads; + downloads.push_back(CreateDownloadItemWithStartTimeOffset( + base::TimeDelta::FromMinutes(20))); + downloads.push_back(CreateDownloadItemWithStartTimeOffset( + -base::TimeDelta::FromMinutes(20))); + std::move(callback).Run(std::move(downloads)); + })); + + // Invoke `GetAllDownloads()`. + base::RunLoop run_loop; + download_controller_ash()->GetAllDownloads(base::BindLambdaForTesting( + [&](std::vector<mojom::DownloadItemPtr> downloads) { + EXPECT_EQ(downloads.size(), 4u); + EXPECT_TRUE(IsSortedChronologicallyByStartTime(downloads)); + run_loop.Quit(); + })); + run_loop.Run(); +} + +} // namespace crosapi
diff --git a/chrome/browser/ash/file_manager/path_util.cc b/chrome/browser/ash/file_manager/path_util.cc index 7905b2f..8aa13298 100644 --- a/chrome/browser/ash/file_manager/path_util.cc +++ b/chrome/browser/ash/file_manager/path_util.cc
@@ -61,10 +61,14 @@ constexpr char kCrostiniMapPlayFiles[] = "PlayFiles"; constexpr char kCrostiniMapSmbFs[] = "SMB"; constexpr char kCrostiniMapTeamDrives[] = "SharedDrives"; +constexpr char kCrostiniMapSharedWithMe[] = "SharedWithMe"; +constexpr char kCrostiniMapShortcutsSharedWithMe[] = "ShortcutsSharedWithMe"; constexpr char kFolderNameDownloads[] = "Downloads"; constexpr char kFolderNameMyFiles[] = "MyFiles"; constexpr char kDisplayNameGoogleDrive[] = "Google Drive"; constexpr char kDriveFsDirComputers[] = "Computers"; +constexpr char kDriveFsDirSharedWithMe[] = ".files-by-id"; +constexpr char kDriveFsDirShortcutsSharedWithMe[] = ".shortcut-targets-by-id"; constexpr char kDriveFsDirRoot[] = "root"; constexpr char kDriveFsDirTeamDrives[] = "team_drives"; @@ -414,6 +418,17 @@ // team_drives -> SharedDrives. base_to_exclude = base_to_exclude.Append(kDriveFsDirTeamDrives); *inside = inside->Append(kCrostiniMapTeamDrives); + } else if (components.size() >= 2 && + components[1] == kDriveFsDirSharedWithMe) { + // .files-by-id -> SharedWithMe. + base_to_exclude = base_to_exclude.Append(kDriveFsDirSharedWithMe); + *inside = inside->Append(kCrostiniMapSharedWithMe); + } else if (components.size() >= 2 && + components[1] == kDriveFsDirShortcutsSharedWithMe) { + // .shortcut-targets-by-id -> ShortcutsSharedWithMe. + base_to_exclude = + base_to_exclude.Append(kDriveFsDirShortcutsSharedWithMe); + *inside = inside->Append(kCrostiniMapShortcutsSharedWithMe); } // Computers -> Computers } else if (id == chromeos::kSystemMountNameRemovable) { @@ -517,12 +532,22 @@ // GoogleDrive if (AppendRelativePath(base::FilePath(kCrostiniMapMyDrive), path, &relative_path)) { - // Special mapping for /GoogleDrive/MyDrive -> root + // /GoogleDrive/MyDrive -> root path = base::FilePath(kDriveFsDirRoot).Append(relative_path); } else if (AppendRelativePath(base::FilePath(kCrostiniMapTeamDrives), path, &relative_path)) { - // Special mapping for /GoogleDrive/SharedDrive -> team_drives + // /GoogleDrive/SharedDrive -> team_drives path = base::FilePath(kDriveFsDirTeamDrives).Append(relative_path); + } else if (AppendRelativePath(base::FilePath(kCrostiniMapSharedWithMe), + path, &relative_path)) { + // /GoogleDrive/SharedWithMe -> .files-by-id + path = base::FilePath(kDriveFsDirSharedWithMe).Append(relative_path); + } else if (AppendRelativePath( + base::FilePath(kCrostiniMapShortcutsSharedWithMe), path, + &relative_path)) { + // /GoogleDrive/ShortcutsSharedWithMe -> .shortcut-targets-by-id + path = base::FilePath(kDriveFsDirShortcutsSharedWithMe) + .Append(relative_path); } // Computers -> Computers } else if (base::FilePath(chromeos::kSystemMountNameRemovable) @@ -810,6 +835,28 @@ .Append(l10n_util::GetStringUTF8( IDS_FILE_BROWSER_DRIVE_COMPUTERS_LABEL)) .value())) { + } else if ( + drive_integration_service && + ReplacePrefix( + &result, + drive_integration_service->GetMountPointPath() + .Append(kDriveFsDirSharedWithMe) + .value(), + base::FilePath(kDisplayNameGoogleDrive) + .Append(l10n_util::GetStringUTF8( + IDS_FILE_BROWSER_DRIVE_SHARED_WITH_ME_COLLECTION_LABEL)) + .value())) { + } else if ( + drive_integration_service && + ReplacePrefix( + &result, + drive_integration_service->GetMountPointPath() + .Append(kDriveFsDirShortcutsSharedWithMe) + .value(), + base::FilePath(kDisplayNameGoogleDrive) + .Append(l10n_util::GetStringUTF8( + IDS_FILE_BROWSER_DRIVE_SHARED_WITH_ME_COLLECTION_LABEL)) + .value())) { } else if (ReplacePrefix(&result, kAndroidFilesPath, l10n_util::GetStringUTF8( IDS_FILE_BROWSER_ANDROID_FILES_ROOT_LABEL))) {
diff --git a/chrome/browser/ash/file_manager/path_util_unittest.cc b/chrome/browser/ash/file_manager/path_util_unittest.cc index f5e27f0..71a25097 100644 --- a/chrome/browser/ash/file_manager/path_util_unittest.cc +++ b/chrome/browser/ash/file_manager/path_util_unittest.cc
@@ -175,6 +175,17 @@ &profile2, "/media/fuse/drivefs-84675c855b63e12f384d45f033826980/" "Computers/My Other Computer/bar")); + EXPECT_EQ("Google Drive \u203a Shared with me \u203a 1234 \u203a shared", + GetPathDisplayTextForSettings( + &profile2, + "/media/fuse/drivefs-84675c855b63e12f384d45f033826980/" + ".files-by-id/1234/shared")); + EXPECT_EQ( + "Google Drive \u203a Shared with me \u203a 1-abc-xyz \u203a shortcut", + GetPathDisplayTextForSettings( + &profile2, + "/media/fuse/drivefs-84675c855b63e12f384d45f033826980/" + ".shortcut-targets-by-id/1-abc-xyz/shortcut")); EXPECT_EQ("Google Drive \u203a My Drive \u203a foo", GetPathDisplayTextForSettings(&profile2, "${google_drive}/foo")); @@ -411,6 +422,11 @@ "/mnt/chromeos/GoogleDrive/Computers/path/in/computers", }, { + "drivefs-84675c855b63e12f384d45f033826980", + ".files-by-id/1234/shared", + "/mnt/chromeos/GoogleDrive/SharedWithMe/1234/shared", + }, + { "removable", "MyUSB/path/in/removable", "/mnt/chromeos/removable/MyUSB/path/in/removable",
diff --git a/chrome/browser/ash/guest_os/guest_os_share_path.cc b/chrome/browser/ash/guest_os/guest_os_share_path.cc index 9ad0a44..09c6aef 100644 --- a/chrome/browser/ash/guest_os/guest_os_share_path.cc +++ b/chrome/browser/ash/guest_os/guest_os_share_path.cc
@@ -269,6 +269,8 @@ base::FilePath root("root"); base::FilePath team_drives("team_drives"); base::FilePath computers("Computers"); + base::FilePath files_by_id(".files-by-id"); + base::FilePath shortcut_targets_by_id(".shortcut-targets-by-id"); base::FilePath trash(".Trash"); // Not to be shared! if (AppendRelativePath(root, drivefs_path, &relative_path)) { // My Drive and subdirs. @@ -293,6 +295,17 @@ if (components.size() < 2) { allowed_path = false; } + } else if (AppendRelativePath(files_by_id, drivefs_path, &relative_path)) { + // Shared (.files-by-id) and subdirs. + allowed_path = true; + request.set_storage_location( + vm_tools::seneschal::SharePathRequest::DRIVEFS_FILES_BY_ID); + } else if (AppendRelativePath(shortcut_targets_by_id, drivefs_path, + &relative_path)) { + // Shared (.shortcut-targets-by-id) and subdirs. + allowed_path = true; + request.set_storage_location(vm_tools::seneschal::SharePathRequest:: + DRIVEFS_SHORTCUT_TARGETS_BY_ID); } else if (trash == drivefs_path || trash.IsParent(drivefs_path)) { // Note: Do not expose .Trash which would allow linux apps to make // permanent deletes from Drive. This branch is not especially required,
diff --git a/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc b/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc index 9769fe2..c1fd41b 100644 --- a/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc +++ b/chrome/browser/ash/guest_os/guest_os_share_path_unittest.cc
@@ -528,6 +528,32 @@ run_loop()->Run(); } +TEST_F(GuestOsSharePathTest, SuccessDriveFsFilesById) { + SetUpVolume(); + guest_os_share_path_->SharePath( + "vm-running", drivefs_.Append(".files-by-id/1234/shared"), PERSIST_NO, + base::BindOnce( + &GuestOsSharePathTest::SharePathCallback, base::Unretained(this), + "vm-running", Persist::NO, SeneschalClientCalled::YES, + &vm_tools::seneschal::SharePathRequest::DRIVEFS_FILES_BY_ID, + "1234/shared", Success::YES, "")); + run_loop()->Run(); +} + +TEST_F(GuestOsSharePathTest, SuccessDriveFsShortcutTargetsById) { + SetUpVolume(); + guest_os_share_path_->SharePath( + "vm-running", + drivefs_.Append(".shortcut-targets-by-id/1-abc-xyz/shortcut"), PERSIST_NO, + base::BindOnce(&GuestOsSharePathTest::SharePathCallback, + base::Unretained(this), "vm-running", Persist::NO, + SeneschalClientCalled::YES, + &vm_tools::seneschal::SharePathRequest:: + DRIVEFS_SHORTCUT_TARGETS_BY_ID, + "1-abc-xyz/shortcut", Success::YES, "")); + run_loop()->Run(); +} + TEST_F(GuestOsSharePathTest, FailDriveFsTrash) { SetUpVolume(); guest_os_share_path_->SharePath(
diff --git a/chrome/browser/ash/input_method/ui/undo_window.cc b/chrome/browser/ash/input_method/ui/undo_window.cc index b14193ac..a2e1c42 100644 --- a/chrome/browser/ash/input_method/ui/undo_window.cc +++ b/chrome/browser/ash/input_method/ui/undo_window.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/ash/input_method/ui/undo_window.h" #include "ash/public/cpp/style/color_provider.h" -#include "ash/style/scoped_light_mode_as_default.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ash/input_method/ui/border_factory.h" #include "ui/base/metadata/metadata_impl_macros.h"
diff --git a/chrome/browser/ash/pcie_peripheral/OWNERS b/chrome/browser/ash/pcie_peripheral/OWNERS new file mode 100644 index 0000000..cbaa826 --- /dev/null +++ b/chrome/browser/ash/pcie_peripheral/OWNERS
@@ -0,0 +1,2 @@ +jimmyxgong@chromium.org +zentaro@chromium.org \ No newline at end of file
diff --git a/chrome/browser/ash/pcie_peripheral/ash_usb_detector.cc b/chrome/browser/ash/pcie_peripheral/ash_usb_detector.cc new file mode 100644 index 0000000..17ee43a --- /dev/null +++ b/chrome/browser/ash/pcie_peripheral/ash_usb_detector.cc
@@ -0,0 +1,97 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/pcie_peripheral/ash_usb_detector.h" + +#include "ash/components/pcie_peripheral/pcie_peripheral_manager.h" +#include "base/memory/weak_ptr.h" +#include "content/public/browser/device_service.h" + +namespace ash { + +namespace { +static AshUsbDetector* g_ash_usb_detector = nullptr; +} // namespace + +AshUsbDetector::AshUsbDetector() { + DCHECK(!g_ash_usb_detector); + g_ash_usb_detector = this; +} + +AshUsbDetector::~AshUsbDetector() { + DCHECK_EQ(this, g_ash_usb_detector); + g_ash_usb_detector = nullptr; +} + +// static +AshUsbDetector* AshUsbDetector::Get() { + return g_ash_usb_detector; +} + +void AshUsbDetector::ConnectToDeviceManager() { + if (!device_manager_) { + content::GetDeviceService().BindUsbDeviceManager( + device_manager_.BindNewPipeAndPassReceiver()); + } + DCHECK(device_manager_); + device_manager_.set_disconnect_handler( + base::BindOnce(&AshUsbDetector::OnDeviceManagerConnectionError, + weak_ptr_factory_.GetWeakPtr())); + + // Listen for added/removed device events. + DCHECK(!client_receiver_.is_bound()); + device_manager_->EnumerateDevicesAndSetClient( + client_receiver_.BindNewEndpointAndPassRemote(), + base::BindOnce(&AshUsbDetector::OnListAttachedDevices, + weak_ptr_factory_.GetWeakPtr())); +} + +int32_t AshUsbDetector::GetOnDeviceCheckedCountForTesting() { + return on_device_checked_counter_for_testing_; +} + +void AshUsbDetector::OnDeviceAdded( + device::mojom::UsbDeviceInfoPtr device_info) { + std::string guid = device_info->guid; + device_manager_->CheckAccess( + guid, + base::BindOnce(&AshUsbDetector::OnDeviceChecked, + weak_ptr_factory_.GetWeakPtr(), std::move(device_info))); +} + +void AshUsbDetector::OnDeviceRemoved( + device::mojom::UsbDeviceInfoPtr device_info) {} + +void AshUsbDetector::OnListAttachedDevices( + std::vector<device::mojom::UsbDeviceInfoPtr> devices) { + for (device::mojom::UsbDeviceInfoPtr& device_info : devices) + AshUsbDetector::OnDeviceAdded(std::move(device_info)); +} + +void AshUsbDetector::OnDeviceChecked( + device::mojom::UsbDeviceInfoPtr device_info, + bool allowed) { + if (!allowed) + return; + + ash::PciePeripheralManager::Get()->OnDeviceConnected(device_info.get()); + + if (is_testing_) + ++on_device_checked_counter_for_testing_; +} + +void AshUsbDetector::OnDeviceManagerConnectionError() { + device_manager_.reset(); + client_receiver_.reset(); + ConnectToDeviceManager(); +} + +void AshUsbDetector::SetDeviceManagerForTesting( + mojo::PendingRemote<device::mojom::UsbDeviceManager> device_manager) { + DCHECK(!device_manager_) << "device_manager_ was already initialized"; + device_manager_.Bind(std::move(device_manager)); + is_testing_ = true; +} + +} // namespace ash
diff --git a/chrome/browser/ash/pcie_peripheral/ash_usb_detector.h b/chrome/browser/ash/pcie_peripheral/ash_usb_detector.h new file mode 100644 index 0000000..2e3b7e52 --- /dev/null +++ b/chrome/browser/ash/pcie_peripheral/ash_usb_detector.h
@@ -0,0 +1,64 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_ASH_PCIE_PERIPHERAL_ASH_USB_DETECTOR_H_ +#define CHROME_BROWSER_ASH_PCIE_PERIPHERAL_ASH_USB_DETECTOR_H_ + +#include "ash/public/cpp/ash_public_export.h" +#include "mojo/public/cpp/bindings/associated_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "services/device/public/mojom/usb_device.mojom.h" +#include "services/device/public/mojom/usb_manager.mojom.h" +#include "services/device/public/mojom/usb_manager_client.mojom.h" + +namespace ash { + +// Detects usb devices when they are connected and notifies ash. Similar to +// CrosUsbDetector and WebUsbDetector. +class ASH_PUBLIC_EXPORT AshUsbDetector + : public device::mojom::UsbDeviceManagerClient { + public: + AshUsbDetector(); + ~AshUsbDetector() override; + + static AshUsbDetector* Get(); + + // Connect to the device manager to be notified of connection/removal. + // Used during browser startup, after connection errors and to setup a fake + // device manager during testing. + void ConnectToDeviceManager(); + + private: + friend class AshUsbDetectorTest; + + int32_t GetOnDeviceCheckedCountForTesting(); + + // device::mojom::UsbDeviceManagerClient + void OnDeviceAdded(device::mojom::UsbDeviceInfoPtr device_info) override; + void OnDeviceRemoved(device::mojom::UsbDeviceInfoPtr device) override; + + void OnListAttachedDevices( + std::vector<device::mojom::UsbDeviceInfoPtr> devices); + void OnDeviceChecked(device::mojom::UsbDeviceInfoPtr device_info, + bool allowed); + void OnDeviceManagerConnectionError(); + + void SetDeviceManagerForTesting( + mojo::PendingRemote<device::mojom::UsbDeviceManager> device_manager); + + mojo::Remote<device::mojom::UsbDeviceManager> device_manager_; + mojo::AssociatedReceiver<device::mojom::UsbDeviceManagerClient> + client_receiver_{this}; + + int32_t on_device_checked_counter_for_testing_ = 0; + bool is_testing_ = false; + + // WeakPtrFactory to use for callbacks. + base::WeakPtrFactory<AshUsbDetector> weak_ptr_factory_{this}; +}; + +} // namespace ash + +#endif // CHROME_BROWSER_ASH_PCIE_PERIPHERAL_ASH_USB_DETECTOR_H_
diff --git a/chrome/browser/ash/pcie_peripheral/ash_usb_detector_unittest.cc b/chrome/browser/ash/pcie_peripheral/ash_usb_detector_unittest.cc new file mode 100644 index 0000000..cbaaa7c --- /dev/null +++ b/chrome/browser/ash/pcie_peripheral/ash_usb_detector_unittest.cc
@@ -0,0 +1,78 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ash/pcie_peripheral/ash_usb_detector.h" + +#include "ash/components/pcie_peripheral/pcie_peripheral_manager.h" +#include "chrome/test/base/browser_with_test_window_test.h" +#include "chromeos/dbus/pciguard/pciguard_client.h" +#include "chromeos/dbus/typecd/typecd_client.h" +#include "services/device/public/cpp/test/fake_usb_device_manager.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { +// USB device product name. +const char* kProductName_1 = "Google Product A"; +const char* kManufacturerName = "Google"; +} // namespace + +namespace ash { + +class AshUsbDetectorTest : public BrowserWithTestWindowTest { + public: + AshUsbDetectorTest() = default; + AshUsbDetectorTest(const AshUsbDetectorTest&) = delete; + AshUsbDetectorTest& operator=(const AshUsbDetectorTest&) = delete; + ~AshUsbDetectorTest() override = default; + + void SetUp() override { + BrowserWithTestWindowTest::SetUp(); + + ash_usb_detector_ = std::make_unique<AshUsbDetector>(); + + // Set a fake USB device manager before ConnectToDeviceManager(). + mojo::PendingRemote<device::mojom::UsbDeviceManager> device_manager; + device_manager_.AddReceiver( + device_manager.InitWithNewPipeAndPassReceiver()); + AshUsbDetector::Get()->SetDeviceManagerForTesting( + std::move(device_manager)); + + chromeos::TypecdClient::InitializeFake(); + chromeos::PciguardClient::InitializeFake(); + PciePeripheralManager::Initialize(/*is_guest_session=*/false, + /*is_pcie_tunneling_allowed=*/false); + } + + void TearDown() override { + BrowserWithTestWindowTest::TearDown(); + ash_usb_detector_.reset(); + } + + void ConnectToDeviceManager() { + AshUsbDetector::Get()->ConnectToDeviceManager(); + } + + int32_t GetOnDeviceCheckedCount() { + return ash_usb_detector_->GetOnDeviceCheckedCountForTesting(); + } + + device::FakeUsbDeviceManager device_manager_; + std::unique_ptr<AshUsbDetector> ash_usb_detector_; +}; + +TEST_F(AshUsbDetectorTest, AddOneDevice) { + ConnectToDeviceManager(); + base::RunLoop().RunUntilIdle(); + + auto device = base::MakeRefCounted<device::FakeUsbDeviceInfo>( + /*vendor_id=*/0, /*product_id=*/1, kManufacturerName, kProductName_1, + /*serial_number=*/"002"); + + device_manager_.AddDevice(device); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(1, GetOnDeviceCheckedCount()); +} + +} // namespace ash
diff --git a/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc b/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc index 209ff5c..78ecd8d14 100644 --- a/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc +++ b/chrome/browser/ash/web_applications/media_app/media_app_integration_browsertest.cc
@@ -277,6 +277,8 @@ TestFile(kFileJpeg640x480)); PrepareAppForTest(app); + EXPECT_EQ("640x480", WaitForImageAlt(app, kFileJpeg640x480)); + clickAppBarButton(app, kAnnotationButtonSelector); // Checks ink is loaded for images by ensuring the ink engine canvas has a non
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 2aa89a3..0da8ea6 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -13,6 +13,7 @@ #include <utility> #include <vector> +#include "ash/constants/ash_features.h" #include "base/at_exit.h" #include "base/base_switches.h" #include "base/bind.h" @@ -1639,8 +1640,10 @@ } #if BUILDFLAG(IS_CHROMEOS_ASH) - speech::SodaInstaller::GetInstance()->Init(profile_->GetPrefs(), - browser_process_->local_state()); + if (base::FeatureList::IsEnabled(ash::features::kOnDeviceSpeechRecognition)) { + speech::SodaInstaller::GetInstance()->Init(profile_->GetPrefs(), + browser_process_->local_state()); + } #endif // BUILDFLAG(IS_CHROMEOS_ASH) variations::VariationsService* variations_service =
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index ffcf9125..a445e13 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -2038,6 +2038,8 @@ "../ash/ownership/owner_settings_service_ash.h", "../ash/ownership/owner_settings_service_ash_factory.cc", "../ash/ownership/owner_settings_service_ash_factory.h", + "../ash/pcie_peripheral/ash_usb_detector.cc", + "../ash/pcie_peripheral/ash_usb_detector.h", "../ash/plugin_vm/plugin_vm_diagnostics.cc", "../ash/plugin_vm/plugin_vm_diagnostics.h", "../ash/plugin_vm/plugin_vm_drive_image_download_service.cc", @@ -3982,6 +3984,7 @@ "../ash/notifications/request_system_proxy_credentials_view_unittest.cc", "../ash/notifications/update_required_notification_unittest.cc", "../ash/ownership/owner_settings_service_ash_unittest.cc", + "../ash/pcie_peripheral/ash_usb_detector_unittest.cc", "../ash/plugin_vm/mock_plugin_vm_manager.cc", "../ash/plugin_vm/mock_plugin_vm_manager.h", "../ash/plugin_vm/plugin_vm_features_unittest.cc",
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc index aaa81a5..a6d2914 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -97,6 +97,7 @@ #include "chrome/browser/ash/notifications/gnubby_notification.h" #include "chrome/browser/ash/notifications/low_disk_notification.h" #include "chrome/browser/ash/ownership/owner_settings_service_ash_factory.h" +#include "chrome/browser/ash/pcie_peripheral/ash_usb_detector.h" #include "chrome/browser/ash/policy/core/browser_policy_connector_chromeos.h" #include "chrome/browser/ash/policy/core/device_local_account.h" #include "chrome/browser/ash/policy/handlers/lock_to_single_user_manager.h" @@ -1162,6 +1163,13 @@ base::BindOnce(&CrosUsbDetector::ConnectToDeviceManager, base::Unretained(cros_usb_detector_.get()))); + // USB detection for ash notifications. + ash_usb_detector_ = std::make_unique<ash::AshUsbDetector>(); + content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT}) + ->PostTask(FROM_HERE, + base::BindOnce(&ash::AshUsbDetector::ConnectToDeviceManager, + base::Unretained(ash_usb_detector_.get()))); + if (chromeos::features::IsPciguardUiEnabled()) { // The local_state pref may not be available at this stage of Chrome's // lifecycle, default to false for now. The actual state will be set in a
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.h b/chrome/browser/chromeos/chrome_browser_main_chromeos.h index 11161ec..38db7c05 100644 --- a/chrome/browser/chromeos/chrome_browser_main_chromeos.h +++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.h
@@ -38,6 +38,7 @@ // TODO(https://crbug.com/1164001): remove and use forward declaration. #include "chrome/browser/ash/usb/cros_usb_detector.h" // TODO(https://crbug.com/1164001): remove and use forward declaration. +#include "chrome/browser/ash/pcie_peripheral/ash_usb_detector.h" #include "chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_manager.h" #include "chrome/browser/chrome_browser_main_linux.h" #include "chrome/browser/chromeos/external_metrics.h" @@ -194,6 +195,7 @@ std::unique_ptr<DemoModeResourcesRemover> demo_mode_resources_remover_; std::unique_ptr<crostini::CrosvmMetrics> crosvm_metrics_; + std::unique_ptr<ash::AshUsbDetector> ash_usb_detector_; std::unique_ptr<CrosUsbDetector> cros_usb_detector_; std::unique_ptr<crostini::CrostiniUnsupportedActionNotifier>
diff --git a/chrome/browser/continuous_search/android/java/res/layout/continuous_search_layout.xml b/chrome/browser/continuous_search/android/java/res/layout/continuous_search_layout.xml index 32c31ce..be34615a 100644 --- a/chrome/browser/continuous_search/android/java/res/layout/continuous_search_layout.xml +++ b/chrome/browser/continuous_search/android/java/res/layout/continuous_search_layout.xml
@@ -2,7 +2,6 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> @@ -27,5 +26,5 @@ android:layout_weight="0" android:gravity="center" android:src="@drawable/btn_close" - tools:ignore="ContentDescription" /> -</LinearLayout> \ No newline at end of file + android:contentDescription="@string/close" /> +</LinearLayout>
diff --git a/chrome/browser/download/android/download_manager_service.cc b/chrome/browser/download/android/download_manager_service.cc index d4ddc04..68e4a61 100644 --- a/chrome/browser/download/android/download_manager_service.cc +++ b/chrome/browser/download/android/download_manager_service.cc
@@ -839,6 +839,7 @@ download::DOWNLOAD_INTERRUPT_REASON_CRASH, false, false, false, base::Time(), false, std::vector<download::DownloadItem::ReceivedSlice>(), + download::DownloadItemRerouteInfo(), absl::nullopt /*download_schedule*/, nullptr)); }
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index 9752c3f4..03162a2 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -4816,6 +4816,7 @@ false /* allow_metered */, false /* opened */, current_time, false /* transient */, std::vector<download::DownloadItem::ReceivedSlice>(), + download::DownloadItemRerouteInfo(), absl::nullopt /*download_schedule*/, nullptr /* download_entry */)); download::DownloadItem* download = coordinator->GetDownloadByGuid(guid);
diff --git a/chrome/browser/download/download_item_model_unittest.cc b/chrome/browser/download/download_item_model_unittest.cc index f271bca..7fa4c06a 100644 --- a/chrome/browser/download/download_item_model_unittest.cc +++ b/chrome/browser/download/download_item_model_unittest.cc
@@ -18,7 +18,7 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "components/download/public/common/mock_download_item.h" -#include "components/enterprise/common/proto/download_item_reroute_info.pb.h" +#include "components/enterprise/common/download_item_reroute_info.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/text/bytes_formatting.h"
diff --git a/chrome/browser/download/internal/android/java/res/layout/download_manager_section_header.xml b/chrome/browser/download/internal/android/java/res/layout/download_manager_section_header.xml index 30a3f40..348feba 100644 --- a/chrome/browser/download/internal/android/java/res/layout/download_manager_section_header.xml +++ b/chrome/browser/download/internal/android/java/res/layout/download_manager_section_header.xml
@@ -8,15 +8,10 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> - <View - android:id="@+id/divider" - style="@style/HorizontalDivider" /> - <Space android:id="@+id/top_space" android:layout_width="match_parent" - android:layout_height="@dimen/download_manager_section_title_padding_top" - android:layout_below="@+id/divider" /> + android:layout_height="@dimen/download_manager_section_title_padding_top" /> <TextView android:id="@+id/date"
diff --git a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutatorTest.java b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutatorTest.java index d5cd6821..8d46c1c76 100644 --- a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutatorTest.java +++ b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMutatorTest.java
@@ -115,7 +115,7 @@ DateOrderedListMutator list = createMutatorWithoutJustNowProvider(); Assert.assertEquals(2, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 1), item1); } @@ -134,7 +134,7 @@ DateOrderedListMutator list = createMutatorWithoutJustNowProvider(); Assert.assertEquals(3, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 2), item1); assertOfflineItem(mModel.get(2), buildCalendar(2018, 1, 1, 1), item2); } @@ -153,7 +153,7 @@ DateOrderedListMutator list = createMutatorWithoutJustNowProvider(); Assert.assertEquals(3, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 2), item1); assertOfflineItem(mModel.get(2), buildCalendar(2018, 1, 1, 1), item2); } @@ -232,7 +232,7 @@ assertJustNowSection(mModel.get(0)); assertOfflineItem(mModel.get(1), calendar1, item1); assertOfflineItem(mModel.get(2), calendar2, item2); - assertSectionHeader(mModel.get(3), buildCalendar(2018, 1, 1, 0), true); + assertSectionHeader(mModel.get(3), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(4), buildCalendar(2018, 1, 1, 10), item3); } @@ -315,7 +315,7 @@ Assert.assertEquals(4, mModel.size()); assertJustNowSection(mModel.get(0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 2, 1, 1), item1); - assertSectionHeader(mModel.get(2), buildCalendar(2018, 1, 1, 0), true); + assertSectionHeader(mModel.get(2), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(3), buildCalendar(2018, 1, 1, 1), item2); } @@ -344,7 +344,7 @@ assertOfflineItem(mModel.get(1), calendar, item1); assertJustNowSection(mModel.get(2)); assertOfflineItem(mModel.get(3), buildCalendar(2018, 2, 1, 1), item2); - assertSectionHeader(mModel.get(4), buildCalendar(2018, 1, 1, 0), true); + assertSectionHeader(mModel.get(4), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(5), buildCalendar(2018, 1, 1, 1), item3); } @@ -365,9 +365,9 @@ DateOrderedListMutator list = createMutatorWithoutJustNowProvider(); Assert.assertEquals(4, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 2, 0), item1); - assertSectionHeader(mModel.get(2), buildCalendar(2018, 1, 1, 0), true); + assertSectionHeader(mModel.get(2), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(3), buildCalendar(2018, 1, 1, 0), item2); } @@ -386,7 +386,7 @@ DateOrderedListMutator list = createMutatorWithoutJustNowProvider(); Assert.assertEquals(3, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 5), item2); assertOfflineItem(mModel.get(2), buildCalendar(2018, 1, 1, 4), item1); } @@ -407,9 +407,9 @@ DateOrderedListMutator list = createMutatorWithoutJustNowProvider(); Assert.assertEquals(4, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 2, 4), item1); - assertSectionHeader(mModel.get(2), buildCalendar(2018, 1, 1, 0), true); + assertSectionHeader(mModel.get(2), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(3), buildCalendar(2018, 1, 1, 5), item2); } @@ -429,9 +429,9 @@ DateOrderedListMutator list = createMutatorWithoutJustNowProvider(); Assert.assertEquals(4, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 2, 4), item1); - assertSectionHeader(mModel.get(2), buildCalendar(2018, 1, 1, 0), true); + assertSectionHeader(mModel.get(2), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(3), buildCalendar(2018, 1, 1, 5), item2); } @@ -451,9 +451,9 @@ DateOrderedListMutator list = createMutatorWithoutJustNowProvider(); Assert.assertEquals(4, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 2, 3), item2); - assertSectionHeader(mModel.get(2), buildCalendar(2018, 1, 1, 0), true); + assertSectionHeader(mModel.get(2), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(3), buildCalendar(2018, 1, 1, 4), item1); } @@ -603,7 +603,7 @@ list.onItemsRemoved(Collections.singletonList(item1)); Assert.assertEquals(2, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 2, 2), item2); } @@ -629,7 +629,7 @@ list.onItemsRemoved(Collections.singletonList(item2)); Assert.assertEquals(2, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 2, 3), item1); } @@ -656,7 +656,7 @@ list.onItemsRemoved(Collections.singletonList(item2)); Assert.assertEquals(2, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 3, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 3, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 3, 3), item1); } @@ -688,10 +688,10 @@ list.onItemsAdded(Arrays.asList(item1, item2, item3, item4)); Assert.assertEquals(6, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 2, 12), item4); assertOfflineItem(mModel.get(2), buildCalendar(2018, 1, 2, 10), item3); - assertSectionHeader(mModel.get(3), buildCalendar(2018, 1, 1, 0), true); + assertSectionHeader(mModel.get(3), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(4), buildCalendar(2018, 1, 1, 6), item1); assertOfflineItem(mModel.get(5), buildCalendar(2018, 1, 1, 4), item2); } @@ -768,7 +768,7 @@ list.onItemsAdded(Collections.singletonList(item1)); Assert.assertEquals(2, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 6), item1); // Complete the download. @@ -782,7 +782,7 @@ list.onItemsAdded(Collections.singletonList(item2)); Assert.assertEquals(3, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 6), update1); assertOfflineItem(mModel.get(2), buildCalendar(2018, 1, 1, 4), item2); } @@ -817,7 +817,7 @@ list.onItemsRemoved(Arrays.asList(item2, item3, item4)); Assert.assertEquals(2, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 6), item1); } @@ -847,7 +847,7 @@ list.onItemUpdated(item1, newItem1); Assert.assertEquals(2, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 4), newItem1); } @@ -879,7 +879,7 @@ list.onItemUpdated(item1, newItem1); Assert.assertEquals(3, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 4), item2); assertOfflineItem(mModel.get(2), buildCalendar(2018, 1, 1, 3), newItem1); } @@ -912,7 +912,7 @@ list.onItemUpdated(item1, newItem1); Assert.assertEquals(3, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 1, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 1, 4), item2); assertOfflineItem(mModel.get(2), buildCalendar(2018, 1, 1, 3), newItem1); } @@ -941,7 +941,7 @@ list.onItemUpdated(item1, newItem1); Assert.assertEquals(2, mModel.size()); - assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0), false); + assertSectionHeader(mModel.get(0), buildCalendar(2018, 1, 2, 0)); assertOfflineItem(mModel.get(1), buildCalendar(2018, 1, 2, 6), newItem1); } @@ -1265,7 +1265,7 @@ Assert.assertEquals(offlineItem, ((OfflineItemListItem) item).item); } - private static void assertSectionHeader(ListItem item, Calendar calendar, boolean showDivider) { + private static void assertSectionHeader(ListItem item, Calendar calendar) { Assert.assertTrue(item instanceof SectionHeaderListItem); SectionHeaderListItem sectionHeader = (SectionHeaderListItem) item; assertDatesAreEqual(sectionHeader.date, calendar); @@ -1278,7 +1278,6 @@ Assert.assertEquals(SectionHeaderListItem.generateStableId( SectionHeaderType.SCHEDULED_LATER, calendar.getTimeInMillis()), StableIds.SCHEDULE_LATER_SECTION); - Assert.assertEquals(sectionHeader.showTopDivider, showDivider); } private static void assertJustNowSection(ListItem item) { @@ -1291,8 +1290,6 @@ private static void assertScheduledLaterHeader(ListItem item) { Assert.assertTrue(item instanceof SectionHeaderListItem); SectionHeaderListItem sectionHeader = (SectionHeaderListItem) item; - Assert.assertEquals("Schedule for later section is at the top of the list", false, - sectionHeader.showTopDivider); Assert.assertEquals(SectionHeaderType.SCHEDULED_LATER, sectionHeader.type); Assert.assertEquals(StableIds.SCHEDULE_LATER_SECTION, item.stableId); }
diff --git a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/ListItem.java b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/ListItem.java index 5f50e926..9fcbf06 100644 --- a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/ListItem.java +++ b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/ListItem.java
@@ -144,16 +144,13 @@ /** A {@link ListItem} representing a section header. */ public static class SectionHeaderListItem extends DateListItem { public @SectionHeaderType int type; - public boolean showTopDivider; /** * Creates a {@link SectionHeaderListItem} instance for a given {@code timestamp}. */ - public SectionHeaderListItem( - long timestamp, @SectionHeaderType int type, boolean showTopDivider) { + public SectionHeaderListItem(long timestamp, @SectionHeaderType int type) { super(generateStableId(type, timestamp), new Date(timestamp)); this.type = type; - this.showTopDivider = showTopDivider; } @VisibleForTesting
diff --git a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/holder/SectionTitleViewHolder.java b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/holder/SectionTitleViewHolder.java index 3a101d4..15ed0cf 100644 --- a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/holder/SectionTitleViewHolder.java +++ b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/holder/SectionTitleViewHolder.java
@@ -21,7 +21,6 @@ * A {@link ViewHolder} specifically meant to display a section header. */ public class SectionTitleViewHolder extends ListItemViewHolder { - private final View mTopDivider; private final TextView mTitle; /** Create a new {@link SectionTitleViewHolder} instance. */ @@ -33,7 +32,6 @@ private SectionTitleViewHolder(View view) { super(view); - mTopDivider = view.findViewById(R.id.divider); mTitle = (TextView) view.findViewById(R.id.date); } @@ -42,7 +40,6 @@ public void bind(PropertyModel properties, ListItem item) { SectionHeaderListItem sectionItem = (SectionHeaderListItem) item; mTitle.setText(getSectionTitle(sectionItem, itemView.getContext())); - mTopDivider.setVisibility(sectionItem.showTopDivider ? ViewGroup.VISIBLE : ViewGroup.GONE); } private static CharSequence getSectionTitle(
diff --git a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/mutator/DateLabelAdder.java b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/mutator/DateLabelAdder.java index a7a8ab5..288a8ab 100644 --- a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/mutator/DateLabelAdder.java +++ b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/list/mutator/DateLabelAdder.java
@@ -73,28 +73,25 @@ @SectionHeaderType int previousHeaderType = getSectionHeaderType(previousItem); - // Add a divider between sections after the first section header. - boolean showTopDivider = previousItem != null; - // Add a section header when starting a new section. if (currentHeaderType != previousHeaderType) { - addSectionHeader(listWithHeaders, currentItem, showTopDivider); + addSectionHeader(listWithHeaders, currentItem); return; } // For date time section, each day has a header. if (currentHeaderType == SectionHeaderType.DATE && startOfNewDay(currentItem, previousItem)) { - addSectionHeader(listWithHeaders, currentItem, showTopDivider); + addSectionHeader(listWithHeaders, currentItem); return; } } - private void addSectionHeader(List<ListItem> listWithHeaders, @NonNull OfflineItem currentItem, - boolean showTopDivider) { + private void addSectionHeader( + List<ListItem> listWithHeaders, @NonNull OfflineItem currentItem) { Date day = CalendarUtils.getStartOfDay(currentItem.creationTimeMs).getTime(); ListItem.SectionHeaderListItem sectionHeaderItem = new ListItem.SectionHeaderListItem( - day.getTime(), getSectionHeaderType(currentItem), showTopDivider); + day.getTime(), getSectionHeaderType(currentItem)); listWithHeaders.add(sectionHeaderItem); }
diff --git a/chrome/browser/download/notification/download_item_notification_unittest.cc b/chrome/browser/download/notification/download_item_notification_unittest.cc index 4439f2a..fd3ed5bbd 100644 --- a/chrome/browser/download/notification/download_item_notification_unittest.cc +++ b/chrome/browser/download/notification/download_item_notification_unittest.cc
@@ -32,7 +32,7 @@ #include "chrome/test/base/testing_profile_manager.h" #include "components/download/public/common/download_danger_type.h" #include "components/download/public/common/mock_download_item.h" -#include "components/enterprise/common/proto/download_item_reroute_info.pb.h" +#include "components/enterprise/common/download_item_reroute_info.h" #include "content/public/browser/download_item_utils.h" #include "content/public/test/browser_task_environment.h" #include "content/public/test/mock_download_manager.h"
diff --git a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc index 636f631..42aaad2 100644 --- a/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc +++ b/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc
@@ -150,6 +150,8 @@ picker_params.request_audio = request_audio; picker_controller_ = std::make_unique<DesktopMediaPickerController>(g_picker_factory); + picker_params.restricted_by_policy = + (capture_level != AllowedScreenCaptureLevel::kUnrestricted); picker_controller_->Show(picker_params, std::move(media_types), includable_web_contents_filter, std::move(callback)); return RespondLater();
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 26106dc..5ea70b2 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -608,6 +608,9 @@ settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_allowlist)[chromeos::assistant::prefs::kAssistantHotwordEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN; + (*s_allowlist) + [chromeos::assistant::prefs::kAssistantVoiceMatchEnabledDuringOobe] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_allowlist)[chromeos::assistant::prefs::kAssistantLaunchWithMicOpen] = settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_allowlist)[chromeos::assistant::prefs::kAssistantNotificationEnabled] =
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc index 3aff5a8..1d6a162 100644 --- a/chrome/browser/extensions/service_worker_apitest.cc +++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -2335,8 +2335,16 @@ EXPECT_EQ(0u, GetWorkerRefCount(extension_key)); } +// Disabled on Ozone due to flakiness: https://crbug.com/1236184. +#if defined(USE_OZONE) +#define MAYBE_PRE_EventsAfterRestart DISABLED_PRE_EventsAfterRestart +#define MAYBE_EventsAfterRestart DISABLED_EventsAfterRestart +#else +#define MAYBE_PRE_EventsAfterRestart PRE_EventsAfterRestart +#define MAYBE_EventsAfterRestart EventsAfterRestart +#endif IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, - PRE_EventsAfterRestart) { + MAYBE_PRE_EventsAfterRestart) { ExtensionTestMessageListener event_added_listener("ready", false); base::ScopedAllowBlockingForTesting allow_blocking; @@ -2366,7 +2374,8 @@ // tabs.onCreated event listener to the extension without explicitly loading the // extension. This is because the extension registered a listener for // tabs.onMoved before browser restarted in PRE_EventsAfterRestart. -IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, EventsAfterRestart) { +IN_PROC_BROWSER_TEST_F(ServiceWorkerBasedBackgroundTest, + MAYBE_EventsAfterRestart) { // Verify there is no RenderProcessHost for the extension. EXPECT_FALSE(ExtensionHasRenderProcessHost(kTestExtensionId));
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index bc95cba..12eb1a7 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -1876,7 +1876,7 @@ { "name": "enable-experimental-accessibility-switch-access-setup-guide", "owners": ["ansatasi@google.com", "josiahk@google.com", "//ui/accessibility/OWNERS"], - "expiry_milestone": 94 + "expiry_milestone": 97 }, { "name": "enable-experimental-accessibility-switch-access-text", @@ -4502,6 +4502,13 @@ "expiry_milestone": 95 }, { + "name": "password-import", + "owners": [ "//components/password_manager/OWNERS" ], + // The feature is already extensively used externally. + // However, it's not polished enough yet to launch. + "expiry_milestone": -1 + }, + { "name": "password-reuse-detection", "owners": [ "edchin", @@ -4516,11 +4523,6 @@ "expiry_milestone": 95 }, { - "name": "PasswordImport", - "owners": [ "jdoerrie", "vasilii" ], - "expiry_milestone": 92 - }, - { "name": "passwords-account-storage", "owners": [ "mamir", "treib" ], "expiry_milestone": 95
diff --git a/chrome/browser/flag-never-expire-list.json b/chrome/browser/flag-never-expire-list.json index 8bb39e2..0fdbdab 100644 --- a/chrome/browser/flag-never-expire-list.json +++ b/chrome/browser/flag-never-expire-list.json
@@ -82,6 +82,7 @@ "memlog-sampling-rate", "memlog-stack-mode", "overlay-strategies", + "password-import", "reader-mode-heuristics", "record-web-app-debug-info", "release-notes-notification-all-channels",
diff --git a/chrome/browser/history_clusters/history_clusters_tab_helper.cc b/chrome/browser/history_clusters/history_clusters_tab_helper.cc index 75909214..43ffb9a 100644 --- a/chrome/browser/history_clusters/history_clusters_tab_helper.cc +++ b/chrome/browser/history_clusters/history_clusters_tab_helper.cc
@@ -17,7 +17,6 @@ #include "components/history/core/browser/history_backend.h" #include "components/history/core/browser/history_database.h" #include "components/history/core/browser/history_db_task.h" -#include "components/history/core/browser/history_types.h" #include "components/history/core/browser/url_row.h" #include "components/history_clusters/core/history_clusters_service.h" #include "components/keyed_service/core/service_access_type.h"
diff --git a/chrome/browser/installable/installable_manager_browsertest.cc b/chrome/browser/installable/installable_manager_browsertest.cc index 842604c7..10b2a917 100644 --- a/chrome/browser/installable/installable_manager_browsertest.cc +++ b/chrome/browser/installable/installable_manager_browsertest.cc
@@ -429,7 +429,6 @@ EXPECT_FALSE(manager->has_worker()); EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error()); - EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error()); EXPECT_TRUE(!manager->task_queue_.HasCurrent()); } @@ -460,7 +459,6 @@ EXPECT_EQ(IN_INCOGNITO, manager->eligibility_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error()); - EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error()); EXPECT_TRUE(!manager->task_queue_.HasCurrent()); } @@ -708,8 +706,9 @@ base::RunLoop run_loop; std::unique_ptr<CallbackTester> tester( new CallbackTester(run_loop.QuitClosure())); - - RunInstallableManager(browser(), tester.get(), GetWebAppParams()); + auto params = GetWebAppParams(); + params.valid_manifest = false; + RunInstallableManager(browser(), tester.get(), params); run_loop.Run(); EXPECT_FALSE(tester->manifest().IsEmpty()); @@ -832,6 +831,7 @@ IN_PROC_BROWSER_TEST_P(InstallableManagerOfflineCapabilityBrowserTest, CheckWebapp) { + auto params = GetWebAppParams(); // Request everything except splash icon. { base::HistogramTester histograms; @@ -861,14 +861,13 @@ EXPECT_FALSE(manager->manifest().IsEmpty()); EXPECT_FALSE(manager->manifest_url().is_empty()); - EXPECT_TRUE(manager->valid_manifest()); EXPECT_EQ(1u, manager->icons_.size()); + EXPECT_FALSE(manager->valid_manifest()); EXPECT_FALSE(( manager->icon_url(InstallableManager::IconUsage::kPrimary).is_empty())); EXPECT_NE(nullptr, (manager->icon(InstallableManager::IconUsage::kPrimary))); EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error()); - EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(InstallableManager::IconUsage::kPrimary))); EXPECT_TRUE(!manager->task_queue_.HasCurrent()); @@ -881,8 +880,10 @@ base::RunLoop run_loop; std::unique_ptr<CallbackTester> tester( new CallbackTester(run_loop.QuitClosure())); - - RunInstallableManager(browser(), tester.get(), GetWebAppParams()); + auto params = GetWebAppParams(); + // Make sure valid_manifest check is run. + params.is_debug_mode = true; + RunInstallableManager(browser(), tester.get(), params); run_loop.Run(); EXPECT_FALSE(tester->manifest().IsEmpty()); @@ -899,14 +900,13 @@ EXPECT_FALSE(manager->manifest().IsEmpty()); EXPECT_FALSE(manager->manifest_url().is_empty()); - EXPECT_TRUE(manager->valid_manifest()); EXPECT_EQ(1u, manager->icons_.size()); + EXPECT_FALSE(manager->valid_manifest()); EXPECT_FALSE(( manager->icon_url(InstallableManager::IconUsage::kPrimary).is_empty())); EXPECT_NE(nullptr, (manager->icon(InstallableManager::IconUsage::kPrimary))); EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error()); - EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(InstallableManager::IconUsage::kPrimary))); EXPECT_TRUE(!manager->task_queue_.HasCurrent()); @@ -924,7 +924,6 @@ EXPECT_FALSE(manager->has_worker()); EXPECT_TRUE(manager->icons_.empty()); EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error()); - EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error()); EXPECT_TRUE(!manager->task_queue_.HasCurrent()); } @@ -1207,14 +1206,13 @@ EXPECT_TRUE(tester->manifest().IsEmpty()); EXPECT_FALSE(manager->manifest().IsEmpty()); EXPECT_FALSE(manager->manifest_url().is_empty()); - EXPECT_TRUE(manager->valid_manifest()); EXPECT_FALSE(manager->has_worker()); EXPECT_EQ(1u, manager->icons_.size()); + EXPECT_TRUE(manager->valid_manifest()); EXPECT_FALSE( (manager->icon_url(InstallableManager::IconUsage::kPrimary).is_empty())); EXPECT_NE(nullptr, (manager->icon(InstallableManager::IconUsage::kPrimary))); EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error()); - EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, manager->worker_error()); EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(InstallableManager::IconUsage::kPrimary))); @@ -1271,13 +1269,12 @@ // Verify internal state. EXPECT_FALSE(manager->manifest().IsEmpty()); EXPECT_FALSE(manager->manifest_url().is_empty()); - EXPECT_TRUE(manager->valid_manifest()); + EXPECT_FALSE(manager->valid_manifest()); EXPECT_EQ(1u, manager->icons_.size()); EXPECT_FALSE( (manager->icon_url(InstallableManager::IconUsage::kPrimary).is_empty())); EXPECT_NE(nullptr, (manager->icon(InstallableManager::IconUsage::kPrimary))); EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error()); - EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(InstallableManager::IconUsage::kPrimary))); EXPECT_TRUE(!manager->task_queue_.HasCurrent()); @@ -1411,7 +1408,7 @@ EXPECT_FALSE(tester->primary_icon_url().is_empty()); EXPECT_NE(nullptr, tester->primary_icon()); - EXPECT_TRUE(tester->valid_manifest()); + EXPECT_FALSE(tester->valid_manifest()); EXPECT_FALSE(tester->has_worker()); EXPECT_TRUE(tester->splash_icon_url().is_empty()); EXPECT_EQ(nullptr, tester->splash_icon()); @@ -1428,7 +1425,10 @@ NavigateAndRunInstallableManager(browser(), tester.get(), GetWebAppParams(), GetPath("/banners/nested_sw_test_page")); - RunInstallableManager(browser(), tester.get(), GetWebAppParams()); + auto params = GetWebAppParams(); + // Make sure valid_manifest check is run. + params.is_debug_mode = true; + RunInstallableManager(browser(), tester.get(), params); run_loop.Run(); EXPECT_FALSE(tester->manifest().IsEmpty()); @@ -1519,7 +1519,10 @@ base::RunLoop run_loop; std::unique_ptr<CallbackTester> tester( new CallbackTester(run_loop.QuitClosure())); - RunInstallableManager(browser(), tester.get(), GetWebAppParams()); + auto params = GetWebAppParams(); + // Make sure valid_manifest check is run. + params.is_debug_mode = true; + RunInstallableManager(browser(), tester.get(), params); run_loop.Run(); @@ -1572,13 +1575,12 @@ EXPECT_FALSE(manager->manifest().IsEmpty()); EXPECT_FALSE(manager->manifest_url().is_empty()); - EXPECT_TRUE(manager->valid_manifest()); + EXPECT_FALSE(manager->valid_manifest()); EXPECT_EQ(1u, manager->icons_.size()); EXPECT_FALSE( (manager->icon_url(InstallableManager::IconUsage::kPrimary).is_empty())); EXPECT_NE(nullptr, (manager->icon(InstallableManager::IconUsage::kPrimary))); EXPECT_EQ(NO_ERROR_DETECTED, manager->manifest_error()); - EXPECT_EQ(NO_ERROR_DETECTED, manager->valid_manifest_error()); EXPECT_EQ(NO_ERROR_DETECTED, (manager->icon_error(InstallableManager::IconUsage::kPrimary))); EXPECT_TRUE(!manager->task_queue_.HasCurrent());
diff --git a/chrome/browser/lacros/download_controller_client_lacros.cc b/chrome/browser/lacros/download_controller_client_lacros.cc index b644642..74b892b 100644 --- a/chrome/browser/lacros/download_controller_client_lacros.cc +++ b/chrome/browser/lacros/download_controller_client_lacros.cc
@@ -52,6 +52,7 @@ download->has_received_bytes = true; download->total_bytes = item->GetTotalBytes(); download->has_total_bytes = true; + download->start_time = item->GetStartTime(); return download; } @@ -76,6 +77,13 @@ ~ObservableDownloadManager() override = default; + // Returns all downloads, no matter the type or state. + std::vector<download::DownloadItem*> GetAllDownloads() { + download::SimpleDownloadManager::DownloadVector downloads; + manager_->GetAllDownloads(&downloads); + return downloads; + } + // Pauses the download associated with the specified `download_guid`. void Pause(const std::string& download_guid) { download::DownloadItem* download = GetDownloadByGuid(download_guid); @@ -204,6 +212,27 @@ g_browser_process->profile_manager()->RemoveObserver(this); } +void DownloadControllerClientLacros::GetAllDownloads( + crosapi::mojom::DownloadControllerClient::GetAllDownloadsCallback + callback) { + std::vector<crosapi::mojom::DownloadItemPtr> downloads; + + // Aggregate all downloads. + for (auto& observable_download_manager : observable_download_managers_) { + for (auto* download : observable_download_manager->GetAllDownloads()) + downloads.push_back(ConvertToMojoDownloadItem(download)); + } + + // Sort chronologically by start time. + std::sort(downloads.begin(), downloads.end(), + [](const auto& a, const auto& b) { + return a->start_time.value_or(base::Time()) < + b->start_time.value_or(base::Time()); + }); + + std::move(callback).Run(std::move(downloads)); +} + void DownloadControllerClientLacros::Pause(const std::string& download_guid) { for (auto& observable_download_manager : observable_download_managers_) observable_download_manager->Pause(download_guid);
diff --git a/chrome/browser/lacros/download_controller_client_lacros.h b/chrome/browser/lacros/download_controller_client_lacros.h index 206ac24..52cae56 100644 --- a/chrome/browser/lacros/download_controller_client_lacros.h +++ b/chrome/browser/lacros/download_controller_client_lacros.h
@@ -42,6 +42,9 @@ class ObservableDownloadManager; // crosapi::mojom::DownloadControllerClient: + void GetAllDownloads( + crosapi::mojom::DownloadControllerClient::GetAllDownloadsCallback + callback) override; void Pause(const std::string& download_guid) override; void Resume(const std::string& download_guid, bool user_resume) override; void Cancel(const std::string& download_guid, bool user_cancel) override;
diff --git a/chrome/browser/lacros/download_controller_client_lacros_browsertest.cc b/chrome/browser/lacros/download_controller_client_lacros_browsertest.cc new file mode 100644 index 0000000..87de4df --- /dev/null +++ b/chrome/browser/lacros/download_controller_client_lacros_browsertest.cc
@@ -0,0 +1,115 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/lacros/download_controller_client_lacros.h" + +#include <memory> +#include <vector> + +#include "base/run_loop.h" +#include "base/test/bind.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/crosapi/mojom/download_controller.mojom.h" +#include "content/public/browser/download_item_utils.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/fake_download_item.h" +#include "content/public/test/mock_download_manager.h" + +// Helpers --------------------------------------------------------------------- + +std::unique_ptr<download::DownloadItem> CreateDownloadItemWithStartTimeOffset( + Profile* profile, + base::TimeDelta start_time_offset) { + auto download = std::make_unique<content::FakeDownloadItem>(); + download->SetState(download::DownloadItem::IN_PROGRESS); + download->SetStartTime(base::Time::Now() + start_time_offset); + content::DownloadItemUtils::AttachInfo(download.get(), profile, nullptr); + return download; +} + +bool IsSortedChronologicallyByStartTime( + const std::vector<crosapi::mojom::DownloadItemPtr>& downloads) { + for (size_t i = 1; i < downloads.size(); ++i) { + if (downloads[i]->start_time.value_or(base::Time()) < + downloads[i - 1]->start_time.value_or(base::Time())) { + return false; + } + } + return true; +} + +// DownloadControllerClientLacrosBrowserTest ----------------------------------- + +class DownloadControllerClientLacrosBrowserTest : public InProcessBrowserTest { + public: + crosapi::mojom::DownloadControllerClient* download_controller_client() { + return download_controller_client_.get(); + } + + testing::NiceMock<content::MockDownloadManager>* download_manager() { + return download_manager_; + } + + Profile* profile() { return browser()->profile(); } + + private: + // InProcessBrowserTest: + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + + // Download manager. + auto download_manager = + std::make_unique<testing::NiceMock<content::MockDownloadManager>>(); + download_manager_ = download_manager.get(); + profile()->GetDownloadManager()->Shutdown(); + profile()->SetDownloadManagerForTesting(std::move(download_manager)); + + ON_CALL(*download_manager_, IsManagerInitialized()) + .WillByDefault(testing::Return(true)); + + // Download controller client. + download_controller_client_ = + std::make_unique<DownloadControllerClientLacros>(); + } + + void TearDownOnMainThread() override { + InProcessBrowserTest::TearDownOnMainThread(); + download_controller_client_.reset(); + } + + std::unique_ptr<crosapi::mojom::DownloadControllerClient> + download_controller_client_; + testing::NiceMock<content::MockDownloadManager>* download_manager_ = nullptr; +}; + +// Tests ----------------------------------------------------------------------- + +IN_PROC_BROWSER_TEST_F(DownloadControllerClientLacrosBrowserTest, + GetAllDownloads) { + // Create a few `downloads`. + std::vector<std::unique_ptr<download::DownloadItem>> downloads; + downloads.push_back(CreateDownloadItemWithStartTimeOffset( + profile(), base::TimeDelta::FromMinutes(10))); + downloads.push_back(CreateDownloadItemWithStartTimeOffset( + profile(), -base::TimeDelta::FromMinutes(10))); + + // Mock `download_manager()` response for `GetAllDownloads()`. + EXPECT_CALL(*download_manager(), GetAllDownloads) + .WillOnce(testing::Invoke( + [&](std::vector<download::DownloadItem*>* download_ptrs) { + for (auto& download : downloads) + download_ptrs->push_back(download.get()); + })); + + // Invoke `GetAllDownloads()`. + base::RunLoop run_loop; + download_controller_client()->GetAllDownloads(base::BindLambdaForTesting( + [&](std::vector<crosapi::mojom::DownloadItemPtr> downloads) { + EXPECT_EQ(downloads.size(), 2u); + EXPECT_TRUE(IsSortedChronologicallyByStartTime(downloads)); + run_loop.Quit(); + })); + run_loop.Run(); +}
diff --git a/chrome/browser/lacros/lacros_extension_apps_controller.cc b/chrome/browser/lacros/lacros_extension_apps_controller.cc index 85aab74b..03bccfe 100644 --- a/chrome/browser/lacros/lacros_extension_apps_controller.cc +++ b/chrome/browser/lacros/lacros_extension_apps_controller.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/lacros/lacros_extension_apps_controller.h" #include "chrome/browser/apps/app_service/app_icon_factory.h" +#include "chrome/browser/apps/app_service/publishers/extension_apps_util.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/lacros/lacros_extension_apps_utility.h" #include "chrome/browser/ui/browser.h" @@ -16,25 +17,6 @@ #include "extensions/common/extension.h" #include "extensions/common/extension_urls.h" -namespace { - -extensions::UninstallReason GetUninstallReason( - apps::mojom::UninstallSource uninstall_source) { - switch (uninstall_source) { - case apps::mojom::UninstallSource::kUnknown: - // We assume if the reason is unknown that it's user inititated. - return extensions::UNINSTALL_REASON_USER_INITIATED; - case apps::mojom::UninstallSource::kAppList: - case apps::mojom::UninstallSource::kAppManagement: - case apps::mojom::UninstallSource::kShelf: - return extensions::UNINSTALL_REASON_USER_INITIATED; - case apps::mojom::UninstallSource::kMigration: - return extensions::UNINSTALL_REASON_MIGRATED; - } -} - -} // namespace - LacrosExtensionAppsController::LacrosExtensionAppsController() = default; LacrosExtensionAppsController::~LacrosExtensionAppsController() = default; @@ -56,7 +38,8 @@ std::u16string error; extensions::ExtensionSystem::Get(profile) ->extension_service() - ->UninstallExtension(extension_id, GetUninstallReason(uninstall_source), + ->UninstallExtension(extension_id, + apps::GetExtensionUninstallReason(uninstall_source), &error); if (report_abuse) {
diff --git a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc index f13bfa9..9e7fa10 100644 --- a/chrome/browser/media/webrtc/desktop_capture_access_handler.cc +++ b/chrome/browser/media/webrtc/desktop_capture_access_handler.cc
@@ -592,10 +592,11 @@ } const GURL& request_origin = pending_request.request.security_origin; + AllowedScreenCaptureLevel capture_level = + capture_policy::GetAllowedCaptureLevel(request_origin, web_contents); auto includable_web_contents_filter = - capture_policy::GetIncludableWebContentsFilter( - request_origin, - capture_policy::GetAllowedCaptureLevel(request_origin, web_contents)); + capture_policy::GetIncludableWebContentsFilter(request_origin, + capture_level); auto source_lists = picker_factory_->CreateMediaList( {DesktopMediaList::Type::kWebContents}, web_contents, @@ -616,6 +617,8 @@ blink::mojom::MediaStreamType::NO_SERVICE) ? false : true; + picker_params.restricted_by_policy = + (capture_level != AllowedScreenCaptureLevel::kUnrestricted); pending_request.picker->Show(picker_params, std::move(source_lists), std::move(done_callback));
diff --git a/chrome/browser/media/webrtc/desktop_media_picker.h b/chrome/browser/media/webrtc/desktop_media_picker.h index 01b764f7..c592ccf 100644 --- a/chrome/browser/media/webrtc/desktop_media_picker.h +++ b/chrome/browser/media/webrtc/desktop_media_picker.h
@@ -67,6 +67,10 @@ // user select a desktop, the desktop picker also serves to prevent the // screen screen from being shared without the user's explicit consent. bool select_only_screen = false; + // Indicates that the caller of this picker is subject to enterprise + // policies that may restrict the available choices, and a suitable warning + // should be shown to the user. + bool restricted_by_policy = false; }; // Creates a picker dialog/confirmation box depending on the value of
diff --git a/chrome/browser/media/webrtc/display_media_access_handler.cc b/chrome/browser/media/webrtc/display_media_access_handler.cc index 591bdc2..9e2ae3c9 100644 --- a/chrome/browser/media/webrtc/display_media_access_handler.cc +++ b/chrome/browser/media/webrtc/display_media_access_handler.cc
@@ -292,6 +292,8 @@ picker_params.request_audio = pending_request.request.audio_type == blink::mojom::MediaStreamType::DISPLAY_AUDIO_CAPTURE; + picker_params.restricted_by_policy = + (capture_level != AllowedScreenCaptureLevel::kUnrestricted); pending_request.picker->Show(picker_params, std::move(source_lists), std::move(done_callback)); }
diff --git a/chrome/browser/media/webrtc/media_capture_devices_dispatcher.cc b/chrome/browser/media/webrtc/media_capture_devices_dispatcher.cc index dcf15e3..dfb27d0 100644 --- a/chrome/browser/media/webrtc/media_capture_devices_dispatcher.cc +++ b/chrome/browser/media/webrtc/media_capture_devices_dispatcher.cc
@@ -165,17 +165,6 @@ } #endif - if (request.video_type == - blink::mojom::MediaStreamType::DISPLAY_VIDEO_CAPTURE_THIS_TAB) { - if (!base::FeatureList::IsEnabled( - blink::features::kRTCGetCurrentBrowsingContextMedia)) { - std::move(callback).Run( - blink::MediaStreamDevices(), - blink::mojom::MediaStreamRequestResult::NOT_SUPPORTED, nullptr); - return; - } - } - for (const auto& handler : media_access_handlers_) { if (handler->SupportsStreamType(web_contents, request.video_type, extension) ||
diff --git a/chrome/browser/media/webrtc/same_origin_observer.cc b/chrome/browser/media/webrtc/same_origin_observer.cc new file mode 100644 index 0000000..6abfc6a --- /dev/null +++ b/chrome/browser/media/webrtc/same_origin_observer.cc
@@ -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. + +#include "chrome/browser/media/webrtc/same_origin_observer.h" + +#include "base/callback.h" +#include "base/check.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/web_contents.h" +#include "url/gurl.h" +#include "url/origin.h" + +SameOriginObserver::SameOriginObserver( + content::WebContents* observed_contents, + const GURL& reference_origin, + base::RepeatingCallback<void(content::WebContents*)> + on_same_origin_state_changed, + bool check_before_commit) + : observed_contents_(observed_contents), + reference_origin_(reference_origin), + on_same_origin_state_changed_(on_same_origin_state_changed), + check_before_commit_(check_before_commit) { + DCHECK(observed_contents); + is_same_origin_ = url::IsSameOriginWith( + reference_origin_, observed_contents_->GetLastCommittedURL().GetOrigin()); + Observe(observed_contents); +} + +SameOriginObserver::~SameOriginObserver() = default; + +void SameOriginObserver::ReadyToCommitNavigation( + content::NavigationHandle* navigation_handle) { + if (check_before_commit_) { + CheckForOriginChanged(navigation_handle->GetURL().GetOrigin()); + } +} + +void SameOriginObserver::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (!check_before_commit_) { + CheckForOriginChanged( + observed_contents_->GetLastCommittedURL().GetOrigin()); + } +} + +void SameOriginObserver::CheckForOriginChanged(const GURL& new_origin) { + bool is_now_same_origin = + url::IsSameOriginWith(reference_origin_, new_origin); + if (is_same_origin_ != is_now_same_origin) { + is_same_origin_ = is_now_same_origin; + on_same_origin_state_changed_.Run(observed_contents_); + } +}
diff --git a/chrome/browser/media/webrtc/same_origin_observer.h b/chrome/browser/media/webrtc/same_origin_observer.h new file mode 100644 index 0000000..c810910a --- /dev/null +++ b/chrome/browser/media/webrtc/same_origin_observer.h
@@ -0,0 +1,52 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_MEDIA_WEBRTC_SAME_ORIGIN_OBSERVER_H_ +#define CHROME_BROWSER_MEDIA_WEBRTC_SAME_ORIGIN_OBSERVER_H_ + +#include "base/callback.h" +#include "content/public/browser/web_contents_observer.h" +#include "url/gurl.h" + +namespace content { +class WebContents; +} + +// This observer class will trigger the provided callback whenever the observed +// WebContents's origin either now or no longer matches the provided origin. +class SameOriginObserver : public content::WebContentsObserver { + public: + // The default behavior is that the observer will not trigger the callback + // until the navigation has been committed. This will ensure that + // WebContents::GetLastCommittedURL will return the new origin, and thus allow + // more simply re-using any code paths that set initial state. Setting + // |check_before_commit| will fire before the navigation has been fully + // committed, so that any actions that may be needed (i.e. to terminate a + // capture that no longer satisifes the SameOrigin requirement), can fire + // immediately. + SameOriginObserver(content::WebContents* observed_contents, + const GURL& reference_origin, + base::RepeatingCallback<void(content::WebContents*)> + on_same_origin_state_changed, + bool check_before_commit = false); + ~SameOriginObserver() override; + + // WebContentsObserver + void ReadyToCommitNavigation( + content::NavigationHandle* navigation_handle) override; + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + + private: + void CheckForOriginChanged(const GURL& new_origin); + + content::WebContents* const observed_contents_; + const GURL reference_origin_; + base::RepeatingCallback<void(content::WebContents*)> + on_same_origin_state_changed_; + const bool check_before_commit_; + bool is_same_origin_ = false; +}; + +#endif // CHROME_BROWSER_MEDIA_WEBRTC_SAME_ORIGIN_OBSERVER_H_
diff --git a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc index b9da0e19..84d6971 100644 --- a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
@@ -5,7 +5,6 @@ #include <string> #include "base/strings/stringprintf.h" -#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/media/webrtc/webrtc_browsertest_base.h" @@ -98,12 +97,7 @@ : public WebRtcScreenCaptureBrowserTest, public testing::WithParamInterface<TestConfigForPicker> { public: - WebRtcScreenCaptureBrowserTestWithPicker() : test_config_(GetParam()) { - if (test_config_.should_prefer_current_tab_) { - scoped_feature_list_.InitAndEnableFeature( - blink::features::kRTCGetCurrentBrowsingContextMedia); - } - } + WebRtcScreenCaptureBrowserTestWithPicker() : test_config_(GetParam()) {} void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch( @@ -128,7 +122,6 @@ } const TestConfigForPicker test_config_; - base::test::ScopedFeatureList scoped_feature_list_; }; // TODO(1170479): Real desktop capture is flaky on below platforms. @@ -228,12 +221,7 @@ : public WebRtcScreenCaptureBrowserTest, public testing::WithParamInterface<TestConfigForFakeUI> { public: - WebRtcScreenCaptureBrowserTestWithFakeUI() : test_config_(GetParam()) { - if (test_config_.should_prefer_current_tab_) { - scoped_feature_list_.InitAndEnableFeature( - blink::features::kRTCGetCurrentBrowsingContextMedia); - } - } + WebRtcScreenCaptureBrowserTestWithFakeUI() : test_config_(GetParam()) {} void SetUpCommandLine(base::CommandLine* command_line) override { command_line->AppendSwitch( @@ -252,7 +240,6 @@ protected: const TestConfigForFakeUI test_config_; - base::test::ScopedFeatureList scoped_feature_list_; }; IN_PROC_BROWSER_TEST_P(WebRtcScreenCaptureBrowserTestWithFakeUI, @@ -338,12 +325,7 @@ public: WebRtcScreenCapturePermissionPolicyBrowserTest() : tested_variant_(GetParam().first), - allowlisted_by_policy_(GetParam().second) { - if (tested_variant_ == GetDisplayMediaVariant::kPreferCurrentTab) { - scoped_feature_list_.InitAndEnableFeature( - blink::features::kRTCGetCurrentBrowsingContextMedia); - } - } + allowlisted_by_policy_(GetParam().second) {} ~WebRtcScreenCapturePermissionPolicyBrowserTest() override = default; @@ -363,7 +345,6 @@ const bool allowlisted_by_policy_; private: - base::test::ScopedFeatureList scoped_feature_list_; }; INSTANTIATE_TEST_SUITE_P(
diff --git a/chrome/browser/payments/secure_payment_confirmation_browsertest.cc b/chrome/browser/payments/secure_payment_confirmation_browsertest.cc index b66f58e8..51e55f4 100644 --- a/chrome/browser/payments/secure_payment_confirmation_browsertest.cc +++ b/chrome/browser/payments/secure_payment_confirmation_browsertest.cc
@@ -539,6 +539,9 @@ // crash. IN_PROC_BROWSER_TEST_P(SecurePaymentConfirmationCreationTestWithParameter, WebContentsClosedDuringEnrollmentBrowserPrompt) { + if (GetParam() == APIVersion::kApiV3) + return; + ReplaceFidoDiscoveryFactory(/*should_succeed=*/true); NavigateTo("a.com", "/secure_payment_confirmation.html"); ObserveEnrollmentController(); @@ -581,12 +584,15 @@ GetDefaultIconURL()))); // Verify that credential id size gets recorded. + int expected_enroll_histogram_value_ = + (GetParam() == APIVersion::kApiV3) ? 0 : 1; histogram_tester_.ExpectTotalCount( "PaymentRequest.SecurePaymentConfirmationCredentialIdSizeInBytes", 1U); ExpectEnrollDialogShown(SecurePaymentConfirmationEnrollDialogShown::kShown, - 1); + expected_enroll_histogram_value_); ExpectEnrollDialogResult( - SecurePaymentConfirmationEnrollDialogResult::kAccepted, 1); + SecurePaymentConfirmationEnrollDialogResult::kAccepted, + expected_enroll_histogram_value_); ExpectEnrollSystemPromptResult( SecurePaymentConfirmationEnrollSystemPromptResult::kAccepted, 1); ExpectNoFunnelCount(); @@ -647,10 +653,14 @@ EXPECT_EQ(1u, test_controller()->app_descriptions().size()); EXPECT_EQ("display_name_for_instrument", test_controller()->app_descriptions().front().label); + + int expected_enroll_histogram_value_ = + (GetParam() == APIVersion::kApiV3) ? 0 : 1; ExpectEnrollDialogShown(SecurePaymentConfirmationEnrollDialogShown::kShown, - 1); + expected_enroll_histogram_value_); ExpectEnrollDialogResult( - SecurePaymentConfirmationEnrollDialogResult::kAccepted, 1); + SecurePaymentConfirmationEnrollDialogResult::kAccepted, + expected_enroll_histogram_value_); ExpectEnrollSystemPromptResult( SecurePaymentConfirmationEnrollSystemPromptResult::kAccepted, 1); ExpectNoFunnelCount(); @@ -697,10 +707,14 @@ "postToIframe($1, $2);", https_server()->GetURL("c.com", "/iframe_receiver.html").spec(), credentialIdentifier))); + + int expected_enroll_histogram_value_ = + (GetParam() == APIVersion::kApiV3) ? 0 : 1; ExpectEnrollDialogShown(SecurePaymentConfirmationEnrollDialogShown::kShown, - 1); + expected_enroll_histogram_value_); ExpectEnrollDialogResult( - SecurePaymentConfirmationEnrollDialogResult::kAccepted, 1); + SecurePaymentConfirmationEnrollDialogResult::kAccepted, + expected_enroll_histogram_value_); ExpectEnrollSystemPromptResult( SecurePaymentConfirmationEnrollSystemPromptResult::kAccepted, 1); ExpectFunnelCount(SecurePaymentConfirmationSystemPromptResult::kAccepted, 1); @@ -757,10 +771,13 @@ "getTotalAmountFromClientDataWithModifierAndShowPromise($1, $2);", credentialIdentifier, "0.04"))); + int expected_enroll_histogram_value_ = + (GetParam() == APIVersion::kApiV3) ? 0 : 1; ExpectEnrollDialogShown(SecurePaymentConfirmationEnrollDialogShown::kShown, - 1); + expected_enroll_histogram_value_); ExpectEnrollDialogResult( - SecurePaymentConfirmationEnrollDialogResult::kAccepted, 1); + SecurePaymentConfirmationEnrollDialogResult::kAccepted, + expected_enroll_histogram_value_); ExpectEnrollSystemPromptResult( SecurePaymentConfirmationEnrollSystemPromptResult::kAccepted, 1); ExpectFunnelCount(SecurePaymentConfirmationSystemPromptResult::kAccepted, 4); @@ -792,10 +809,13 @@ content::JsReplace("getTotalAmountFromClientData($1, $2);", credentialIdentifier, "0.01"))); + int expected_enroll_histogram_value_ = + (GetParam() == APIVersion::kApiV3) ? 0 : 1; ExpectEnrollDialogShown(SecurePaymentConfirmationEnrollDialogShown::kShown, - 1); + expected_enroll_histogram_value_); ExpectEnrollDialogResult( - SecurePaymentConfirmationEnrollDialogResult::kAccepted, 1); + SecurePaymentConfirmationEnrollDialogResult::kAccepted, + expected_enroll_histogram_value_); ExpectEnrollSystemPromptResult( SecurePaymentConfirmationEnrollSystemPromptResult::kAccepted, 1); ExpectFunnelCount(SecurePaymentConfirmationSystemPromptResult::kCanceled, 1); @@ -804,6 +824,9 @@ IN_PROC_BROWSER_TEST_P(SecurePaymentConfirmationCreationTestWithParameter, NonexistentIcon) { + if (GetParam() == APIVersion::kApiV3) + return; + NavigateTo("a.com", "/secure_payment_confirmation.html"); ReplaceFidoDiscoveryFactory(/*should_succeed=*/true); @@ -866,10 +889,13 @@ histogram_tester_.ExpectTotalCount( "PaymentRequest.SecurePaymentConfirmationCredentialIdSizeInBytes", 2U); + int expected_enroll_histogram_value_ = + (GetParam() == APIVersion::kApiV3) ? 0 : 2; ExpectEnrollDialogShown(SecurePaymentConfirmationEnrollDialogShown::kShown, - 2); + expected_enroll_histogram_value_); ExpectEnrollDialogResult( - SecurePaymentConfirmationEnrollDialogResult::kAccepted, 2); + SecurePaymentConfirmationEnrollDialogResult::kAccepted, + expected_enroll_histogram_value_); ExpectEnrollSystemPromptResult( SecurePaymentConfirmationEnrollSystemPromptResult::kAccepted, 2); ExpectNoFunnelCount(); @@ -882,9 +908,13 @@ NavigateTo("a.com", "/secure_payment_confirmation.html"); RespondToFutureEnrollments(/*confirm=*/true); + std::list<Event> expected_events_ = + (GetParam() == APIVersion::kApiV3) + ? std::list<Event>{Event::AUTHENTICATOR_REQUEST} + : std::list<Event>{Event::ENROLLMENT_DIALOG_OPENED, + Event::AUTHENTICATOR_REQUEST}; event_waiter_ = - std::make_unique<autofill::EventWaiter<Event>>(std::list<Event>{ - Event::ENROLLMENT_DIALOG_OPENED, Event::AUTHENTICATOR_REQUEST}); + std::make_unique<autofill::EventWaiter<Event>>(expected_events_); ExecuteScriptAsync( GetActiveWebContents(), content::JsReplace("createPaymentCredential($1)", GetDefaultIconURL())); @@ -896,12 +926,19 @@ GetActiveWebContents()->Close(); event_waiter_->Wait(); + int expected_enroll_histogram_value_ = + (GetParam() == APIVersion::kApiV3) ? 0 : 1; ExpectEnrollDialogShown(SecurePaymentConfirmationEnrollDialogShown::kShown, - 1); + expected_enroll_histogram_value_); ExpectEnrollDialogResult( - SecurePaymentConfirmationEnrollDialogResult::kAccepted, 1); - ExpectEnrollSystemPromptResult( - SecurePaymentConfirmationEnrollSystemPromptResult::kCanceled, 1); + SecurePaymentConfirmationEnrollDialogResult::kAccepted, + expected_enroll_histogram_value_); + // In V3, PaymentCredential doesn't get created since the test leaves the + // authentication request idle, so skip this check. + if (GetParam() == APIVersion::kApiV2) { + ExpectEnrollSystemPromptResult( + SecurePaymentConfirmationEnrollSystemPromptResult::kCanceled, 1); + } ExpectNoFunnelCount(); ExpectJourneyLoggerEvent(/*spc_confirm_logged=*/false); } @@ -921,10 +958,13 @@ GetDefaultIconURL())) .ExtractString()); + int expected_enroll_histogram_value_ = + (GetParam() == APIVersion::kApiV3) ? 0 : 1; ExpectEnrollDialogShown(SecurePaymentConfirmationEnrollDialogShown::kShown, - 1); + expected_enroll_histogram_value_); ExpectEnrollDialogResult( - SecurePaymentConfirmationEnrollDialogResult::kAccepted, 1); + SecurePaymentConfirmationEnrollDialogResult::kAccepted, + expected_enroll_histogram_value_); ExpectEnrollSystemPromptResult( SecurePaymentConfirmationEnrollSystemPromptResult::kCanceled, 1); @@ -946,10 +986,12 @@ "getTotalAmountFromClientData($1, $2);", credentialIdentifier, "0.01"))); + expected_enroll_histogram_value_ = (GetParam() == APIVersion::kApiV3) ? 0 : 2; ExpectEnrollDialogShown(SecurePaymentConfirmationEnrollDialogShown::kShown, - 2); + expected_enroll_histogram_value_); ExpectEnrollDialogResult( - SecurePaymentConfirmationEnrollDialogResult::kAccepted, 2); + SecurePaymentConfirmationEnrollDialogResult::kAccepted, + expected_enroll_histogram_value_); histogram_tester_.ExpectTotalCount( "PaymentRequest.SecurePaymentConfirmation.Funnel." "EnrollSystemPromptResult", @@ -977,6 +1019,9 @@ IN_PROC_BROWSER_TEST_P(SecurePaymentConfirmationCreationTestWithParameter, WebContentsClosedDuringIconDownload) { + if (GetParam() == APIVersion::kApiV3) + return; + ReplaceFidoDiscoveryFactory(/*should_succeed=*/true); NavigateTo("a.com", "/secure_payment_confirmation.html");
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 31c2af0..a6dcc37f 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -1080,6 +1080,9 @@ { key::kAssistantOnboardingMode, chromeos::assistant::prefs::kAssistantOnboardingMode, base::Value::Type::STRING }, + { key::kAssistantVoiceMatchEnabledDuringOobe, + chromeos::assistant::prefs::kAssistantVoiceMatchEnabledDuringOobe, + base::Value::Type::BOOLEAN }, { key::kVoiceInteractionContextEnabled, chromeos::assistant::prefs::kAssistantContextEnabled, base::Value::Type::BOOLEAN },
diff --git a/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.cc b/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.cc index b1dc0a50..42cb9de 100644 --- a/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.cc +++ b/chrome/browser/prefetch/search_prefetch/base_search_prefetch_request.cc
@@ -144,10 +144,6 @@ // navigation, the request is relatively high priority. resource_request->priority = net::MEDIUM; resource_request->url = prefetch_url_; - // Search prefetch URL Loaders should check |report_raw_headers| on the - // intercepted request to clear out the raw headers when |report_raw_headers| - // is false. - resource_request->report_raw_headers = true; resource_request->credentials_mode = network::mojom::CredentialsMode::kInclude; resource_request->method = "GET";
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_from_string_url_loader.cc b/chrome/browser/prefetch/search_prefetch/search_prefetch_from_string_url_loader.cc index dd2161e0..31010d0 100644 --- a/chrome/browser/prefetch/search_prefetch/search_prefetch_from_string_url_loader.cc +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_from_string_url_loader.cc
@@ -110,10 +110,6 @@ return; } - if (!request.report_raw_headers) { - head_->raw_request_response_info = nullptr; - } - client_->OnReceiveResponse(std::move(head_)); client_->OnStartLoadingResponseBody(std::move(consumer_handle));
diff --git a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc index 3c380b4..11ef6be 100644 --- a/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc +++ b/chrome/browser/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
@@ -918,24 +918,6 @@ bool had_raw_request_info_ = false; }; -// A delegate to cancel prefetch requests by setting |defer| to true. -class HeaderObserverThrottle : public blink::URLLoaderThrottle { - public: - explicit HeaderObserverThrottle(HeaderObserverContentBrowserClient* client) - : client_(client) {} - ~HeaderObserverThrottle() override = default; - - void WillProcessResponse(const GURL& response_url, - network::mojom::URLResponseHead* response_head, - bool* defer) override { - client_->set_had_raw_request_info( - !!response_head->raw_request_response_info); - } - - private: - HeaderObserverContentBrowserClient* client_; -}; - std::vector<std::unique_ptr<blink::URLLoaderThrottle>> HeaderObserverContentBrowserClient::CreateURLLoaderThrottles( const network::ResourceRequest& request, @@ -947,7 +929,6 @@ ChromeContentBrowserClient::CreateURLLoaderThrottles( request, browser_context, wc_getter, navigation_ui_data, frame_tree_node_id); - throttles.push_back(std::make_unique<HeaderObserverThrottle>(this)); return throttles; } @@ -980,37 +961,6 @@ } IN_PROC_BROWSER_TEST_P(SearchPrefetchServiceEnabledBrowserTest, - HeadersReportedFromNetworkWithDevTools) { - auto* search_prefetch_service = - SearchPrefetchServiceFactory::GetForProfile(browser()->profile()); - EXPECT_NE(nullptr, search_prefetch_service); - - std::string search_terms = "prefetch_content"; - - GURL prefetch_url = GetSearchServerQueryURL(search_terms); - - EXPECT_TRUE(search_prefetch_service->MaybePrefetchURL(prefetch_url)); - auto prefetch_status = - search_prefetch_service->GetSearchPrefetchStatusForTesting( - base::ASCIIToUTF16(search_terms)); - ASSERT_TRUE(prefetch_status.has_value()); - EXPECT_EQ(SearchPrefetchStatus::kInFlight, prefetch_status.value()); - - WaitUntilStatusChangesTo(base::ASCIIToUTF16(search_terms), - SearchPrefetchStatus::kComplete); - - OpenDevToolsWindow(browser()->tab_strip_model()->GetActiveWebContents()); - - HeaderObserverContentBrowserClient browser_client; - auto* old_client = content::SetBrowserClientForTesting(&browser_client); - ui_test_utils::NavigateToURL(browser(), prefetch_url); - - EXPECT_TRUE(browser_client.had_raw_request_info()); - CloseDevToolsWindow(); - content::SetBrowserClientForTesting(old_client); -} - -IN_PROC_BROWSER_TEST_P(SearchPrefetchServiceEnabledBrowserTest, PrefetchRateLimiting) { base::HistogramTester histogram_tester; auto* search_prefetch_service =
diff --git a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc index 09a8f5c..07f4e5cd 100644 --- a/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc +++ b/chrome/browser/prefetch/search_prefetch/streaming_search_prefetch_url_loader.cc
@@ -82,10 +82,6 @@ weak_factory_.GetWeakPtr())); forwarding_client_.Bind(std::move(forwarding_client)); - if (!resource_request.report_raw_headers) { - resource_response_->raw_request_response_info = nullptr; - } - // We are serving, so if the request is complete before serving, mark the // request completion time as now. if (status_) {
diff --git a/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc b/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc index 2cbbffe..29173ad 100644 --- a/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc +++ b/chrome/browser/printing/pdf_to_emf_converter_browsertest.cc
@@ -445,4 +445,22 @@ "bezier.emf"); } +IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest, PostScriptLevel2Image) { + const PdfRenderSettings pdf_settings( + kLetter200DpiRect, gfx::Point(0, 0), k200DpiSize, + /*autorotate=*/false, /*use_color=*/true, + PdfRenderSettings::Mode::POSTSCRIPT_LEVEL2); + RunSinglePagePdfToPostScriptConverterTest(pdf_settings, "embedded_images.pdf", + "embedded_images_ps_level2.emf"); +} + +IN_PROC_BROWSER_TEST_F(PdfToEmfConverterBrowserTest, PostScriptLevel3Image) { + const PdfRenderSettings pdf_settings( + kLetter200DpiRect, gfx::Point(0, 0), k200DpiSize, + /*autorotate=*/false, /*use_color=*/true, + PdfRenderSettings::Mode::POSTSCRIPT_LEVEL3); + RunSinglePagePdfToPostScriptConverterTest(pdf_settings, "embedded_images.pdf", + "embedded_images_ps_level3.emf"); +} + } // namespace printing
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index a1b52912..79d09a0 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -131,6 +131,7 @@ #include "components/translate/core/browser/translate_download_manager.h" #include "components/translate/core/browser/translate_manager.h" #include "components/translate/core/browser/translate_prefs.h" +#include "components/ukm/content/source_url_recorder.h" #include "components/url_formatter/url_formatter.h" #include "components/user_prefs/user_prefs.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" @@ -155,6 +156,8 @@ #include "pdf/buildflags.h" #include "ppapi/buildflags/buildflags.h" #include "printing/buildflags/buildflags.h" +#include "services/metrics/public/cpp/ukm_builders.h" +#include "services/metrics/public/cpp/ukm_recorder.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/context_menu_data/context_menu_data.h" @@ -1080,6 +1083,19 @@ } } + // Log UKM for Lens context menu items. + if ((id == IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH && + lens::features::GetEnableUKMLoggingForRegionSearch()) || + (id == IDC_CONTENT_CONTEXT_SEARCHLENSFORIMAGE && + lens::features::GetEnableUKMLoggingForImageSearch())) { + // Enum id should correspond to the RenderViewContextMenuItem enum. + ukm::SourceId source_id = + ukm::GetSourceIdForWebContentsDocument(source_web_contents_); + ukm::builders::RenderViewContextMenu_Used(source_id) + .SetSelectedMenuItem(enum_id) + .Record(ukm::UkmRecorder::Get()); + } + // Log for specific contexts. Note that since the menu is displayed for // contexts (all of the ContextMenuContentType::SupportsXXX() functions), // these UMA metrics are necessarily best-effort in distilling into a context.
diff --git a/chrome/browser/resources/read_later/app.html b/chrome/browser/resources/read_later/app.html index d2e0b1e..67601bf 100644 --- a/chrome/browser/resources/read_later/app.html +++ b/chrome/browser/resources/read_later/app.html
@@ -47,7 +47,7 @@ var(--cr-hover-background-color)); --hover-border-color: var(--border-color); border-radius: 4px; - margin: 0 16px 16px; + margin: 0 16px 24px; padding: 8px; transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1); } @@ -63,7 +63,13 @@ } :host([side-panel]) #currentPageActionButton { - margin: 4px 16px 0 16px; + margin: 8px 16px 0 16px; + } + + #empty-state-container:not([hidden]) ~ #currentPageActionButton { + display: flex; + margin: 8px auto 0 auto; + width: fit-content; } #currentPageActionButtonIcon { @@ -79,7 +85,6 @@ margin-inline-end: auto; } - .mwb-list-item:focus-within { background-color: var(--mwb-list-item-hover-background-color); } @@ -119,7 +124,6 @@ #empty-state-image { content: url(images/read_later_empty.svg); margin-bottom: 8px; - margin-top: 48px; width: 240px; } @@ -142,6 +146,10 @@ line-height: 20px; padding: 4px var(--mwb-list-item-horizontal-margin) 24px; } + + :host([side-panel]) #empty-state-subheader { + padding-bottom: 8px; + } </style> <div id="top-container"> @@ -153,8 +161,15 @@ on-click="onCloseClick_" title="$i18n{tooltipClose}"> </cr-icon-button> </div> +<div id="empty-state-container" + hidden="[[!isReadingListEmpty_(unreadItems_, readItems_)]]"> + <img id="empty-state-image" aria-hidden="true"> + <div id="empty-state-header">$i18n{emptyStateHeader}</div> + <div id="empty-state-subheader">$i18n{emptyStateSubheader}</div> +</div> <cr-button id="currentPageActionButton" - class$="[[getCurrentPageActionButtonClass_(currentPageActionButtonState_)]]" + class$="[[getCurrentPageActionButtonClass_( + currentPageActionButtonState_)]]" hidden$="[[!shouldShowCurrentPageActionButton_()]]" aria-label="[[getCurrentPageActionButtonText_( currentPageActionButtonState_)]]" @@ -194,9 +209,3 @@ </template> </iron-selector> </div> -<div id="empty-state-container" - hidden="[[!isReadingListEmpty_(unreadItems_, readItems_)]]"> - <img id="empty-state-image" aria-hidden="true"> - <div id="empty-state-header">$i18n{emptyStateHeader}</div> - <div id="empty-state-subheader">$i18n{emptyStateSubheader}</div> -</div>
diff --git a/chrome/browser/resources/read_later/app.js b/chrome/browser/resources/read_later/app.js index 4555fbb6..c29ebc3 100644 --- a/chrome/browser/resources/read_later/app.js +++ b/chrome/browser/resources/read_later/app.js
@@ -218,11 +218,14 @@ * @private */ getCurrentPageActionButtonIcon_(addIcon, removeIcon) { - if (this.currentPageActionButtonState_ === - readLater.mojom.CurrentPageActionButtonState.kRemove) { - return removeIcon; + switch (this.currentPageActionButtonState_) { + case readLater.mojom.CurrentPageActionButtonState.kAdd: + return addIcon; + case readLater.mojom.CurrentPageActionButtonState.kRemove: + case readLater.mojom.CurrentPageActionButtonState.kDisabled: + default: + return removeIcon; } - return addIcon; } /**
diff --git a/chrome/browser/resources/settings/chromeos/BUILD.gn b/chrome/browser/resources/settings/chromeos/BUILD.gn index 1433328..b6b918b 100644 --- a/chrome/browser/resources/settings/chromeos/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/BUILD.gn
@@ -236,6 +236,7 @@ "chromeos/os_printing_page/cups_printer_types.js", "chromeos/os_printing_page/cups_printers_browser_proxy.js", "chromeos/os_printing_page/cups_printers_entry_manager.js", + "chromeos/os_search_page/search_engines_browser_proxy.js", "chromeos/bluetooth_page/bluetooth_page_browser_proxy.js", "chromeos/os_reset_page/os_reset_browser_proxy.js", "chromeos/os_settings.js", @@ -258,7 +259,6 @@ "prefs/pref_util.js", "privacy_page/privacy_page_browser_proxy.js", "router.js", - "search_engines_page/search_engines_browser_proxy.js", ] }
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn index d07bc37..5956dfe01 100644 --- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/BUILD.gn
@@ -38,6 +38,7 @@ "..:os_route.m", "../..:router", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", + "//ui/webui/resources/cr_components/chromeos/bluetooth:cros_bluetooth_config", "//ui/webui/resources/js:i18n_behavior.m", ] }
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_page.html b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_page.html index d06d38a6..7fde50a 100644 --- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_page.html +++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_page.html
@@ -2,7 +2,7 @@ </style> <settings-animated-pages id="pages" section="bluetooth"> <div route-path="default"> - <os-settings-bluetooth-summary> + <os-settings-bluetooth-summary system-properties="[[systemProperties_]]"> </os-settings-bluetooth-summary> </div> <template is="dom-if" route-path="/bluetoothDevices">
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.html b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.html index 34257584..9c73f17 100644 --- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.html +++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.html
@@ -19,6 +19,13 @@ aria-roledescription="$i18n{subpageArrowRoleDescription}"> </cr-icon-button> </div> + <div class="separator"></div> + <cr-toggle id="enableBluetoothToggle" + class="margin-matches-padding" + checked="{{isBluetoothToggleOn_}}" + disabled$="[[isToggleDisabled_(systemProperties.systemState)]]" + aria-label="$i18n{bluetoothToggleA11yLabel}"> + </cr-toggle> </div> <div id="pairNewDevice" class="settings-box no-padding">
diff --git a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.js b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.js index 17bf5418..c93fb94 100644 --- a/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.js +++ b/chrome/browser/resources/settings/chromeos/os_bluetooth_page/os_bluetooth_summary.js
@@ -13,11 +13,14 @@ import {I18nBehavior, I18nBehaviorInterface} from '//resources/js/i18n_behavior.m.js'; import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {getBluetoothConfig} from 'chrome://resources/cr_components/chromeos/bluetooth/cros_bluetooth_config.js'; import {loadTimeData} from '../../i18n_setup.js'; import {Router} from '../../router.js'; import {routes} from '../os_route.m.js'; +const mojom = chromeos.bluetoothConfig.mojom; + /** * @constructor * @extends {PolymerElement} @@ -37,6 +40,56 @@ return html`{__html_template__}`; } + static get properties() { + return { + /** + * @type {?chromeos.bluetoothConfig.mojom.BluetoothSystemProperties} + */ + systemProperties: { + type: Object, + observer: 'onSystemPropertiesChanged_', + }, + + /** + * Reflects the current state of the toggle button. This will be set when + * the |systemProperties| state changes or when the user presses the + * toggle. + * @private + */ + isBluetoothToggleOn_: { + type: Boolean, + observer: 'onBluetoothToggleChanged_', + }, + }; + } + + /** @private */ + onSystemPropertiesChanged_() { + if (this.isToggleDisabled_()) { + return; + } + this.isBluetoothToggleOn_ = this.systemProperties.systemState === + mojom.BluetoothSystemState.kEnabled || + this.systemProperties.systemState === + mojom.BluetoothSystemState.kEnabling; + } + + /** @private */ + onBluetoothToggleChanged_() { + getBluetoothConfig().setBluetoothEnabledState(this.isBluetoothToggleOn_); + } + + /** + * @return {boolean} + * @private + */ + isToggleDisabled_() { + // TODO(crbug.com/1010321): Add check for modification state when variable + // is available. + return this.systemProperties.systemState === + mojom.BluetoothSystemState.kUnavailable; + } + /** * @param {!Event} e * @private
diff --git a/chrome/browser/resources/settings/chromeos/os_search_page/BUILD.gn b/chrome/browser/resources/settings/chromeos/os_search_page/BUILD.gn index 5f2ff6f..61dd0cec 100644 --- a/chrome/browser/resources/settings/chromeos/os_search_page/BUILD.gn +++ b/chrome/browser/resources/settings/chromeos/os_search_page/BUILD.gn
@@ -25,8 +25,8 @@ "//chrome/browser/resources/settings/chromeos:deep_linking_behavior.m", "//chrome/browser/resources/settings/chromeos:os_route.m", "//chrome/browser/resources/settings/chromeos/google_assistant_page:google_assistant_page", + "//chrome/browser/resources/settings/chromeos/os_search_page:search_engines_browser_proxy", "//chrome/browser/resources/settings/controls:extension_controlled_indicator", - "//chrome/browser/resources/settings/search_engines_page:search_engines_browser_proxy", "//chrome/browser/resources/settings/settings_page:settings_animated_pages", "//chrome/browser/resources/settings/settings_page:settings_subpage", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", @@ -44,7 +44,7 @@ js_library("os_search_selection_dialog.m") { sources = [ "$root_gen_dir/chrome/browser/resources/settings/chromeos/os_search_page/os_search_selection_dialog.m.js" ] deps = [ - "//chrome/browser/resources/settings/search_engines_page:search_engines_browser_proxy", + "//chrome/browser/resources/settings/chromeos/os_search_page:search_engines_browser_proxy", "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", "//ui/webui/resources/cr_elements/cr_button:cr_button.m", "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog.m", @@ -89,6 +89,10 @@ extra_deps = [ ":search_engine_module" ] } +js_library("search_engines_browser_proxy") { + deps = [ "//ui/webui/resources/js:cr.m" ] +} + group("polymer3_elements") { public_deps = [ ":os_search_page_module",
diff --git a/chrome/browser/resources/settings/chromeos/os_search_page/os_search_page.html b/chrome/browser/resources/settings/chromeos/os_search_page/os_search_page.html index 84a78106..9b59396 100644 --- a/chrome/browser/resources/settings/chromeos/os_search_page/os_search_page.html +++ b/chrome/browser/resources/settings/chromeos/os_search_page/os_search_page.html
@@ -13,7 +13,7 @@ <link rel="import" href="os_search_selection_dialog.html"> <link rel="import" href="../../controls/extension_controlled_indicator.html"> <link rel="import" href="../../router.html"> -<link rel="import" href="../../search_engines_page/search_engines_browser_proxy.html"> +<link rel="import" href="search_engines_browser_proxy.html"> <link rel="import" href="../../settings_page/settings_animated_pages.html"> <link rel="import" href="../../settings_page/settings_subpage.html"> <link rel="import" href="../../settings_shared_css.html">
diff --git a/chrome/browser/resources/settings/chromeos/os_search_page/os_search_selection_dialog.html b/chrome/browser/resources/settings/chromeos/os_search_page/os_search_selection_dialog.html index 87688ff..6f61f23a 100644 --- a/chrome/browser/resources/settings/chromeos/os_search_page/os_search_selection_dialog.html +++ b/chrome/browser/resources/settings/chromeos/os_search_page/os_search_selection_dialog.html
@@ -6,7 +6,7 @@ <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/load_time_data.html">> -<link rel="import" href="../../search_engines_page/search_engines_browser_proxy.html"> +<link rel="import" href="search_engines_browser_proxy.html"> <link rel="import" href="../../settings_shared_css.html"> <dom-module id="os-settings-search-selection-dialog"> @@ -53,4 +53,4 @@ </cr-dialog> </template> <script src="os_search_selection_dialog.js"></script> -</dom-module> \ No newline at end of file +</dom-module>
diff --git a/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.html b/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.html index 815f502..920ff8f 100644 --- a/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.html +++ b/chrome/browser/resources/settings/chromeos/os_search_page/search_engine.html
@@ -18,7 +18,7 @@ <link rel="import" href="../../prefs/prefs_behavior.html"> <link rel="import" href="../../prefs/pref_util.html"> <link rel="import" href="../../router.html"> -<link rel="import" href="../../search_engines_page/search_engines_browser_proxy.html"> +<link rel="import" href="search_engines_browser_proxy.html"> <link rel="import" href="../../settings_shared_css.html"> <link rel="import" href="../../settings_vars_css.html"> <link rel="import" href="../os_route.html">
diff --git a/chrome/browser/resources/settings/chromeos/os_search_page/search_engines_browser_proxy.js b/chrome/browser/resources/settings/chromeos/os_search_page/search_engines_browser_proxy.js new file mode 100644 index 0000000..5ea0c51 --- /dev/null +++ b/chrome/browser/resources/settings/chromeos/os_search_page/search_engines_browser_proxy.js
@@ -0,0 +1,72 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// clang-format off +import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js'; +// clang-format on + +/** + * @fileoverview A helper object used from the "Manage search engines" section + * to interact with the browser. + */ + +/** + * @typedef {{canBeDefault: boolean, + * canBeEdited: boolean, + * canBeRemoved: boolean, + * default: boolean, + * displayName: string, + * extension: ({id: string, + * name: string, + * canBeDisabled: boolean, + * icon: string}|undefined), + * iconURL: (string|undefined), + * id: number, + * isOmniboxExtension: boolean, + * keyword: string, + * modelIndex: number, + * name: string, + * url: string, + * urlLocked: boolean}} + * @see chrome/browser/ui/webui/settings/search_engine_manager_handler.cc + */ +export let SearchEngine; + +/** + * @typedef {{ + * defaults: !Array<!SearchEngine>, + * actives: !Array<!SearchEngine>, + * others: !Array<!SearchEngine>, + * extensions: !Array<!SearchEngine> + * }} + */ +export let SearchEnginesInfo; + +/** @interface */ +export class SearchEnginesBrowserProxy { + /** @param {number} modelIndex */ + setDefaultSearchEngine(modelIndex) {} + + /** @return {!Promise<!SearchEnginesInfo>} */ + getSearchEnginesList() {} +} + +/** + * @implements {SearchEnginesBrowserProxy} + */ +export class SearchEnginesBrowserProxyImpl { + /** @override */ + setDefaultSearchEngine(modelIndex) { + chrome.send('setDefaultSearchEngine', [modelIndex]); + } + + /** @override */ + getSearchEnginesList() { + return sendWithPromise('getSearchEnginesList'); + } +} + +// The singleton instance_ is replaced with a test version of this wrapper +// during testing. +addSingletonGetter(SearchEnginesBrowserProxyImpl);
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.gni b/chrome/browser/resources/settings/chromeos/os_settings.gni index 9c180999..3c325cc 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.gni +++ b/chrome/browser/resources/settings/chromeos/os_settings.gni
@@ -246,7 +246,7 @@ "chrome/browser/resources/settings/people_page/sync_browser_proxy.html|SyncBrowserProxyImpl,SyncBrowserProxy,StatusAction,SyncStatus,SyncPrefs", "chrome/browser/resources/settings/route.html|routes", "chrome/browser/resources/settings/router.html|Router,Route,RouteObserverBehavior", - "chrome/browser/resources/settings/search_engines_page/search_engines_browser_proxy.html|SearchEngine,SearchEnginesBrowserProxy,SearchEnginesBrowserProxyImpl", + "chrome/browser/resources/settings/chromeos/os_search_page/search_engines_browser_proxy.html|SearchEngine,SearchEnginesBrowserProxy,SearchEnginesBrowserProxyImpl", "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_browser_proxy.html|CupsPrintersBrowserProxy,CupsPrintersBrowserProxyImpl,CupsPrinterInfo,PrinterSetupResult,CupsPrintersList,PrinterPpdMakeModel,ManufacturersInfo,ModelsInfo,PrintServerResult,PrinterMakeModel", "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_list_behavior.html|CupsPrintersEntryListBehavior", "chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry_manager.html|CupsPrintersEntryManager", @@ -367,6 +367,7 @@ "chrome/browser/resources/settings/chromeos/os_reset_page/os_powerwash_dialog_esim_item.html", "chrome/browser/resources/settings/chromeos/os_reset_page/os_reset_browser_proxy.html", "chrome/browser/resources/settings/chromeos/os_reset_page/os_reset_page.html", + "chrome/browser/resources/settings/chromeos/os_search_page/search_engines_browser_proxy.html", "chrome/browser/resources/settings/chromeos/personalization_page/change_picture_browser_proxy.html", "chrome/browser/resources/settings/chromeos/personalization_page/wallpaper_browser_proxy.html", "chrome/browser/resources/settings/chromeos/keyboard_shortcut_banner/keyboard_shortcut_banner.html", @@ -403,7 +404,6 @@ "chrome/browser/resources/settings/privacy_page/secure_dns.html", "chrome/browser/resources/settings/privacy_page/secure_dns_input.html", "chrome/browser/resources/settings/router.html", - "chrome/browser/resources/settings/search_engines_page/search_engines_browser_proxy.html", "chrome/browser/resources/settings/setting_id_param_util.html", "chrome/browser/resources/settings/settings_main/settings_main.html", "chrome/browser/resources/settings/settings_menu/settings_menu.html",
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.js b/chrome/browser/resources/settings/chromeos/os_settings.js index d1e3cd1..9b874cf 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.js +++ b/chrome/browser/resources/settings/chromeos/os_settings.js
@@ -97,7 +97,6 @@ export {CrSettingsPrefs} from '../prefs/prefs_types.js'; export {PrivacyPageBrowserProxy, PrivacyPageBrowserProxyImpl, ResolverOption, SecureDnsMode, SecureDnsSetting, SecureDnsUiManagementMode} from '../privacy_page/privacy_page_browser_proxy.js'; export {Route, Router} from '../router.js'; -export {SearchEngine, SearchEnginesBrowserProxy, SearchEnginesBrowserProxyImpl, SearchEnginesInfo} from '../search_engines_page/search_engines_browser_proxy.js'; export {getContactManager, observeContactManager, setContactManagerForTesting} from '../shared/nearby_contact_manager.m.js'; export {getNearbyShareSettings, observeNearbyShareSettings, setNearbyShareSettingsForTesting} from '../shared/nearby_share_settings.m.js'; export {NearbySettings, NearbyShareSettingsBehavior} from '../shared/nearby_share_settings_behavior.m.js'; @@ -138,6 +137,7 @@ export {DataAccessPolicyState, PeripheralDataAccessBrowserProxy, PeripheralDataAccessBrowserProxyImpl} from './os_privacy_page/peripheral_data_access_browser_proxy.js'; export {OsResetBrowserProxyImpl} from './os_reset_page/os_reset_browser_proxy.js'; export {routes} from './os_route.m.js'; +export {SearchEngine, SearchEnginesBrowserProxy, SearchEnginesBrowserProxyImpl, SearchEnginesInfo} from './os_search_page/search_engines_browser_proxy.js'; export {ParentalControlsBrowserProxy, ParentalControlsBrowserProxyImpl} from './parental_controls_page/parental_controls_browser_proxy.m.js'; export {ChangePictureBrowserProxy, ChangePictureBrowserProxyImpl} from './personalization_page/change_picture_browser_proxy.js'; export {WallpaperBrowserProxyImpl} from './personalization_page/wallpaper_browser_proxy.js';
diff --git a/chrome/browser/safe_browsing/android/password_reuse_controller_android.cc b/chrome/browser/safe_browsing/android/password_reuse_controller_android.cc index c76c1498..71edf4d 100644 --- a/chrome/browser/safe_browsing/android/password_reuse_controller_android.cc +++ b/chrome/browser/safe_browsing/android/password_reuse_controller_android.cc
@@ -51,10 +51,20 @@ } void PasswordReuseControllerAndroid::ShowCheckPasswords() { - JNIEnv* env = base::android::AttachCurrentThread(); + // TODO(rsamp) Move the below launch code to HandleUserActionOnModalWarning() + // in ChromePasswordProtectionService. - PasswordCheckupLauncherHelper::LaunchLocalCheckupFromPhishGuardWarningDialog( - env, window_android_->GetJavaObject()); + if (password_type_.account_type() == + ReusedPasswordAccountType::SAVED_PASSWORD && + base::FeatureList::IsEnabled( + safe_browsing:: + kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid)) { + JNIEnv* env = base::android::AttachCurrentThread(); + + PasswordCheckupLauncherHelper:: + LaunchLocalCheckupFromPhishGuardWarningDialog( + env, window_android_->GetJavaObject()); + } if (done_callback_) std::move(done_callback_).Run(WarningAction::CHANGE_PASSWORD); @@ -77,20 +87,38 @@ } std::u16string PasswordReuseControllerAndroid::GetPrimaryButtonText() const { - return base::FeatureList::IsEnabled( - safe_browsing:: - kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid) - ? l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHECK_PASSWORDS_BUTTON) - : l10n_util::GetStringUTF16(IDS_CLOSE); + if (password_type_.account_type() == ReusedPasswordAccountType::GMAIL && + password_type_.is_account_syncing() && + base::FeatureList::IsEnabled( + safe_browsing::kPasswordProtectionForSignedInUsers)) { + return l10n_util::GetStringUTF16(IDS_PAGE_INFO_PROTECT_ACCOUNT_BUTTON); + } else if ( + password_type_.account_type() == + ReusedPasswordAccountType::SAVED_PASSWORD && + base::FeatureList::IsEnabled( + safe_browsing:: + kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid)) { + return l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHECK_PASSWORDS_BUTTON); + } + + return l10n_util::GetStringUTF16(IDS_CLOSE); } std::u16string PasswordReuseControllerAndroid::GetSecondaryButtonText() const { - return base::FeatureList::IsEnabled( - safe_browsing:: - kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid) - ? l10n_util::GetStringUTF16( - IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON) - : std::u16string(); + if ((password_type_.account_type() == ReusedPasswordAccountType::GMAIL && + password_type_.is_account_syncing() && + base::FeatureList::IsEnabled( + safe_browsing::kPasswordProtectionForSignedInUsers)) || + (password_type_.account_type() == + ReusedPasswordAccountType::SAVED_PASSWORD && + base::FeatureList::IsEnabled( + safe_browsing:: + kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid))) { + return l10n_util::GetStringUTF16( + IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON); + } + + return std::u16string(); } std::u16string PasswordReuseControllerAndroid::GetWarningDetailText( @@ -136,4 +164,9 @@ delete this; } +void PasswordReuseControllerAndroid::SetReusedPasswordAccountTypeForTesting( + ReusedPasswordAccountType password_type) { + password_type_ = password_type; +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/android/password_reuse_controller_android.h b/chrome/browser/safe_browsing/android/password_reuse_controller_android.h index e3f0b97..f35b3e2 100644 --- a/chrome/browser/safe_browsing/android/password_reuse_controller_android.h +++ b/chrome/browser/safe_browsing/android/password_reuse_controller_android.h
@@ -77,11 +77,14 @@ // content::WebContentsObserver: void WebContentsDestroyed() override; + void SetReusedPasswordAccountTypeForTesting( + ReusedPasswordAccountType password_type); + private: std::unique_ptr<PasswordReuseDialogViewAndroid> dialog_view_; ChromePasswordProtectionService* service_; const GURL url_; - const ReusedPasswordAccountType password_type_; + ReusedPasswordAccountType password_type_; ui::WindowAndroid* window_android_; OnWarningDone done_callback_;
diff --git a/chrome/browser/safe_browsing/android/password_reuse_controller_android_unittest.cc b/chrome/browser/safe_browsing/android/password_reuse_controller_android_unittest.cc index f8d24d1..c943e13 100644 --- a/chrome/browser/safe_browsing/android/password_reuse_controller_android_unittest.cc +++ b/chrome/browser/safe_browsing/android/password_reuse_controller_android_unittest.cc
@@ -46,19 +46,13 @@ WarningAction warning_action) { ASSERT_EQ(expected_action_warning, warning_action); } - - protected: - base::test::ScopedFeatureList scoped_feature_list_; - ReusedPasswordAccountType reused_password_account_type_; }; TEST_F(PasswordReuseControllerAndroidTest, ClickedIgnore) { - reused_password_account_type_.set_is_account_syncing(true); - reused_password_account_type_.set_account_type( - ReusedPasswordAccountType::SAVED_PASSWORD); + ReusedPasswordAccountType password_type; MakeController( - nullptr, reused_password_account_type_, + nullptr, password_type, base::BindOnce( &PasswordReuseControllerAndroidTest::AssertWarningActionEquality, base::Unretained(this), WarningAction::IGNORE_WARNING)) @@ -66,50 +60,210 @@ } TEST_F(PasswordReuseControllerAndroidTest, ClickedClose) { - reused_password_account_type_.set_is_account_syncing(true); - reused_password_account_type_.set_account_type( - ReusedPasswordAccountType::SAVED_PASSWORD); + ReusedPasswordAccountType password_type; MakeController( - nullptr, reused_password_account_type_, + nullptr, password_type, base::BindOnce( &PasswordReuseControllerAndroidTest::AssertWarningActionEquality, base::Unretained(this), WarningAction::CLOSE)) ->CloseDialog(); } -TEST_F(PasswordReuseControllerAndroidTest, ButtonTextWithFlagEnabled) { - scoped_feature_list_.InitAndEnableFeature( - safe_browsing:: - kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid); - +TEST_F(PasswordReuseControllerAndroidTest, VerifyButtonText) { MockOnWarningDone empty_callback; + ReusedPasswordAccountType password_type; - PasswordReuseControllerAndroid* controller = MakeController( - nullptr, reused_password_account_type_, empty_callback.Get()); + PasswordReuseControllerAndroid* controller = + MakeController(nullptr, password_type, empty_callback.Get()); - ASSERT_EQ(l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHECK_PASSWORDS_BUTTON), - controller->GetPrimaryButtonText()); - ASSERT_EQ( - l10n_util::GetStringUTF16(IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON), - controller->GetSecondaryButtonText()); + { + ASSERT_EQ(l10n_util::GetStringUTF16(IDS_CLOSE), + controller->GetPrimaryButtonText()); + ASSERT_EQ(std::u16string(), controller->GetSecondaryButtonText()); + } - delete controller; -} + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {safe_browsing:: + kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid}, + {}); -TEST_F(PasswordReuseControllerAndroidTest, ButtonTextWithFlagDisabled) { - scoped_feature_list_.InitAndDisableFeature( - safe_browsing:: - kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid); + password_type.set_account_type(ReusedPasswordAccountType::SAVED_PASSWORD); + password_type.set_is_account_syncing(false); - MockOnWarningDone empty_callback; + controller->SetReusedPasswordAccountTypeForTesting(password_type); - PasswordReuseControllerAndroid* controller = MakeController( - nullptr, reused_password_account_type_, empty_callback.Get()); + ASSERT_EQ(l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHECK_PASSWORDS_BUTTON), + controller->GetPrimaryButtonText()); + ASSERT_EQ( + l10n_util::GetStringUTF16(IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON), + controller->GetSecondaryButtonText()); + } - ASSERT_EQ(l10n_util::GetStringUTF16(IDS_CLOSE), - controller->GetPrimaryButtonText()); - ASSERT_EQ(std::u16string(), controller->GetSecondaryButtonText()); + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {safe_browsing:: + kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid}, + {}); + + password_type.set_account_type(ReusedPasswordAccountType::GMAIL); + password_type.set_is_account_syncing(true); + + controller->SetReusedPasswordAccountTypeForTesting(password_type); + + ASSERT_EQ(l10n_util::GetStringUTF16(IDS_CLOSE), + controller->GetPrimaryButtonText()); + ASSERT_EQ(std::u16string(), controller->GetSecondaryButtonText()); + } + + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {safe_browsing::kPasswordProtectionForSignedInUsers}, {}); + + password_type.set_account_type(ReusedPasswordAccountType::SAVED_PASSWORD); + password_type.set_is_account_syncing(false); + + controller->SetReusedPasswordAccountTypeForTesting(password_type); + + ASSERT_EQ(l10n_util::GetStringUTF16(IDS_CLOSE), + controller->GetPrimaryButtonText()); + ASSERT_EQ(std::u16string(), controller->GetSecondaryButtonText()); + } + + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {safe_browsing::kPasswordProtectionForSignedInUsers}, {}); + + password_type.set_account_type(ReusedPasswordAccountType::GMAIL); + password_type.set_is_account_syncing(true); + + controller->SetReusedPasswordAccountTypeForTesting(password_type); + + ASSERT_EQ(l10n_util::GetStringUTF16(IDS_PAGE_INFO_PROTECT_ACCOUNT_BUTTON), + controller->GetPrimaryButtonText()); + ASSERT_EQ( + l10n_util::GetStringUTF16(IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON), + controller->GetSecondaryButtonText()); + } + + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {safe_browsing:: + kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid, + safe_browsing::kPasswordProtectionForSignedInUsers}, + {}); + + ReusedPasswordAccountType empty_reused_password; + controller->SetReusedPasswordAccountTypeForTesting(empty_reused_password); + + ASSERT_EQ(l10n_util::GetStringUTF16(IDS_CLOSE), + controller->GetPrimaryButtonText()); + ASSERT_EQ(std::u16string(), controller->GetSecondaryButtonText()); + } + + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {safe_browsing:: + kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid, + safe_browsing::kPasswordProtectionForSignedInUsers}, + {}); + + password_type.set_account_type(ReusedPasswordAccountType::SAVED_PASSWORD); + password_type.set_is_account_syncing(false); + + controller->SetReusedPasswordAccountTypeForTesting(password_type); + + ASSERT_EQ(l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHECK_PASSWORDS_BUTTON), + controller->GetPrimaryButtonText()); + ASSERT_EQ( + l10n_util::GetStringUTF16(IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON), + controller->GetSecondaryButtonText()); + } + + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {safe_browsing:: + kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid, + safe_browsing::kPasswordProtectionForSignedInUsers}, + {}); + + password_type.set_account_type(ReusedPasswordAccountType::GMAIL); + password_type.set_is_account_syncing(true); + + controller->SetReusedPasswordAccountTypeForTesting(password_type); + + ASSERT_EQ(l10n_util::GetStringUTF16(IDS_PAGE_INFO_PROTECT_ACCOUNT_BUTTON), + controller->GetPrimaryButtonText()); + ASSERT_EQ( + l10n_util::GetStringUTF16(IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON), + controller->GetSecondaryButtonText()); + } + + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {safe_browsing:: + kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid, + safe_browsing::kPasswordProtectionForSignedInUsers}, + {}); + + password_type.set_account_type(ReusedPasswordAccountType::SAVED_PASSWORD); + password_type.set_is_account_syncing(false); + + controller->SetReusedPasswordAccountTypeForTesting(password_type); + + ASSERT_EQ(l10n_util::GetStringUTF16(IDS_PAGE_INFO_CHECK_PASSWORDS_BUTTON), + controller->GetPrimaryButtonText()); + ASSERT_EQ( + l10n_util::GetStringUTF16(IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON), + controller->GetSecondaryButtonText()); + } + + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {safe_browsing:: + kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid, + safe_browsing::kPasswordProtectionForSignedInUsers}, + {}); + + password_type.set_account_type(ReusedPasswordAccountType::GMAIL); + password_type.set_is_account_syncing(true); + + controller->SetReusedPasswordAccountTypeForTesting(password_type); + + ASSERT_EQ(l10n_util::GetStringUTF16(IDS_PAGE_INFO_PROTECT_ACCOUNT_BUTTON), + controller->GetPrimaryButtonText()); + ASSERT_EQ( + l10n_util::GetStringUTF16(IDS_PAGE_INFO_IGNORE_PASSWORD_WARNING_BUTTON), + controller->GetSecondaryButtonText()); + } + + { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + {safe_browsing:: + kSafeBrowsingPasswordCheckIntegrationForSavedPasswordsAndroid, + safe_browsing::kPasswordProtectionForSignedInUsers}, + {}); + + password_type.set_account_type(ReusedPasswordAccountType::GMAIL); + password_type.set_is_account_syncing(false); + + controller->SetReusedPasswordAccountTypeForTesting(password_type); + + ASSERT_EQ(l10n_util::GetStringUTF16(IDS_CLOSE), + controller->GetPrimaryButtonText()); + ASSERT_EQ(std::u16string(), controller->GetSecondaryButtonText()); + } delete controller; }
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index 0163c54..6bbcad5 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -1499,6 +1499,9 @@ return extended_reporting_enabled; } +// TODO(rsamp) Expand GAIA password pings from extended reporting to the general +// Safe Browsing population. + // Only saved password reuse warnings are shown on Android, so other types of // password reuse events should be gated by extended reporting. #if defined(OS_ANDROID)
diff --git a/chrome/browser/share/core/BUILD.gn b/chrome/browser/share/core/BUILD.gn index 5b4f9cd9..ce35eca 100644 --- a/chrome/browser/share/core/BUILD.gn +++ b/chrome/browser/share/core/BUILD.gn
@@ -16,6 +16,7 @@ "//chrome/browser:resources_grit", "//chrome/browser/share/core/resources:make_share_targets_protobuf", "//chrome/browser/share/proto:proto", + "//components/country_codes", "//components/resources:components_resources", "//ui/base:base", ]
diff --git a/chrome/browser/share/core/resources/share_targets.asciipb b/chrome/browser/share/core/resources/share_targets.asciipb index 15f47aa..8343a23 100644 --- a/chrome/browser/share/core/resources/share_targets.asciipb +++ b/chrome/browser/share/core/resources/share_targets.asciipb
@@ -5,14 +5,14 @@ ## ## Top level settings ## -version_id: 4 +version_id: 5 ## ## Share Targets ## targets { nickname: "Email" - url: "mailto:?subject=%(escaped_subject)&body=%(escaped_url)" + url: "mailto:?body=%(escaped_url)" } targets { @@ -360,8 +360,8 @@ } targets { - nickname: "Linkedin" - url: "http://www.linkedin.com/shareArticle?url=%(escaped_url)&title=%(escaped_title)" + nickname: "LinkedIn" + url: "http://www.linkedi n.com/shareArticle?url=%(escaped_url)&title=%(escaped_title)" icon: "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAA" "AERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKAC" @@ -806,7 +806,7 @@ targets: "Facebook" targets: "Twitter" targets: "reddit" - targets: "Linkedin" + targets: "LinkedIn" targets: "Pinterest" } @@ -823,7 +823,7 @@ targets: "Email" targets: "WhatsApp" targets: "Facebook" - targets: "Linkedin" + targets: "LinkedIn" targets: "Twitter" } @@ -832,7 +832,7 @@ targets: "Email" targets: "Facebook" targets: "WhatsApp" - targets: "Linkedin" + targets: "LinkedIn" targets: "Twitter" } @@ -841,7 +841,7 @@ targets: "Email" targets: "Facebook" targets: "Twitter" - targets: "Linkedin" + targets: "LinkedIn" targets: "WhatsApp" } @@ -850,7 +850,7 @@ targets: "Email" targets: "Facebook" targets: "Twitter" - targets: "Linkedin" + targets: "LinkedIn" } locale_mapping { @@ -860,7 +860,7 @@ targets: "Facebook" targets: "WhatsApp" targets: "Twitter" - targets: "Linkedin" + targets: "LinkedIn" } locale_mapping { @@ -869,13 +869,13 @@ targets: "Facebook" targets: "WhatsApp" targets: "Twitter" - targets: "Linkedin" + targets: "LinkedIn" } locale_mapping { locale_keys: "ALL" targets: "Facebook" - targets: "Linkedin" + targets: "LinkedIn" targets: "Email" targets: "Pinterest" targets: "reddit"
diff --git a/chrome/browser/share/core/share_targets.cc b/chrome/browser/share/core/share_targets.cc index 10eaebe..3ca4dcca 100644 --- a/chrome/browser/share/core/share_targets.cc +++ b/chrome/browser/share/core/share_targets.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/share/core/share_targets_observer.h" #include "chrome/browser/share/proto/share_target.pb.h" #include "chrome/grit/browser_resources.h" +#include "components/country_codes/country_codes.h" #include "third_party/protobuf/src/google/protobuf/io/zero_copy_stream_impl.h" #include "ui/base/resource/resource_bundle.h" @@ -133,12 +134,14 @@ } void ShareTargets::NotifyObserver(ShareTargetsObserver* observer) { - std::string locale = GLOBAL; - std::string app_locale = g_browser_process->GetApplicationLocale(); - if (!app_locale.empty() && app_locale.size() == 5) { - // This retrieves just the country code from the locale. - locale = app_locale.substr(3, 2); - } + int countryID = country_codes::GetCurrentCountryID(); + // Decode the country code string from the provided integer. + unsigned char mask = 0xFF; + char c2 = static_cast<char>(mask & countryID); + char c1 = static_cast<char>(countryID >> 8); + std::string locale = std::string() + static_cast<char>(toupper(c1)) + + static_cast<char>(toupper(c2)); + auto it = targets_->map_target_locale_map().find(locale); if (it == targets_->map_target_locale_map().end()) {
diff --git a/chrome/browser/speech/on_device_speech_recognizer.cc b/chrome/browser/speech/on_device_speech_recognizer.cc index b38fc87..c393acb 100644 --- a/chrome/browser/speech/on_device_speech_recognizer.cc +++ b/chrome/browser/speech/on_device_speech_recognizer.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <utility> +#include "ash/constants/ash_features.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/speech/cros_speech_recognition_service.h" @@ -18,7 +19,6 @@ #include "media/audio/audio_system.h" #include "media/base/audio_parameters.h" #include "media/base/bind_to_current_loop.h" -#include "media/base/media_switches.h" namespace { @@ -61,7 +61,7 @@ bool OnDeviceSpeechRecognizer::IsOnDeviceSpeechRecognizerAvailable( const std::string& language) { // kUseSodaForLiveCaption is used to track SODA availability on-device. - if (!base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption)) + if (!base::FeatureList::IsEnabled(ash::features::kOnDeviceSpeechRecognition)) return false; speech::SodaInstaller* soda_installer = speech::SodaInstaller::GetInstance(); return soda_installer->IsSodaInstalled(speech::GetLanguageCode(language));
diff --git a/chrome/browser/speech/on_device_speech_recognizer_browsertest.cc b/chrome/browser/speech/on_device_speech_recognizer_browsertest.cc index 5df919bf..1df57e9 100644 --- a/chrome/browser/speech/on_device_speech_recognizer_browsertest.cc +++ b/chrome/browser/speech/on_device_speech_recognizer_browsertest.cc
@@ -7,6 +7,7 @@ #include <map> #include <memory> +#include "ash/constants/ash_features.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" @@ -97,6 +98,11 @@ OnDeviceSpeechRecognizerTest& operator=(const OnDeviceSpeechRecognizerTest&) = delete; + void SetUpCommandLine(base::CommandLine* command_line) override { + scoped_feature_list_.InitAndEnableFeature( + ash::features::kOnDeviceSpeechRecognition); + } + void SetUpOnMainThread() override { InProcessBrowserTest::SetUpOnMainThread(); // Replaces normal CrosSpeechRecognitionService with a fake one. @@ -162,6 +168,8 @@ // Unowned. speech::FakeSpeechRecognitionService* fake_service_; + + base::test::ScopedFeatureList scoped_feature_list_; }; IN_PROC_BROWSER_TEST_F(OnDeviceSpeechRecognizerTest, SetsUpServiceConnection) {
diff --git a/chrome/browser/sync/OWNERS b/chrome/browser/sync/OWNERS index 2d216a1c..56d318e 100644 --- a/chrome/browser/sync/OWNERS +++ b/chrome/browser/sync/OWNERS
@@ -1,4 +1,4 @@ file://components/sync/OWNERS -per-file *web_app*=file://chrome/browser/web_applications/OWNERS +per-file test/integration/*web_app*=file://chrome/browser/web_applications/OWNERS per-file wifi_configuration*=file://chromeos/components/sync_wifi/OWNERS
diff --git a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java index 5d9b63d..27504fa0 100644 --- a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java +++ b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java
@@ -44,6 +44,7 @@ import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState; import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider; +import org.chromium.components.browser_ui.bottomsheet.BottomSheetTestSupport; import org.chromium.content_public.browser.test.util.TouchCommon; import org.chromium.url.GURL; @@ -100,7 +101,7 @@ runOnUiThreadBlocking(() -> { mTouchToFill.showCredentials(sExampleUrl, true, Collections.singletonList(sAna)); }); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); pollUiThread(() -> getCredentials().getChildAt(1) != null); TouchCommon.singleClickView(getCredentials().getChildAt(1)); @@ -115,7 +116,7 @@ runOnUiThreadBlocking(() -> { mTouchToFill.showCredentials(sExampleUrl, true, Arrays.asList(sAna, sBob)); }); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); Espresso.pressBack();
diff --git a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java index ced169a9..75f2ddf4 100644 --- a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java +++ b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java
@@ -106,7 +106,7 @@ public void testVisibilityChangedByModel() { // After setting the visibility to true, the view should exist and be visible. TestThreadUtils.runOnUiThreadBlocking(() -> mModel.set(VISIBLE, true)); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); assertThat(mTouchToFillView.getContentView().isShown(), is(true)); // After hiding the view, the view should still exist but be invisible. @@ -128,7 +128,7 @@ .build())); mModel.set(VISIBLE, true); }); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); TextView title = mTouchToFillView.getContentView().findViewById(R.id.touch_to_fill_sheet_title); @@ -149,7 +149,7 @@ .build())); mModel.set(VISIBLE, true); }); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); TextView title = mTouchToFillView.getContentView().findViewById(R.id.touch_to_fill_sheet_title); @@ -169,7 +169,7 @@ .build())); mModel.set(VISIBLE, true); }); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); TextView subtitle = mTouchToFillView.getContentView().findViewById(R.id.touch_to_fill_sheet_subtitle); @@ -188,7 +188,7 @@ .build())); mModel.set(VISIBLE, true); }); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); TextView subtitle = mTouchToFillView.getContentView().findViewById(R.id.touch_to_fill_sheet_subtitle); @@ -205,7 +205,7 @@ buildCredentialItem(BOB))); }); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); assertThat(getCredentials().getChildCount(), is(3)); assertThat(getCredentialOriginAt(0).getVisibility(), is(View.GONE)); assertThat(getCredentialNameAt(0).getText(), is(ANA.getFormattedUsername())); @@ -233,7 +233,7 @@ mModel.get(SHEET_ITEMS).addAll(Collections.singletonList(buildCredentialItem(ANA))); mModel.set(VISIBLE, true); }); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); assertNotNull(getCredentials().getChildAt(0)); @@ -252,7 +252,7 @@ buildConfirmationButton(ANA))); mModel.set(VISIBLE, true); }); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); assertNotNull(getCredentials().getChildAt(0)); assertNotNull(getCredentials().getChildAt(1)); @@ -270,7 +270,7 @@ mModel.set(ON_CLICK_MANAGE, () -> manageButtonClicked.set(true)); mModel.set(VISIBLE, true); }); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); BottomSheetTestSupport sheetSupport = new BottomSheetTestSupport( getActivity().getRootUiCoordinatorForTesting().getBottomSheetController()); @@ -289,7 +289,7 @@ @MediumTest public void testDismissesWhenHidden() { TestThreadUtils.runOnUiThreadBlocking(() -> mModel.set(VISIBLE, true)); - pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF); + BottomSheetTestSupport.waitForOpen(mBottomSheetController); TestThreadUtils.runOnUiThreadBlocking(() -> mModel.set(VISIBLE, false)); pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HIDDEN); verify(mDismissHandler).onResult(BottomSheetController.StateChangeReason.NONE);
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 7566fd8..9a98777 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1632,7 +1632,7 @@ "//chrome/common/search:generate_chrome_colors_info", "//chrome/common/search:mojo_bindings", "//chrome/common/themes:autogenerated_theme_util", - "//components/enterprise/common/proto:download_item_reroute_info_proto", + "//components/enterprise/common:download_item_reroute_info", "//components/feedback/proto", "//components/keep_alive_registry", "//components/media_router/common/mojom:media_router",
diff --git a/chrome/browser/ui/android/safe_browsing/password_reuse_dialog_view_android.cc b/chrome/browser/ui/android/safe_browsing/password_reuse_dialog_view_android.cc index 2ac98d8..3ffff80 100644 --- a/chrome/browser/ui/android/safe_browsing/password_reuse_dialog_view_android.cc +++ b/chrome/browser/ui/android/safe_browsing/password_reuse_dialog_view_android.cc
@@ -34,8 +34,11 @@ std::u16string warning_detail_text = controller_->GetWarningDetailText(&placeholder_offsets); - const std::vector<std::u16string> placeholders = - controller_->GetPlaceholdersForSavedPasswordWarningText(); + std::vector<std::u16string> placeholders; + + if (placeholder_offsets.size() > 0) { + placeholders = controller_->GetPlaceholdersForSavedPasswordWarningText(); + } DCHECK_EQ(placeholder_offsets.size(), placeholders.size());
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 366b49c..3d1710f 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -1274,11 +1274,11 @@ <message name="IDS_LANGUAGES_SPLIT_READY" desc="Text to display next to the native name of a language when it has been downloaded to use as Chrome's UI language. The dash separates the native name from the description."> <ph name="LANG">%1$s<ex>हिन्दी</ex></ph> - Language ready, restart <ph name="APP_NAME">%2$s<ex>Chrome</ex></ph>. </message> - <message name="IDS_LANGUAGES_SPLIT_FAILED" desc="Text to display next to the native name of a language when a langauge pack has failed to download. The dash separates the native name from the description. The message asks the user to try again."> + <message name="IDS_LANGUAGES_SPLIT_FAILED" desc="Text to display next to the native name of a language when a language pack has failed to download. The dash separates the native name from the description. The message asks the user to try again."> <ph name="LANG">%1$s<ex>हिन्दी</ex></ph> - This language couldn't be downloaded. Try again later. </message> <message name="IDS_LANGUAGES_INFOBAR_READY" desc="Infobar text to appear when a new language pack has been downloaded. [CHAR_LIMIT=32]"> - <ph name="LANG">%1$s<ex>Hindi</ex></ph> is ready. + <ph name="LANG">%1$s<ex>Hindi</ex></ph> is ready </message> <message name="IDS_LANGUAGES_INFOBAR_RESTART" desc="The clickable link letting the user know they can click to restart Chrome. [CHAR_LIMIT=32]"> Restart Chrome
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LANGUAGES_INFOBAR_READY.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LANGUAGES_INFOBAR_READY.png.sha1 index 17c0078f..4bec129 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LANGUAGES_INFOBAR_READY.png.sha1 +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_LANGUAGES_INFOBAR_READY.png.sha1
@@ -1 +1 @@ -686b50ba1d8336e6c79252b34d5d1c79d4484f4b \ No newline at end of file +78abfb810d3762f93a1b537cb6f56a1d8d16cc27 \ No newline at end of file
diff --git a/chrome/browser/ui/android/theme/BUILD.gn b/chrome/browser/ui/android/theme/BUILD.gn index 4b37114..5465f35 100644 --- a/chrome/browser/ui/android/theme/BUILD.gn +++ b/chrome/browser/ui/android/theme/BUILD.gn
@@ -13,6 +13,7 @@ deps = [ ":java_resources", "//base:base_java", + "//chrome/browser/flags:java", "//chrome/browser/tab:java", "//chrome/browser/ui/android/native_page:java", "//components/browser_ui/styles/android:java",
diff --git a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeUtils.java b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeUtils.java index b4bfb43..a3afa6a 100644 --- a/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeUtils.java +++ b/chrome/browser/ui/android/theme/java/src/org/chromium/chrome/browser/theme/ThemeUtils.java
@@ -15,6 +15,8 @@ import androidx.appcompat.content.res.AppCompatResources; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.chrome.browser.flags.BooleanCachedFieldTrialParameter; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.ui.native_page.NativePage; import org.chromium.components.browser_ui.styles.ChromeColors; @@ -28,6 +30,13 @@ public class ThemeUtils { private static final float LOCATION_BAR_TRANSPARENT_BACKGROUND_ALPHA = 0.2f; + // This param is used to split the dynamic colors launch into a minimal launch that is primarily + // activity specific, and then a later launch that will be app wide. + private static final String FULL_DYNAMIC_COLORS_PARAM = "dynamic_color_full"; + public static final BooleanCachedFieldTrialParameter ENABLE_FULL_DYNAMIC_COLORS = + new BooleanCachedFieldTrialParameter( + ChromeFeatureList.DYNAMIC_COLOR_ANDROID, FULL_DYNAMIC_COLORS_PARAM, false); + /** * The background color to use for a given {@link Tab}. This will either be the color specified * by the associated web content or a default color if not specified.
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc b/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc index cd07126..a5d1db6 100644 --- a/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc +++ b/chrome/browser/ui/ash/holding_space/holding_space_downloads_delegate.cc
@@ -63,6 +63,7 @@ mojo_download_item->has_received_bytes = true; mojo_download_item->total_bytes = item->GetTotalBytes(); mojo_download_item->has_total_bytes = true; + mojo_download_item->start_time = item->GetStartTime(); // NOTE: `browser_context` may be `nullptr` in tests. auto* browser_context = content::DownloadItemUtils::GetBrowserContext(item);
diff --git a/chrome/browser/ui/ash/projector/projector_client_impl.cc b/chrome/browser/ui/ash/projector/projector_client_impl.cc index 5c1b41a..30a938e 100644 --- a/chrome/browser/ui/ash/projector/projector_client_impl.cc +++ b/chrome/browser/ui/ash/projector/projector_client_impl.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/ui/ash/projector/projector_client_impl.h" +#include "ash/constants/ash_features.h" #include "ash/public/cpp/projector/projector_controller.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/speech/on_device_speech_recognizer.h" @@ -32,7 +33,8 @@ ShouldUseWebSpeechFallback(); controller_->OnSpeechRecognitionAvailable(recognition_available); - if (!recognition_available) { + if (!recognition_available && + base::FeatureList::IsEnabled(ash::features::kOnDeviceSpeechRecognition)) { speech::SodaInstaller::GetInstance()->AddObserver(this); } }
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 ffbc93c..0bbd7cf 100644 --- a/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc +++ b/chrome/browser/ui/ash/projector/projector_client_impl_browsertest.cc
@@ -57,7 +57,8 @@ class ProjectorClientTest : public InProcessBrowserTest { public: ProjectorClientTest() { - scoped_feature_list_.InitAndEnableFeature(features::kProjector); + scoped_feature_list_.InitWithFeatures( + {features::kProjector, features::kOnDeviceSpeechRecognition}, {}); } ~ProjectorClientTest() override = default;
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index feee6e10..17c3233 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -725,10 +725,6 @@ FRIEND_TEST_ALL_PREFIXES(ExclusiveAccessTest, TabEntersPresentationModeFromWindowed); FRIEND_TEST_ALL_PREFIXES(BrowserCloseTest, LastGuest); - FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, OpenAppShortcutNoPref); - FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, - OpenAppShortcutWindowPref); - FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, OpenAppShortcutTabPref); // Used to describe why a tab is being detached. This is used by // TabDetachedAtImpl.
diff --git a/chrome/browser/ui/startup/startup_browser_creator.cc b/chrome/browser/ui/startup/startup_browser_creator.cc index 932b0b7..1f80f14 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.cc +++ b/chrome/browser/ui/startup/startup_browser_creator.cc
@@ -1101,6 +1101,12 @@ if (command_line.HasSwitch(switches::kAppId)) { std::string app_id = command_line.GetSwitchValueASCII(switches::kAppId); +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) + // If Chrome Apps are deprecated and |app_id| is a Chrome App, display the + // deprecation UI instead of launching the app. + if (apps::OpenDeprecatedApplicationPrompt(privacy_safe_profile, app_id)) + return true; +#endif // If |app_id| is a disabled or terminated platform app we handle it // specially here, otherwise it will be handled below. if (apps::OpenExtensionApplicationWithReenablePrompt(
diff --git a/chrome/browser/ui/startup/startup_browser_creator.h b/chrome/browser/ui/startup/startup_browser_creator.h index a7abc5d..223a891 100644 --- a/chrome/browser/ui/startup/startup_browser_creator.h +++ b/chrome/browser/ui/startup/startup_browser_creator.h
@@ -190,10 +190,14 @@ ValidNotificationLaunchId); FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, InvalidNotificationLaunchId); - FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, OpenAppShortcutNoPref); - FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, OpenAppShortcutTabPref); - FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, + FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorChromeAppShortcutTest, + OpenAppShortcutNoPref); + FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorChromeAppShortcutTest, + OpenAppShortcutTabPref); + FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorChromeAppShortcutTest, OpenAppShortcutWindowPref); + FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorChromeAppShortcutTest, + OpenPolicyForcedAppShortcut); FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, OpenAppUrlShortcut); FRIEND_TEST_ALL_PREFIXES(StartupBrowserWithRealWebAppTest, LastUsedProfilesWithRealWebApp);
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index 3cfaf732..494a5b3 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -90,10 +90,13 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_utils.h" #include "content/public/test/test_launcher.h" #include "content/public/test/test_navigation_observer.h" #include "content/public/test/test_utils.h" #include "extensions/browser/extension_registry.h" +#include "extensions/browser/pref_names.h" +#include "extensions/browser/test_management_policy.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -113,6 +116,7 @@ #include "chrome/browser/web_applications/web_app.h" #include "chrome/browser/web_applications/web_app_registrar.h" #include "chrome/browser/web_applications/web_app_registry_update.h" +#include "chrome/common/chrome_features.h" #include "ui/views/widget/any_widget_observer.h" #include "ui/views/widget/widget.h" #endif @@ -510,7 +514,93 @@ web_contents->GetLastCommittedURL().ExtractFileName()); } -IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenAppShortcutNoPref) { +namespace { + +enum class ChromeAppDeprecationFeatureValue { + kDefault, +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) + kEnabled, + kDisabled, +#endif +}; + +std::string ChromeAppDeprecationFeatureValueToString( + const ::testing::TestParamInfo<ChromeAppDeprecationFeatureValue>& + param_info) { + switch (param_info.param) { + case ChromeAppDeprecationFeatureValue::kDefault: + return "Default"; +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) + case ChromeAppDeprecationFeatureValue::kEnabled: + return "ChromeAppsEnabled"; + case ChromeAppDeprecationFeatureValue::kDisabled: + return "ChromeAppsDisabled"; +#endif + } +} + +} // namespace + +class StartupBrowserCreatorChromeAppShortcutTest + : public StartupBrowserCreatorTest, + public ::testing::WithParamInterface<ChromeAppDeprecationFeatureValue> { + protected: + StartupBrowserCreatorChromeAppShortcutTest() { + switch (GetParam()) { + case ChromeAppDeprecationFeatureValue::kDefault: + break; +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) + case ChromeAppDeprecationFeatureValue::kEnabled: + scoped_feature_list_.InitAndEnableFeature( + features::kChromeAppsDeprecation); + break; + case ChromeAppDeprecationFeatureValue::kDisabled: + scoped_feature_list_.InitAndDisableFeature( + features::kChromeAppsDeprecation); + break; +#endif + } + } + + void ExpectBlockLaunch() { + ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile())); + // Should have opened the requested homepage about:blank in 1st window. + TabStripModel* tab_strip = browser()->tab_strip_model(); + EXPECT_EQ(1, tab_strip->count()); + EXPECT_FALSE(browser()->is_type_app()); + EXPECT_TRUE(browser()->is_type_normal()); + EXPECT_EQ(GURL(url::kAboutBlankURL), + tab_strip->GetWebContentsAt(0)->GetURL()); + // Should have opened the chrome://apps unsupported app flow in 2nd window. + Browser* other_browser = FindOneOtherBrowser(browser()); + ASSERT_TRUE(other_browser); + TabStripModel* other_tab_strip = other_browser->tab_strip_model(); + EXPECT_EQ(1, other_tab_strip->count()); + EXPECT_FALSE(other_browser->is_type_app()); + EXPECT_TRUE(other_browser->is_type_normal()); + EXPECT_EQ(GURL(chrome::kChromeUIAppsURL), + other_tab_strip->GetWebContentsAt(0)->GetURL()); + } + + bool ShouldExpectBlockLaunch() { +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) + switch (GetParam()) { + case ChromeAppDeprecationFeatureValue::kEnabled: + return true; + case ChromeAppDeprecationFeatureValue::kDefault: + case ChromeAppDeprecationFeatureValue::kDisabled: + return false; + } +#endif + return false; + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +IN_PROC_BROWSER_TEST_P(StartupBrowserCreatorChromeAppShortcutTest, + OpenAppShortcutNoPref) { // Load an app with launch.container = 'tab'. const Extension* extension_app = nullptr; ASSERT_NO_FATAL_FAILURE(LoadApp("app_with_tab_container", &extension_app)); @@ -527,18 +617,31 @@ command_line, base::FilePath(), /*process_startup=*/false, browser()->profile(), {})); - // No pref was set, so the app should have opened in a tab in the existing - // window. - ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); - EXPECT_EQ(2, tab_strip->count()); - EXPECT_EQ(tab_strip->GetActiveWebContents(), tab_strip->GetWebContentsAt(1)); + if (ShouldExpectBlockLaunch()) { + ExpectBlockLaunch(); + } else { + // No pref was set, so the app should have opened in a tab in the existing + // window. + ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); + EXPECT_EQ(2, tab_strip->count()); + EXPECT_EQ(tab_strip->GetActiveWebContents(), + tab_strip->GetWebContentsAt(1)); - // It should be a standard tabbed window, not an app window. - EXPECT_FALSE(browser()->is_type_app()); - EXPECT_TRUE(browser()->is_type_normal()); + // It should be a standard tabbed window, not an app window. + EXPECT_FALSE(browser()->is_type_app()); + EXPECT_TRUE(browser()->is_type_normal()); + + // It should have loaded the requested app. + const std::u16string expected_title( + u"app_with_tab_container/empty.html title"); + content::TitleWatcher title_watcher(tab_strip->GetActiveWebContents(), + expected_title); + EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); + } } -IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenAppShortcutWindowPref) { +IN_PROC_BROWSER_TEST_P(StartupBrowserCreatorChromeAppShortcutTest, + OpenAppShortcutWindowPref) { const Extension* extension_app = nullptr; ASSERT_NO_FATAL_FAILURE(LoadApp("app_with_tab_container", &extension_app)); @@ -551,22 +654,27 @@ command_line, base::FilePath(), /*process_startup=*/false, browser()->profile(), {})); - // Pref was set to open in a window, so the app should have opened in a - // window. The launch should have created a new browser. Find the new - // browser. - Browser* new_browser = FindOneOtherBrowser(browser()); - ASSERT_TRUE(new_browser); + if (ShouldExpectBlockLaunch()) { + ExpectBlockLaunch(); + } else { + // Pref was set to open in a window, so the app should have opened in a + // window. The launch should have created a new browser. Find the new + // browser. + Browser* new_browser = FindOneOtherBrowser(browser()); + ASSERT_TRUE(new_browser); - // Expect an app window. - EXPECT_TRUE(new_browser->is_type_app()); + // Expect an app window. + EXPECT_TRUE(new_browser->is_type_app()); - // The browser's app_name should include the app's ID. - EXPECT_NE( - new_browser->app_name_.find(extension_app->id()), - std::string::npos) << new_browser->app_name_; + // The browser's app_name should include the app's ID. + EXPECT_NE(new_browser->app_name().find(extension_app->id()), + std::string::npos) + << new_browser->app_name(); + } } -IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorTest, OpenAppShortcutTabPref) { +IN_PROC_BROWSER_TEST_P(StartupBrowserCreatorChromeAppShortcutTest, + OpenAppShortcutTabPref) { // When we start, the browser should already have an open tab. TabStripModel* tab_strip = browser()->tab_strip_model(); EXPECT_EQ(1, tab_strip->count()); @@ -584,18 +692,89 @@ command_line, base::FilePath(), /*process_startup=*/false, browser()->profile(), {})); - // When an app shortcut is open and the pref indicates a tab should open, the - // tab is open in the existing browser window. + if (ShouldExpectBlockLaunch()) { + ExpectBlockLaunch(); + } else { + // When an app shortcut is open and the pref indicates a tab should open, + // the tab is open in the existing browser window. + ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); + EXPECT_EQ(2, tab_strip->count()); + EXPECT_EQ(tab_strip->GetActiveWebContents(), + tab_strip->GetWebContentsAt(1)); + + // The browser's app_name should not include the app's ID: it is in a normal + // tabbed browser. + EXPECT_EQ(browser()->app_name().find(extension_app->id()), + std::string::npos) + << browser()->app_name(); + + // It should have loaded the requested app. + const std::u16string expected_title( + u"app_with_tab_container/empty.html title"); + content::TitleWatcher title_watcher(tab_strip->GetActiveWebContents(), + expected_title); + EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); + } +} + +IN_PROC_BROWSER_TEST_P(StartupBrowserCreatorChromeAppShortcutTest, + OpenPolicyForcedAppShortcut) { + // Load an app with launch.container = 'tab'. + const Extension* extension_app = nullptr; + ASSERT_NO_FATAL_FAILURE(LoadApp("app_with_tab_container", &extension_app)); + + // Install a test policy provider which will mark the app as force-installed. + extensions::TestManagementPolicyProvider policy_provider( + extensions::TestManagementPolicyProvider::MUST_REMAIN_INSTALLED); + extensions::ExtensionSystem* extension_system = + extensions::ExtensionSystem::Get(browser()->profile()); + extension_system->management_policy()->RegisterProvider(&policy_provider); + + // When we start, the browser should already have an open tab. + TabStripModel* tab_strip = browser()->tab_strip_model(); + EXPECT_EQ(1, tab_strip->count()); + + // Add --app-id=<extension->id()> to the command line. + base::CommandLine command_line(base::CommandLine::NO_PROGRAM); + command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); + + ASSERT_TRUE(StartupBrowserCreator().ProcessCmdLineImpl( + command_line, base::FilePath(), /*process_startup=*/false, + browser()->profile(), {})); + + // Policy force-installed app should be allowed regardless of Chrome App + // Deprecation status. + // + // No app launch pref was set, so the app should have opened in a tab in the + // existing window. ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); EXPECT_EQ(2, tab_strip->count()); EXPECT_EQ(tab_strip->GetActiveWebContents(), tab_strip->GetWebContentsAt(1)); - // The browser's app_name should not include the app's ID: it is in a normal - // tabbed browser. - EXPECT_EQ(browser()->app_name_.find(extension_app->id()), std::string::npos) - << browser()->app_name_; + // It should be a standard tabbed window, not an app window. + EXPECT_FALSE(browser()->is_type_app()); + EXPECT_TRUE(browser()->is_type_normal()); + + // It should have loaded the requested app. + const std::u16string expected_title( + u"app_with_tab_container/empty.html title"); + content::TitleWatcher title_watcher(tab_strip->GetActiveWebContents(), + expected_title); + EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); } +INSTANTIATE_TEST_SUITE_P( + All, + StartupBrowserCreatorChromeAppShortcutTest, + ::testing::Values(ChromeAppDeprecationFeatureValue::kDefault +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) + , + ChromeAppDeprecationFeatureValue::kEnabled, + ChromeAppDeprecationFeatureValue::kDisabled +#endif + ), + ChromeAppDeprecationFeatureValueToString); + #endif // !BUILDFLAG(IS_CHROMEOS_ASH) #if defined(OS_WIN)
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc index 41c9e5c..b0d4adc 100644 --- a/chrome/browser/ui/views/content_setting_bubble_contents.cc +++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -28,6 +28,7 @@ #include "ui/base/metadata/metadata_header_macros.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/models/combobox_model.h" +#include "ui/base/models/image_model.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/geometry/insets.h" @@ -242,13 +243,11 @@ if (item.image) { item_icon->SetBorder( views::CreateEmptyBorder(kTitleDescriptionListItemInset)); - const SkColor icon_color = - views::style::GetColor(*item_icon, CONTEXT_DIALOG_BODY_TEXT_SMALL, - views::style::STYLE_PRIMARY); - item_icon->SetImage(CreateVectorIconWithBadge( - *item.image, GetLayoutConstant(LOCATION_BAR_ICON_SIZE), icon_color, - item.has_blocked_badge ? vector_icons::kBlockedBadgeIcon - : gfx::kNoneIcon)); + item_icon->SetImage(ui::ImageModel::FromVectorIcon( + *item.image, ui::NativeTheme::kColorId_LabelEnabledColor, + GetLayoutConstant(LOCATION_BAR_ICON_SIZE), + item.has_blocked_badge ? &vector_icons::kBlockedBadgeIcon + : &gfx::kNoneIcon)); } std::unique_ptr<views::View> item_contents;
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc index 13d28c251..4bf4a83 100644 --- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc +++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
@@ -24,6 +24,7 @@ #include "chrome/grit/generated_resources.h" #include "components/constrained_window/constrained_window_views.h" #include "components/strings/grit/components_strings.h" +#include "components/vector_icons/vector_icons.h" #include "components/web_modal/web_contents_modal_dialog_manager.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" @@ -37,6 +38,7 @@ #include "ui/events/keycodes/keyboard_codes.h" #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/insets.h" +#include "ui/gfx/paint_vector_icon.h" #include "ui/views/controls/button/checkbox.h" #include "ui/views/controls/scroll_view.h" #include "ui/views/controls/tabbed_pane/tabbed_pane.h" @@ -208,6 +210,41 @@ } } +// Helper to generate the view containing the enterprise icon and a message that +// the picker choices may have been restricted. +std::unique_ptr<views::View> CreatePolicyRestrictedView() { + auto icon = std::make_unique<views::ImageView>(); + icon->SetImage(gfx::CreateVectorIcon(gfx::IconDescription( + vector_icons::kBusinessIcon, 18, gfx::kChromeIconGrey))); + + auto policy_label = std::make_unique<views::Label>(); + policy_label->SetMultiLine(true); + policy_label->SetText( + l10n_util::GetStringUTF16(IDS_DESKTOP_MEDIA_PICKER_MANAGED)); + + auto policy_view = std::make_unique<views::View>(); + int text_padding = ChromeLayoutProvider::Get()->GetDistanceMetric( + views::DISTANCE_TEXTFIELD_HORIZONTAL_TEXT_PADDING); + + views::GridLayout* layout = + policy_view->SetLayoutManager(std::make_unique<views::GridLayout>()); + + views::ColumnSet* columnset = layout->AddColumnSet(0); + columnset->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, + views::GridLayout::kFixedSize, + views::GridLayout::ColumnSize::kUsePreferred, 0, 0); + columnset->AddPaddingColumn(views::GridLayout::kFixedSize, text_padding); + columnset->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, + views::GridLayout::kFixedSize, + views::GridLayout::ColumnSize::kUsePreferred, 0, 0); + + layout->StartRow(views::GridLayout::kFixedSize, 0); + layout->AddView(std::move(icon)); + layout->AddView(std::move(policy_label)); + + return policy_view; +} + } // namespace bool DesktopMediaPickerDialogView::AudioSupported(DesktopMediaList::Type type) { @@ -429,6 +466,10 @@ params.app_name, params.target_name)); } + if (params.restricted_by_policy) { + AddChildView(CreatePolicyRestrictedView()); + } + DCHECK(!categories_.empty()); previously_selected_category_ = GetSelectedTabIndex();
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc index 3742073..31de9c7 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc
@@ -80,7 +80,6 @@ #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h" #include "chromeos/ui/frame/default_frame_header.h" #include "chromeos/ui/frame/frame_header.h" -#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" #include "components/account_id/account_id.h" #include "components/keep_alive_registry/keep_alive_types.h" #include "components/keep_alive_registry/scoped_keep_alive.h" @@ -375,353 +374,6 @@ namespace { -class ImmersiveModeBrowserViewTest - : public TopChromeMdParamTest<InProcessBrowserTest> { - public: - ImmersiveModeBrowserViewTest() = default; - ~ImmersiveModeBrowserViewTest() override = default; - - // TopChromeMdParamTest<InProcessBrowserTest>: - void PreRunTestOnMainThread() override { - InProcessBrowserTest::PreRunTestOnMainThread(); - - BrowserView::SetDisableRevealerDelayForTesting(true); - - chromeos::ImmersiveFullscreenControllerTestApi( - static_cast<ImmersiveModeControllerChromeos*>( - BrowserView::GetBrowserViewForBrowser(browser()) - ->immersive_mode_controller()) - ->controller()) - .SetupForTest(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ImmersiveModeBrowserViewTest); -}; - -} // namespace - -using ImmersiveModeBrowserViewTestNoWebUiTabStrip = - WebUiTabStripOverrideTest<false, ImmersiveModeBrowserViewTest>; - -// This test does not make sense for the webUI tabstrip, since the frame is not -// painted in that case. -IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTestNoWebUiTabStrip, - ImmersiveFullscreen) { - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); - content::WebContents* web_contents = browser_view->GetActiveWebContents(); - BrowserNonClientFrameViewChromeOS* frame_view = - GetFrameViewChromeOS(browser_view); - - ImmersiveModeController* immersive_mode_controller = - browser_view->immersive_mode_controller(); - - // Immersive fullscreen starts disabled. - ASSERT_FALSE(browser_view->GetWidget()->IsFullscreen()); - EXPECT_FALSE(immersive_mode_controller->IsEnabled()); - - // Frame paints by default. - EXPECT_TRUE(frame_view->GetShouldPaint()); - EXPECT_LT(0, frame_view - ->GetBoundsForTabStripRegion( - browser_view->tab_strip_region_view()->GetMinimumSize()) - .bottom()); - - // Enter both browser fullscreen and tab fullscreen. Entering browser - // fullscreen should enable immersive fullscreen. - ToggleFullscreenModeAndWait(browser()); - EnterFullscreenModeForTabAndWait(browser(), web_contents); - EXPECT_TRUE(immersive_mode_controller->IsEnabled()); - - // An immersive reveal shows the buttons and the top of the frame. - std::unique_ptr<ImmersiveRevealedLock> revealed_lock( - immersive_mode_controller->GetRevealedLock( - ImmersiveModeController::ANIMATE_REVEAL_NO)); - EXPECT_TRUE(immersive_mode_controller->IsRevealed()); - EXPECT_TRUE(frame_view->GetShouldPaint()); - - // End the reveal. When in both immersive browser fullscreen and tab - // fullscreen. - revealed_lock.reset(); - EXPECT_FALSE(immersive_mode_controller->IsRevealed()); - EXPECT_FALSE(frame_view->GetShouldPaint()); - EXPECT_EQ(0, frame_view - ->GetBoundsForTabStripRegion( - browser_view->tab_strip_region_view()->GetMinimumSize()) - .bottom()); - - // Repeat test but without tab fullscreen. - ExitFullscreenModeForTabAndWait(browser(), web_contents); - - // Immersive reveal should have same behavior as before. - revealed_lock.reset(immersive_mode_controller->GetRevealedLock( - ImmersiveModeController::ANIMATE_REVEAL_NO)); - EXPECT_TRUE(immersive_mode_controller->IsRevealed()); - EXPECT_TRUE(frame_view->GetShouldPaint()); - EXPECT_LT(0, frame_view - ->GetBoundsForTabStripRegion( - browser_view->tab_strip_region_view()->GetMinimumSize()) - .bottom()); - - // Ending the reveal. Immersive browser should have the same behavior as full - // screen, i.e., having an origin of (0,0). - revealed_lock.reset(); - EXPECT_FALSE(frame_view->GetShouldPaint()); - EXPECT_EQ(0, frame_view - ->GetBoundsForTabStripRegion( - browser_view->tab_strip_region_view()->GetMinimumSize()) - .bottom()); - - // Exiting immersive fullscreen should make the caption buttons and the frame - // visible again. - { - FullscreenNotificationObserver waiter(browser()); - browser_view->ExitFullscreen(); - waiter.Wait(); - } - EXPECT_FALSE(immersive_mode_controller->IsEnabled()); - EXPECT_TRUE(frame_view->GetShouldPaint()); - EXPECT_LT(0, frame_view - ->GetBoundsForTabStripRegion( - browser_view->tab_strip_region_view()->GetMinimumSize()) - .bottom()); -} - -// Tests IDC_SELECT_TAB_0, IDC_SELECT_NEXT_TAB, IDC_SELECT_PREVIOUS_TAB and -// IDC_SELECT_LAST_TAB when the browser is in immersive fullscreen mode. -IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTest, - TabNavigationAcceleratorsFullscreenBrowser) { - ImmersiveModeTester tester(browser()); - // Make sure that the focus is on the webcontents rather than on the omnibox, - // because if the focus is on the omnibox, the tab strip will remain revealed - // in the immersive fullscreen mode and will interfere with this test waiting - // for the revealer to be dismissed. - browser()->tab_strip_model()->GetActiveWebContents()->Focus(); - - // Create three more tabs plus the existing one that browser tests start with. - const GURL about_blank(url::kAboutBlankURL); - AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED); - browser()->tab_strip_model()->GetActiveWebContents()->Focus(); - AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED); - browser()->tab_strip_model()->GetActiveWebContents()->Focus(); - AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED); - browser()->tab_strip_model()->GetActiveWebContents()->Focus(); - - // Toggle fullscreen mode. - chrome::ToggleFullscreenMode(browser()); - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); - EXPECT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); - // Wait for the end of the initial reveal which results from adding the new - // tabs and changing the focused tab. - tester.VerifyTabIndexAfterReveal(0); - - // Groups the browser command ID and its corresponding active tab index that - // will result when the command is executed in this test. - struct TestData { - int command; - int expected_index; - }; - constexpr TestData test_data[] = {{IDC_SELECT_LAST_TAB, 3}, - {IDC_SELECT_TAB_0, 0}, - {IDC_SELECT_NEXT_TAB, 1}, - {IDC_SELECT_PREVIOUS_TAB, 0}}; - for (const auto& datum : test_data) - tester.RunCommand(datum.command, datum.expected_index); -} - -// This test does not make sense for the webUI tabstrip, since the window layout -// is different in that case. -IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTestNoWebUiTabStrip, - TestCaptionButtonsReceiveEventsInBrowserImmersiveMode) { - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); - - // Make sure that the focus is on the webcontents rather than on the omnibox, - // because if the focus is on the omnibox, the tab strip will remain revealed - // in the immersive fullscreen mode and will interfere with this test waiting - // for the revealer to be dismissed. - browser()->tab_strip_model()->GetActiveWebContents()->Focus(); - - // Toggle fullscreen mode. - chrome::ToggleFullscreenMode(browser()); - EXPECT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); - - EXPECT_TRUE(browser()->window()->IsFullscreen()); - EXPECT_FALSE(browser()->window()->IsMaximized()); - EXPECT_FALSE(browser_view->immersive_mode_controller()->IsRevealed()); - - std::unique_ptr<ImmersiveRevealedLock> revealed_lock( - browser_view->immersive_mode_controller()->GetRevealedLock( - ImmersiveModeController::ANIMATE_REVEAL_NO)); - EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed()); - - ImmersiveModeTester tester(browser()); - - // Clicking the "restore" caption button should exit the immersive mode. - aura::Window* window = browser()->window()->GetNativeWindow(); - ui::test::EventGenerator event_generator(window->GetRootWindow()); - gfx::Size button_size = views::GetCaptionButtonLayoutSize( - views::CaptionButtonLayoutSize::kBrowserCaptionMaximized); - gfx::Point point_in_restore_button(window->GetBoundsInScreen().top_right()); - point_in_restore_button.Offset(-button_size.width() * 3 / 2, - button_size.height() / 2); - - event_generator.MoveMouseTo(point_in_restore_button); - EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed()); - event_generator.ClickLeftButton(); - tester.WaitForFullscreenToExit(); - - EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); - EXPECT_FALSE(browser()->window()->IsFullscreen()); -} - -IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTest, - TestCaptionButtonsReceiveEventsInAppImmersiveMode) { - browser()->window()->Close(); - - // Open a new app window. - Browser::CreateParams params = Browser::CreateParams::CreateForApp( - "test_browser_app", true /* trusted_source */, gfx::Rect(0, 0, 300, 300), - browser()->profile(), true); - params.initial_show_state = ui::SHOW_STATE_DEFAULT; - Browser* browser = Browser::Create(params); - ASSERT_TRUE(browser->is_type_app()); - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); - - chromeos::ImmersiveFullscreenControllerTestApi( - static_cast<ImmersiveModeControllerChromeos*>( - browser_view->immersive_mode_controller()) - ->controller()) - .SetupForTest(); - - // Toggle fullscreen mode. - chrome::ToggleFullscreenMode(browser); - EXPECT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); - EXPECT_FALSE(browser_view->GetTabStripVisible()); - - EXPECT_TRUE(browser->window()->IsFullscreen()); - EXPECT_FALSE(browser->window()->IsMaximized()); - EXPECT_FALSE(browser_view->immersive_mode_controller()->IsRevealed()); - - std::unique_ptr<ImmersiveRevealedLock> revealed_lock( - browser_view->immersive_mode_controller()->GetRevealedLock( - ImmersiveModeController::ANIMATE_REVEAL_NO)); - EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed()); - - ImmersiveModeTester tester(browser); - AddBlankTabAndShow(browser); - - // Clicking the "restore" caption button should exit the immersive mode. - aura::Window* window = browser->window()->GetNativeWindow(); - ui::test::EventGenerator event_generator(window->GetRootWindow(), window); - gfx::Size button_size = views::GetCaptionButtonLayoutSize( - views::CaptionButtonLayoutSize::kBrowserCaptionMaximized); - gfx::Point point_in_restore_button( - window->GetBoundsInRootWindow().top_right()); - point_in_restore_button.Offset(-2 * button_size.width(), - button_size.height() / 2); - - event_generator.MoveMouseTo(point_in_restore_button); - EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed()); - event_generator.ClickLeftButton(); - tester.WaitForFullscreenToExit(); - - EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); - EXPECT_FALSE(browser->window()->IsFullscreen()); -} - -// Regression test for crbug.com/796171. Make sure that going from regular -// fullscreen to locked fullscreen does not cause a crash. -// Also test that the immersive mode is disabled afterwards (and the shelf is -// hidden, and the fullscreen control popup doesn't show up). -IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTest, - RegularToLockedFullscreenDisablesImmersive) { - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); - - // Toggle fullscreen mode. - chrome::ToggleFullscreenMode(browser()); - EXPECT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); - - // Set locked fullscreen state. - browser()->window()->GetNativeWindow()->SetProperty( - chromeos::kWindowPinTypeKey, chromeos::WindowPinType::kTrustedPinned); - - // We're fullscreen, immersive is disabled in locked fullscreen, and while - // we're at it, also make sure that the shelf is hidden. - EXPECT_TRUE(browser_view->GetWidget()->IsFullscreen()); - EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); - EXPECT_FALSE(IsShelfVisible()); - - // Make sure the fullscreen control popup doesn't show up. - ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, gfx::Point(1, 1), gfx::Point(), - base::TimeTicks(), 0, 0); - ASSERT_TRUE(browser_view->fullscreen_control_host_for_test()); - browser_view->fullscreen_control_host_for_test()->OnMouseEvent(mouse_move); - EXPECT_FALSE(browser_view->fullscreen_control_host_for_test()->IsVisible()); -} - -// Regression test for crbug.com/883104. Make sure that immersive fullscreen is -// disabled in locked fullscreen mode (also the shelf is hidden, and the -// fullscreen control popup doesn't show up). -IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTest, - LockedFullscreenDisablesImmersive) { - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); - EXPECT_FALSE(browser_view->GetWidget()->IsFullscreen()); - - // Set locked fullscreen state. - browser()->window()->GetNativeWindow()->SetProperty( - chromeos::kWindowPinTypeKey, chromeos::WindowPinType::kTrustedPinned); - - // We're fullscreen, immersive is disabled in locked fullscreen, and while - // we're at it, also make sure that the shelf is hidden. - EXPECT_TRUE(browser_view->GetWidget()->IsFullscreen()); - EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); - EXPECT_FALSE(IsShelfVisible()); - - // Make sure the fullscreen control popup doesn't show up. - ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, gfx::Point(1, 1), gfx::Point(), - base::TimeTicks(), 0, 0); - ASSERT_TRUE(browser_view->fullscreen_control_host_for_test()); - browser_view->fullscreen_control_host_for_test()->OnMouseEvent(mouse_move); - EXPECT_FALSE(browser_view->fullscreen_control_host_for_test()->IsVisible()); -} - -// Test the shelf visibility affected by entering and exiting tab fullscreen and -// immersive fullscreen. -IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTest, TabAndBrowserFullscreen) { - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); - - AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_TYPED); - - // The shelf should start out as visible. - EXPECT_TRUE(IsShelfVisible()); - - // 1) Test that entering tab fullscreen from immersive fullscreen hides the - // shelf. - chrome::ToggleFullscreenMode(browser()); - ASSERT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); - EXPECT_FALSE(IsShelfVisible()); - - content::WebContents* web_contents = browser_view->GetActiveWebContents(); - EnterFullscreenModeForTabAndWait(browser(), web_contents); - ASSERT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); - EXPECT_FALSE(IsShelfVisible()); - - // 2) Test that exiting tab fullscreen autohides the shelf. - ExitFullscreenModeForTabAndWait(browser(), web_contents); - ASSERT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); - EXPECT_FALSE(IsShelfVisible()); - - // 3) Test that exiting tab fullscreen and immersive fullscreen correctly - // updates the shelf visibility. - EnterFullscreenModeForTabAndWait(browser(), web_contents); - ASSERT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); - chrome::ToggleFullscreenMode(browser()); - ASSERT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); - EXPECT_TRUE(IsShelfVisible()); -} - -namespace { - class WebAppNonClientFrameViewAshTest : public TopChromeMdParamTest<InProcessBrowserTest> { public: @@ -1461,8 +1113,6 @@ INSTANTIATE_TEST_SUITE(BrowserNonClientFrameViewChromeOSTest); INSTANTIATE_TEST_SUITE(BrowserNonClientFrameViewChromeOSTestNoWebUiTabStrip); INSTANTIATE_TEST_SUITE(BrowserNonClientFrameViewChromeOSTestWithWebUiTabStrip); -INSTANTIATE_TEST_SUITE(ImmersiveModeBrowserViewTest); -INSTANTIATE_TEST_SUITE(ImmersiveModeBrowserViewTestNoWebUiTabStrip); INSTANTIATE_TEST_SUITE(WebAppNonClientFrameViewAshTest); INSTANTIATE_TEST_SUITE(HomeLauncherBrowserNonClientFrameViewChromeOSTest); INSTANTIATE_TEST_SUITE(TabSearchFrameCaptionButtonTest);
diff --git a/chrome/browser/ui/views/frame/immersive_mode_browser_view_test.cc b/chrome/browser/ui/views/frame/immersive_mode_browser_view_test.cc new file mode 100644 index 0000000..dbc2037 --- /dev/null +++ b/chrome/browser/ui/views/frame/immersive_mode_browser_view_test.cc
@@ -0,0 +1,388 @@ +// 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 "chrome/app/chrome_command_ids.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_commands.h" +#include "chrome/browser/ui/exclusive_access/exclusive_access_test.h" +#include "chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos.h" +#include "chrome/browser/ui/views/frame/browser_non_client_frame_view_chromeos_test_utils.h" +#include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/frame/immersive_mode_controller.h" +#include "chrome/browser/ui/views/frame/immersive_mode_controller_chromeos.h" +#include "chrome/browser/ui/views/frame/immersive_mode_tester.h" +#include "chrome/browser/ui/views/frame/tab_strip_region_view.h" +#include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/ui/base/window_pin_type.h" +#include "chromeos/ui/base/window_properties.h" +#include "chromeos/ui/frame/immersive/immersive_fullscreen_controller_test_api.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/browser_test.h" +#include "ui/aura/window.h" +#include "ui/base/page_transition_types.h" +#include "ui/base/ui_base_types.h" +#include "ui/events/test/event_generator.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" +#include "ui/views/widget/widget.h" +#include "ui/views/window/caption_button_layout_constants.h" +#include "url/gurl.h" +#include "url/url_constants.h" + +namespace { + +class ImmersiveModeBrowserViewTest + : public TopChromeMdParamTest<InProcessBrowserTest> { + public: + ImmersiveModeBrowserViewTest() = default; + ImmersiveModeBrowserViewTest(const ImmersiveModeBrowserViewTest&) = delete; + ImmersiveModeBrowserViewTest& operator=(const ImmersiveModeBrowserViewTest&) = + delete; + ~ImmersiveModeBrowserViewTest() override = default; + + // TopChromeMdParamTest<InProcessBrowserTest>: + void PreRunTestOnMainThread() override { + InProcessBrowserTest::PreRunTestOnMainThread(); + + BrowserView::SetDisableRevealerDelayForTesting(true); + + chromeos::ImmersiveFullscreenControllerTestApi( + static_cast<ImmersiveModeControllerChromeos*>( + BrowserView::GetBrowserViewForBrowser(browser()) + ->immersive_mode_controller()) + ->controller()) + .SetupForTest(); + } +}; + +} // namespace + +using ImmersiveModeBrowserViewTestNoWebUiTabStrip = + WebUiTabStripOverrideTest<false, ImmersiveModeBrowserViewTest>; + +// This test does not make sense for the webUI tabstrip, since the frame is not +// painted in that case. +IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTestNoWebUiTabStrip, + ImmersiveFullscreen) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + content::WebContents* web_contents = browser_view->GetActiveWebContents(); + BrowserNonClientFrameViewChromeOS* frame_view = + GetFrameViewChromeOS(browser_view); + + ImmersiveModeController* immersive_mode_controller = + browser_view->immersive_mode_controller(); + + // Immersive fullscreen starts disabled. + ASSERT_FALSE(browser_view->GetWidget()->IsFullscreen()); + EXPECT_FALSE(immersive_mode_controller->IsEnabled()); + + // Frame paints by default. + EXPECT_TRUE(frame_view->GetShouldPaint()); + EXPECT_LT(0, frame_view + ->GetBoundsForTabStripRegion( + browser_view->tab_strip_region_view()->GetMinimumSize()) + .bottom()); + + // Enter both browser fullscreen and tab fullscreen. Entering browser + // fullscreen should enable immersive fullscreen. + ToggleFullscreenModeAndWait(browser()); + EnterFullscreenModeForTabAndWait(browser(), web_contents); + EXPECT_TRUE(immersive_mode_controller->IsEnabled()); + + // An immersive reveal shows the buttons and the top of the frame. + std::unique_ptr<ImmersiveRevealedLock> revealed_lock( + immersive_mode_controller->GetRevealedLock( + ImmersiveModeController::ANIMATE_REVEAL_NO)); + EXPECT_TRUE(immersive_mode_controller->IsRevealed()); + EXPECT_TRUE(frame_view->GetShouldPaint()); + + // End the reveal. When in both immersive browser fullscreen and tab + // fullscreen. + revealed_lock.reset(); + EXPECT_FALSE(immersive_mode_controller->IsRevealed()); + EXPECT_FALSE(frame_view->GetShouldPaint()); + EXPECT_EQ(0, frame_view + ->GetBoundsForTabStripRegion( + browser_view->tab_strip_region_view()->GetMinimumSize()) + .bottom()); + + // Repeat test but without tab fullscreen. + ExitFullscreenModeForTabAndWait(browser(), web_contents); + + // Immersive reveal should have same behavior as before. + revealed_lock.reset(immersive_mode_controller->GetRevealedLock( + ImmersiveModeController::ANIMATE_REVEAL_NO)); + EXPECT_TRUE(immersive_mode_controller->IsRevealed()); + EXPECT_TRUE(frame_view->GetShouldPaint()); + EXPECT_LT(0, frame_view + ->GetBoundsForTabStripRegion( + browser_view->tab_strip_region_view()->GetMinimumSize()) + .bottom()); + + // Ending the reveal. Immersive browser should have the same behavior as full + // screen, i.e., having an origin of (0,0). + revealed_lock.reset(); + EXPECT_FALSE(frame_view->GetShouldPaint()); + EXPECT_EQ(0, frame_view + ->GetBoundsForTabStripRegion( + browser_view->tab_strip_region_view()->GetMinimumSize()) + .bottom()); + + // Exiting immersive fullscreen should make the caption buttons and the frame + // visible again. + { + FullscreenNotificationObserver waiter(browser()); + browser_view->ExitFullscreen(); + waiter.Wait(); + } + EXPECT_FALSE(immersive_mode_controller->IsEnabled()); + EXPECT_TRUE(frame_view->GetShouldPaint()); + EXPECT_LT(0, frame_view + ->GetBoundsForTabStripRegion( + browser_view->tab_strip_region_view()->GetMinimumSize()) + .bottom()); +} + +// Tests IDC_SELECT_TAB_0, IDC_SELECT_NEXT_TAB, IDC_SELECT_PREVIOUS_TAB and +// IDC_SELECT_LAST_TAB when the browser is in immersive fullscreen mode. +IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTest, + TabNavigationAcceleratorsFullscreenBrowser) { + ImmersiveModeTester tester(browser()); + // Make sure that the focus is on the webcontents rather than on the omnibox, + // because if the focus is on the omnibox, the tab strip will remain revealed + // in the immersive fullscreen mode and will interfere with this test waiting + // for the revealer to be dismissed. + browser()->tab_strip_model()->GetActiveWebContents()->Focus(); + + // Create three more tabs plus the existing one that browser tests start with. + const GURL about_blank(url::kAboutBlankURL); + AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED); + browser()->tab_strip_model()->GetActiveWebContents()->Focus(); + AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED); + browser()->tab_strip_model()->GetActiveWebContents()->Focus(); + AddTabAtIndex(0, about_blank, ui::PAGE_TRANSITION_TYPED); + browser()->tab_strip_model()->GetActiveWebContents()->Focus(); + + // Toggle fullscreen mode. + chrome::ToggleFullscreenMode(browser()); + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + EXPECT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); + // Wait for the end of the initial reveal which results from adding the new + // tabs and changing the focused tab. + tester.VerifyTabIndexAfterReveal(0); + + // Groups the browser command ID and its corresponding active tab index that + // will result when the command is executed in this test. + struct TestData { + int command; + int expected_index; + }; + constexpr TestData test_data[] = {{IDC_SELECT_LAST_TAB, 3}, + {IDC_SELECT_TAB_0, 0}, + {IDC_SELECT_NEXT_TAB, 1}, + {IDC_SELECT_PREVIOUS_TAB, 0}}; + for (const auto& datum : test_data) + tester.RunCommand(datum.command, datum.expected_index); +} + +// This test does not make sense for the webUI tabstrip, since the window layout +// is different in that case. +IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTestNoWebUiTabStrip, + TestCaptionButtonsReceiveEventsInBrowserImmersiveMode) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + + // Make sure that the focus is on the webcontents rather than on the omnibox, + // because if the focus is on the omnibox, the tab strip will remain revealed + // in the immersive fullscreen mode and will interfere with this test waiting + // for the revealer to be dismissed. + browser()->tab_strip_model()->GetActiveWebContents()->Focus(); + + // Toggle fullscreen mode. + chrome::ToggleFullscreenMode(browser()); + EXPECT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); + + EXPECT_TRUE(browser()->window()->IsFullscreen()); + EXPECT_FALSE(browser()->window()->IsMaximized()); + EXPECT_FALSE(browser_view->immersive_mode_controller()->IsRevealed()); + + std::unique_ptr<ImmersiveRevealedLock> revealed_lock( + browser_view->immersive_mode_controller()->GetRevealedLock( + ImmersiveModeController::ANIMATE_REVEAL_NO)); + EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed()); + + ImmersiveModeTester tester(browser()); + + // Clicking the "restore" caption button should exit the immersive mode. + aura::Window* window = browser()->window()->GetNativeWindow(); + ui::test::EventGenerator event_generator(window->GetRootWindow()); + gfx::Size button_size = views::GetCaptionButtonLayoutSize( + views::CaptionButtonLayoutSize::kBrowserCaptionMaximized); + gfx::Point point_in_restore_button(window->GetBoundsInScreen().top_right()); + point_in_restore_button.Offset(-button_size.width() * 3 / 2, + button_size.height() / 2); + + event_generator.MoveMouseTo(point_in_restore_button); + EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed()); + event_generator.ClickLeftButton(); + tester.WaitForFullscreenToExit(); + + EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); + EXPECT_FALSE(browser()->window()->IsFullscreen()); +} + +IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTest, + TestCaptionButtonsReceiveEventsInAppImmersiveMode) { + browser()->window()->Close(); + + // Open a new app window. + Browser::CreateParams params = Browser::CreateParams::CreateForApp( + "test_browser_app", true /* trusted_source */, gfx::Rect(0, 0, 300, 300), + browser()->profile(), true); + params.initial_show_state = ui::SHOW_STATE_DEFAULT; + Browser* browser = Browser::Create(params); + ASSERT_TRUE(browser->is_type_app()); + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); + + chromeos::ImmersiveFullscreenControllerTestApi( + static_cast<ImmersiveModeControllerChromeos*>( + browser_view->immersive_mode_controller()) + ->controller()) + .SetupForTest(); + + // Toggle fullscreen mode. + chrome::ToggleFullscreenMode(browser); + EXPECT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); + EXPECT_FALSE(browser_view->GetTabStripVisible()); + + EXPECT_TRUE(browser->window()->IsFullscreen()); + EXPECT_FALSE(browser->window()->IsMaximized()); + EXPECT_FALSE(browser_view->immersive_mode_controller()->IsRevealed()); + + std::unique_ptr<ImmersiveRevealedLock> revealed_lock( + browser_view->immersive_mode_controller()->GetRevealedLock( + ImmersiveModeController::ANIMATE_REVEAL_NO)); + EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed()); + + ImmersiveModeTester tester(browser); + AddBlankTabAndShow(browser); + + // Clicking the "restore" caption button should exit the immersive mode. + aura::Window* window = browser->window()->GetNativeWindow(); + ui::test::EventGenerator event_generator(window->GetRootWindow(), window); + gfx::Size button_size = views::GetCaptionButtonLayoutSize( + views::CaptionButtonLayoutSize::kBrowserCaptionMaximized); + gfx::Point point_in_restore_button( + window->GetBoundsInRootWindow().top_right()); + point_in_restore_button.Offset(-2 * button_size.width(), + button_size.height() / 2); + + event_generator.MoveMouseTo(point_in_restore_button); + EXPECT_TRUE(browser_view->immersive_mode_controller()->IsRevealed()); + event_generator.ClickLeftButton(); + tester.WaitForFullscreenToExit(); + + EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); + EXPECT_FALSE(browser->window()->IsFullscreen()); +} + +// Regression test for crbug.com/796171. Make sure that going from regular +// fullscreen to locked fullscreen does not cause a crash. +// Also test that the immersive mode is disabled afterwards (and the shelf is +// hidden, and the fullscreen control popup doesn't show up). +IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTest, + RegularToLockedFullscreenDisablesImmersive) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + + // Toggle fullscreen mode. + chrome::ToggleFullscreenMode(browser()); + EXPECT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); + + // Set locked fullscreen state. + browser()->window()->GetNativeWindow()->SetProperty( + chromeos::kWindowPinTypeKey, chromeos::WindowPinType::kTrustedPinned); + + // We're fullscreen, immersive is disabled in locked fullscreen, and while + // we're at it, also make sure that the shelf is hidden. + EXPECT_TRUE(browser_view->GetWidget()->IsFullscreen()); + EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); + EXPECT_FALSE(IsShelfVisible()); + + // Make sure the fullscreen control popup doesn't show up. + ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, gfx::Point(1, 1), gfx::Point(), + base::TimeTicks(), 0, 0); + ASSERT_TRUE(browser_view->fullscreen_control_host_for_test()); + browser_view->fullscreen_control_host_for_test()->OnMouseEvent(mouse_move); + EXPECT_FALSE(browser_view->fullscreen_control_host_for_test()->IsVisible()); +} + +// Regression test for crbug.com/883104. Make sure that immersive fullscreen is +// disabled in locked fullscreen mode (also the shelf is hidden, and the +// fullscreen control popup doesn't show up). +IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTest, + LockedFullscreenDisablesImmersive) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + EXPECT_FALSE(browser_view->GetWidget()->IsFullscreen()); + + // Set locked fullscreen state. + browser()->window()->GetNativeWindow()->SetProperty( + chromeos::kWindowPinTypeKey, chromeos::WindowPinType::kTrustedPinned); + + // We're fullscreen, immersive is disabled in locked fullscreen, and while + // we're at it, also make sure that the shelf is hidden. + EXPECT_TRUE(browser_view->GetWidget()->IsFullscreen()); + EXPECT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); + EXPECT_FALSE(IsShelfVisible()); + + // Make sure the fullscreen control popup doesn't show up. + ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, gfx::Point(1, 1), gfx::Point(), + base::TimeTicks(), 0, 0); + ASSERT_TRUE(browser_view->fullscreen_control_host_for_test()); + browser_view->fullscreen_control_host_for_test()->OnMouseEvent(mouse_move); + EXPECT_FALSE(browser_view->fullscreen_control_host_for_test()->IsVisible()); +} + +// Test the shelf visibility affected by entering and exiting tab fullscreen and +// immersive fullscreen. +IN_PROC_BROWSER_TEST_P(ImmersiveModeBrowserViewTest, TabAndBrowserFullscreen) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + + AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_TYPED); + + // The shelf should start out as visible. + EXPECT_TRUE(IsShelfVisible()); + + // 1) Test that entering tab fullscreen from immersive fullscreen hides the + // shelf. + chrome::ToggleFullscreenMode(browser()); + ASSERT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); + EXPECT_FALSE(IsShelfVisible()); + + content::WebContents* web_contents = browser_view->GetActiveWebContents(); + EnterFullscreenModeForTabAndWait(browser(), web_contents); + ASSERT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); + EXPECT_FALSE(IsShelfVisible()); + + // 2) Test that exiting tab fullscreen autohides the shelf. + ExitFullscreenModeForTabAndWait(browser(), web_contents); + ASSERT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); + EXPECT_FALSE(IsShelfVisible()); + + // 3) Test that exiting tab fullscreen and immersive fullscreen correctly + // updates the shelf visibility. + EnterFullscreenModeForTabAndWait(browser(), web_contents); + ASSERT_TRUE(browser_view->immersive_mode_controller()->IsEnabled()); + chrome::ToggleFullscreenMode(browser()); + ASSERT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); + EXPECT_TRUE(IsShelfVisible()); +} + +#define INSTANTIATE_TEST_SUITE(name) \ + INSTANTIATE_TEST_SUITE_P(All, name, ::testing::Values(false, true)) + +INSTANTIATE_TEST_SUITE(ImmersiveModeBrowserViewTest); +INSTANTIATE_TEST_SUITE(ImmersiveModeBrowserViewTestNoWebUiTabStrip);
diff --git a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc index d8c54f6..09dcbe7 100644 --- a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc +++ b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.cc
@@ -11,7 +11,9 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "chrome/browser/favicon/favicon_utils.h" +#include "chrome/browser/media/webrtc/capture_policy_utils.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" +#include "chrome/browser/media/webrtc/same_origin_observer.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -136,10 +138,23 @@ static_cast<uint8_t*>(bitmap->getPixels()), bitmap->computeByteSize())); } +WebContents* WebContentsFromId(GlobalRenderFrameHostId rfh_id) { + // Note that both FromID() and FromRenderFrameHost() are robust to null + // input. + return content::WebContents::FromRenderFrameHost( + content::RenderFrameHost::FromID(rfh_id)); +} + +GURL GetOriginFromId(GlobalRenderFrameHostId rfh_id) { + WebContents* capturer = WebContentsFromId(rfh_id); + if (!capturer) + return {}; + + return capturer->GetLastCommittedURL().GetOrigin(); +} + bool CanFocusCapturer(GlobalRenderFrameHostId capturer_id) { - // Note that both FromID() and FromRenderFrameHost() are robust to null input. - WebContents* const capturer = - WebContents::FromRenderFrameHost(RenderFrameHost::FromID(capturer_id)); + WebContents* const capturer = WebContentsFromId(capturer_id); if (!capturer) { return false; } @@ -148,6 +163,15 @@ extensions::kExtensionScheme); } +bool CapturerRestrictedToSameOrigin(GlobalRenderFrameHostId capturer_id) { + WebContents* capturer = WebContentsFromId(capturer_id); + if (!capturer) + return false; + return capture_policy::GetAllowedCaptureLevel( + capturer->GetLastCommittedURL().GetOrigin(), capturer) == + AllowedScreenCaptureLevel::kSameOrigin; +} + } // namespace // static @@ -166,7 +190,10 @@ std::u16string app_name, bool favicons_used_for_switch_to_tab_button) : capturer_(capturer), + capturer_origin_(GetOriginFromId(capturer)), can_focus_capturer_(CanFocusCapturer(capturer)), + capturer_restricted_to_same_origin_( + CapturerRestrictedToSameOrigin(capturer)), shared_tab_media_id_(media_id), app_name_(std::move(app_name)), favicons_used_for_switch_to_tab_button_( @@ -181,6 +208,16 @@ #if !BUILDFLAG(IS_CHROMEOS_ASH) InitContentsBorderWidget(shared_tab_); #endif + + if (capturer_restricted_to_same_origin_) { + // base::Unretained is safe here because we own the origin observer, so it + // cannot outlive us. + shared_tab_origin_observer_ = std::make_unique<SameOriginObserver>( + shared_tab_, capturer_origin_, + base::BindRepeating(&TabSharingUIViews::StopCaptureDueToPolicy, + base::Unretained(this)), + /*check_before_commit=*/true); + } } TabSharingUIViews::~TabSharingUIViews() { @@ -279,8 +316,9 @@ if (sad_tab_helper && sad_tab_helper->sad_tab()) return; - if (infobars_.find(contents) == infobars_.end()) + if (infobars_.find(contents) == infobars_.end()) { CreateInfobarForWebContents(contents); + } } void TabSharingUIViews::OnInfoBarRemoved(infobars::InfoBar* infobar, @@ -348,11 +386,26 @@ const bool is_capturing_tab = (GetGlobalId(contents) == capturer_); const bool is_captured_tab = (contents == shared_tab_); - // Never show the [share this tab instead] button on either the capturing - // tab or the captured tab. - const bool can_share_instead = + // We may want to show the "Share this tab instead" button, but we can only do + // so if we have a |source_callback_| and if this tab is neither the capturing + // nor captured tab. + const bool is_share_instead_button_possible = !source_callback_.is_null() && !is_capturing_tab && !is_captured_tab; + // If sharing this tab instead of the currently captured tab is possible, it + // may still be blocked by enterprise policy. If the enterprise policy is + // active, create an observer that will inform us when it's compliance state + // changes. + if (capturer_restricted_to_same_origin_ && is_share_instead_button_possible && + !base::Contains(same_origin_observers_, contents)) { + // We explicitly remove all infobars and clear all policy observers before + // destruction, so base::Unretained is safe here. + same_origin_observers_[contents] = std::make_unique<SameOriginObserver>( + contents, capturer_origin_, + base::BindRepeating(&TabSharingUIViews::CreateInfobarForWebContents, + base::Unretained(this))); + } + absl::optional<TabSharingInfoBarDelegate::FocusTarget> focus_target; if (can_focus_capturer_) { // Self-capture -> no switch-to button. @@ -368,10 +421,21 @@ } } + // Determine if we are currently allowed to share this tab by policy. + const bool is_sharing_allowed_by_policy = + !capturer_restricted_to_same_origin_ || + url::IsSameOriginWith(capturer_origin_, + contents->GetLastCommittedURL().GetOrigin()); + + // Never show the [share this tab instead] if sharing is not possible or is + // blocked by policy. + const bool can_show_share_instead_button = + is_share_instead_button_possible && is_sharing_allowed_by_policy; + infobars_[contents] = TabSharingInfoBarDelegate::Create( infobar_manager, shared_tab_name_, app_name_, - shared_tab_ == contents /*shared_tab*/, can_share_instead, focus_target, - this, favicons_used_for_switch_to_tab_button_); + shared_tab_ == contents /*shared_tab*/, can_show_share_instead_button, + focus_target, this, favicons_used_for_switch_to_tab_button_); } void TabSharingUIViews::RemoveInfobarsForAllTabs() { @@ -384,6 +448,7 @@ } infobars_.clear(); + same_origin_observers_.clear(); } void TabSharingUIViews::CreateTabCaptureIndicator() { @@ -424,8 +489,7 @@ return; } - WebContents* const capturer = - WebContents::FromRenderFrameHost(RenderFrameHost::FromID(capturer_)); + WebContents* const capturer = WebContentsFromId(capturer_); if (!capturer) { return; } @@ -472,8 +536,7 @@ ui::ImageModel TabSharingUIViews::TabFavicon( GlobalRenderFrameHostId rfh_id) const { - return TabFavicon(content::WebContents::FromRenderFrameHost( - content::RenderFrameHost::FromID(rfh_id))); + return TabFavicon(WebContentsFromId(rfh_id)); } void TabSharingUIViews::SetTabFaviconForTesting( @@ -481,3 +544,9 @@ const ui::ImageModel& favicon) { favicon_overrides_for_testing_[web_contents] = favicon; } + +void TabSharingUIViews::StopCaptureDueToPolicy(content::WebContents* contents) { + DCHECK(shared_tab_ == contents); + StopSharing(); + // TODO(https://crbug.com/1182221): Show a dialog that capture was terminated. +}
diff --git a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.h b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.h index 22462c1..7c5675c7 100644 --- a/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.h +++ b/chrome/browser/ui/views/tab_sharing/tab_sharing_ui_views.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/media/webrtc/media_stream_capture_indicator.h" +#include "chrome/browser/media/webrtc/same_origin_observer.h" #include "chrome/browser/ui/browser_list_observer.h" #include "chrome/browser/ui/tab_sharing/tab_sharing_ui.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -110,12 +111,19 @@ void SetTabFaviconForTesting(content::WebContents* web_contents, const ui::ImageModel& favicon); + void StopCaptureDueToPolicy(content::WebContents* contents); + std::map<content::WebContents*, infobars::InfoBar*> infobars_; + std::map<content::WebContents*, std::unique_ptr<SameOriginObserver>> + same_origin_observers_; const content::GlobalRenderFrameHostId capturer_; + const GURL capturer_origin_; const bool can_focus_capturer_; + const bool capturer_restricted_to_same_origin_ = false; content::DesktopMediaID shared_tab_media_id_; const std::u16string app_name_; content::WebContents* shared_tab_; + std::unique_ptr<SameOriginObserver> shared_tab_origin_observer_; std::u16string shared_tab_name_; Profile* profile_; std::unique_ptr<content::MediaStreamUI> tab_capture_indicator_ui_;
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 c8df1d4..ee86ef7 100644 --- a/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc +++ b/chrome/browser/ui/views/toolbar/read_later_toolbar_button.cc
@@ -104,7 +104,7 @@ private: void UpdateActiveURL(content::WebContents* contents) { auto* controller = contents_wrapper_->GetWebUIController(); - if (!controller) + if (!controller || !contents) return; controller->GetAs<ReadLaterUI>()->SetActiveTabURL(
diff --git a/chrome/browser/ui/web_applications/web_app_browsertest.cc b/chrome/browser/ui/web_applications/web_app_browsertest.cc index 06121df..7065a71 100644 --- a/chrome/browser/ui/web_applications/web_app_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_browsertest.cc
@@ -88,6 +88,10 @@ #include "ui/base/test/scoped_fake_nswindow_fullscreen.h" #endif +#if defined(OS_WIN) +#include "base/win/windows_version.h" +#endif + namespace { constexpr const char kExampleURL[] = "http://example.org/"; @@ -952,13 +956,7 @@ } #if defined(OS_MAC) || defined(OS_WIN) -// crbug.com/1235246: Disable the test on Windows due to a consistent failure. -#if defined(OS_WIN) -#define MAYBE_ShortcutIconCorrectColor DISABLED_ShortcutIconCorrectColor -#else -#define MAYBE_ShortcutIconCorrectColor ShortcutIconCorrectColor -#endif -IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, MAYBE_ShortcutIconCorrectColor) { +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, ShortcutIconCorrectColor) { os_hooks_suppress_.reset(); base::ScopedAllowBlockingForTesting allow_blocking; @@ -995,15 +993,18 @@ base::FilePath shortcut_path; auto* provider = WebAppProvider::Get(profile()); + SkColor expected_pixel_color = SkColorSetRGB(92, 92, 92); #if defined(OS_MAC) shortcut_path = application_dir.Append( provider->registrar().GetAppShortName(app_id) + ".app"); #elif defined(OS_WIN) shortcut_path = application_dir.AppendASCII( provider->registrar().GetAppShortName(app_id) + ".lnk"); + if (base::win::GetVersion() == base::win::Version::WIN7) + expected_pixel_color = SkColorSetRGB(91, 91, 91); #endif SkColor icon_pixel_color = GetIconTopLeftColor(shortcut_path); - EXPECT_EQ(SkColorSetRGB(92, 92, 92), icon_pixel_color); + EXPECT_EQ(expected_pixel_color, icon_pixel_color); } #endif @@ -1437,6 +1438,27 @@ EXPECT_EQ(absl::nullopt, app->manifest_id()); } +IN_PROC_BROWSER_TEST_F(WebAppBrowserTest, BrowserDisplayNotInstallable) { + GURL url = https_server()->GetURL( + "/banners/" + "manifest_test_page.html?manifest=manifest_display_browser.json"); + NavigateAndAwaitInstallabilityCheck(browser(), url); + + EXPECT_EQ(GetAppMenuCommandState(IDC_INSTALL_PWA, browser()), kNotPresent); + + // Install using Create Shortcut. + chrome::SetAutoAcceptWebAppDialogForTesting(/*auto_accept=*/true, + /*auto_open_in_window=*/false); + WebAppInstallObserver observer(profile()); + CHECK(chrome::ExecuteCommand(browser(), IDC_CREATE_SHORTCUT)); + observer.AwaitNextInstall(); + chrome::SetAutoAcceptWebAppDialogForTesting(false, false); + + // Navigate to this site again and install should still be disabled. + Browser* new_browser = NavigateInNewWindowAndAwaitInstallabilityCheck(url); + EXPECT_EQ(GetAppMenuCommandState(IDC_INSTALL_PWA, new_browser), kNotPresent); +} + IN_PROC_BROWSER_TEST_F(WebAppBrowserTest_WindowControlsOverlay, WindowControlsOverlay) { GURL test_url = https_server()->GetURL(
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc index c612d926..ad95c5c3 100644 --- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc +++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.cc
@@ -260,12 +260,22 @@ return chromeos::CrasAudioHandler::Get()->HasHotwordDevice(); } -bool IsVoiceMatchEnforcedOff(const PrefService* prefs) { - // If the hotword preference is managed to always disabled, then we should not - // show Voice Match flow. - return prefs->IsManagedPreference( - assistant::prefs::kAssistantHotwordEnabled) && - !prefs->GetBoolean(assistant::prefs::kAssistantHotwordEnabled); +bool IsVoiceMatchEnforcedOff(const PrefService* prefs, + bool is_oobe_in_progress) { + // If the hotword preference is managed to always disabled Voice Match flow is + // hidden. + if (prefs->IsManagedPreference(assistant::prefs::kAssistantHotwordEnabled) && + !prefs->GetBoolean(assistant::prefs::kAssistantHotwordEnabled)) { + return true; + } + // If Voice Match is disabled by policy during OOBE, then Voice Match flow is + // hidden. + if (is_oobe_in_progress && + !prefs->GetBoolean( + assistant::prefs::kAssistantVoiceMatchEnabledDuringOobe)) { + return true; + } + return false; } AssistantActivityControlConsent::SettingType
diff --git a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h index b3992c9..561f888 100644 --- a/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h +++ b/chrome/browser/ui/webui/chromeos/assistant_optin/assistant_optin_utils.h
@@ -87,7 +87,8 @@ bool IsHotwordDspAvailable(); -bool IsVoiceMatchEnforcedOff(const PrefService* prefs); +bool IsVoiceMatchEnforcedOff(const PrefService* prefs, + bool is_oobe_in_progress); sync_pb::UserConsentTypes::AssistantActivityControlConsent::SettingType GetActivityControlConsentSettingType(const SettingZippyList& setting_zippys);
diff --git a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc index 35f40514..1a78b97 100644 --- a/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.cc
@@ -26,6 +26,7 @@ #include "chromeos/services/assistant/public/proto/settings_ui.pb.h" #include "components/login/localized_values_builder.h" #include "components/prefs/pref_service.h" +#include "components/session_manager/core/session_manager.h" #include "components/user_manager/user_manager.h" #include "ui/base/l10n/l10n_util.h" #include "ui/chromeos/devicetype_utils.h" @@ -559,12 +560,16 @@ return; } + const bool is_oobe_in_progress = + session_manager::SessionManager::Get()->session_state() != + session_manager::SessionState::ACTIVE; // Pass string constants dictionary. auto dictionary = GetSettingsUiStrings(settings_ui, activity_control_needed_, equal_weight_buttons); PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs(); - dictionary.SetKey("voiceMatchEnforcedOff", - base::Value(IsVoiceMatchEnforcedOff(prefs))); + dictionary.SetKey( + "voiceMatchEnforcedOff", + base::Value(IsVoiceMatchEnforcedOff(prefs, is_oobe_in_progress))); dictionary.SetKey("childName", base::Value(GetGivenNameIfIsChild())); ReloadContent(dictionary); @@ -583,7 +588,7 @@ // If voice match is enabled, the screen that follows third party disclosure // is the "voice match" screen, not "get more" screen. - if (skip_get_more && IsVoiceMatchEnforcedOff(prefs)) + if (skip_get_more && IsVoiceMatchEnforcedOff(prefs, is_oobe_in_progress)) ShowNextScreen(); }
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc index 334674e9..27e1ed4 100644 --- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc +++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
@@ -16,6 +16,7 @@ #include "components/history_clusters/core/memories_features.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "url/gurl.h" #if !defined(CHROME_BRANDED) @@ -112,8 +113,15 @@ clusters_mojoms.emplace_back(std::move(cluster_mojom)); } - std::move(callback).Run(result.continuation_end_time, - std::move(clusters_mojoms)); + // TODO(tommycli): Resolve the semantics mismatch where the C++ handler uses + // `continuation_end_time` == base::Time() to represent exhausted history, + // while the mojom uses an explicit absl::optional value. + absl::optional<base::Time> continuation_end_time; + if (!result.continuation_end_time.is_null()) { + continuation_end_time = result.continuation_end_time; + } + + std::move(callback).Run(continuation_end_time, std::move(clusters_mojoms)); } // Exists temporarily only for developer usage. Never enabled via variations. @@ -149,7 +157,12 @@ void HistoryClustersHandler::QueryClusters(mojom::QueryParamsPtr query_params) { const std::string& query = query_params->query; const size_t max_count = query_params->max_count; - base::Time end_time = query_params->end_time.value_or(base::Time()); + base::Time end_time; + if (query_params->end_time) { + DCHECK(!query_params->end_time->is_null()) + << "Page called handler with non-null but invalid end_time."; + end_time = *(query_params->end_time); + } auto result_callback = base::BindOnce(&HistoryClustersHandler::OnClustersQueryResult, weak_ptr_factory_.GetWeakPtr(), std::move(query_params));
diff --git a/chrome/browser/ui/webui/read_later/read_later_page_handler.cc b/chrome/browser/ui/webui/read_later/read_later_page_handler.cc index f30887f..b2ed0c0 100644 --- a/chrome/browser/ui/webui/read_later/read_later_page_handler.cc +++ b/chrome/browser/ui/webui/read_later/read_later_page_handler.cc
@@ -193,7 +193,7 @@ ui::PAGE_TRANSITION_AUTO_BOOKMARK, false); browser->OpenURL(params); - if (mark_as_read) + if (mark_as_read && !side_panel_enabled) reading_list_model_->SetReadStatus(url, true); base::RecordAction(base::UserMetricsAction(
diff --git a/chrome/browser/ui/webui/settings/captions_handler.cc b/chrome/browser/ui/webui/settings/captions_handler.cc index 3184ae46..0d5117c 100644 --- a/chrome/browser/ui/webui/settings/captions_handler.cc +++ b/chrome/browser/ui/webui/settings/captions_handler.cc
@@ -17,16 +17,26 @@ #include "media/base/media_switches.h" #include "ui/base/l10n/l10n_util.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "ash/constants/ash_features.h" +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + #if defined(OS_WIN) || defined(OS_MAC) #include "chrome/browser/accessibility/caption_settings_dialog.h" #endif namespace settings { -CaptionsHandler::CaptionsHandler(PrefService* prefs) : prefs_(prefs) {} +CaptionsHandler::CaptionsHandler(PrefService* prefs) : prefs_(prefs) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + soda_available_ = + base::FeatureList::IsEnabled(ash::features::kOnDeviceSpeechRecognition); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) +} CaptionsHandler::~CaptionsHandler() { - speech::SodaInstaller::GetInstance()->RemoveObserver(this); + if (soda_available_) + speech::SodaInstaller::GetInstance()->RemoveObserver(this); } void CaptionsHandler::RegisterMessages() { @@ -41,11 +51,13 @@ } void CaptionsHandler::OnJavascriptAllowed() { - speech::SodaInstaller::GetInstance()->AddObserver(this); + if (soda_available_) + speech::SodaInstaller::GetInstance()->AddObserver(this); } void CaptionsHandler::OnJavascriptDisallowed() { - speech::SodaInstaller::GetInstance()->RemoveObserver(this); + if (soda_available_) + speech::SodaInstaller::GetInstance()->RemoveObserver(this); } void CaptionsHandler::HandleLiveCaptionSectionReady( @@ -61,7 +73,8 @@ } void CaptionsHandler::OnSodaInstalled() { - if (!base::FeatureList::IsEnabled(media::kLiveCaptionMultiLanguage)) { + if (!base::FeatureList::IsEnabled(media::kLiveCaptionMultiLanguage) && + soda_available_) { speech::SodaInstaller::GetInstance()->RemoveObserver(this); }
diff --git a/chrome/browser/ui/webui/settings/captions_handler.h b/chrome/browser/ui/webui/settings/captions_handler.h index 97cd770..0358bfc 100644 --- a/chrome/browser/ui/webui/settings/captions_handler.h +++ b/chrome/browser/ui/webui/settings/captions_handler.h
@@ -41,6 +41,7 @@ speech::LanguageCode language_code) override; PrefService* prefs_; + bool soda_available_ = true; }; } // namespace settings
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc index efad15a..c9562245 100644 --- a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler.cc
@@ -128,7 +128,7 @@ } void AccessibilityHandler::OnJavascriptDisallowed() { - if (features::IsExperimentalAccessibilityDictationOfflineEnabled()) + if (features::IsDictationOfflineAvailableAndEnabled()) soda_observation_.Reset(); } @@ -151,7 +151,7 @@ void AccessibilityHandler::MaybeAddSodaInstallerObserver() { // TODO(crbug.com/1195916): Don't display SODA status if the Dictation // language is not a downloaded or available SODA language. - if (features::IsExperimentalAccessibilityDictationOfflineEnabled()) { + if (features::IsDictationOfflineAvailableAndEnabled()) { const std::string dictation_locale = profile_->GetPrefs()->GetString(prefs::kAccessibilityDictationLocale); if (speech::SodaInstaller::GetInstance()->IsSodaInstalled(
diff --git a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_browsertest.cc b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_browsertest.cc index fd90d5c..f889698 100644 --- a/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_browsertest.cc +++ b/chrome/browser/ui/webui/settings/chromeos/accessibility_handler_browsertest.cc
@@ -7,6 +7,7 @@ #include <memory> #include <set> +#include "ash/constants/ash_features.h" #include "chrome/browser/ash/input_method/mock_input_method_engine.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile_manager.h" @@ -46,8 +47,10 @@ ~AccessibilityHandlerTest() override = default; void SetUpCommandLine(base::CommandLine* command_line) override { - scoped_feature_list_.InitAndEnableFeature( - features::kExperimentalAccessibilityDictationOffline); + scoped_feature_list_.InitWithFeatures( + {::features::kExperimentalAccessibilityDictationOffline, + features::kOnDeviceSpeechRecognition}, + {}); } void SetUpOnMainThread() override {
diff --git a/chrome/browser/web_applications/extension_status_utils.h b/chrome/browser/web_applications/extension_status_utils.h index 867f24b..fc193d0 100644 --- a/chrome/browser/web_applications/extension_status_utils.h +++ b/chrome/browser/web_applications/extension_status_utils.h
@@ -8,6 +8,7 @@ #include <string> #include "base/callback_forward.h" +#include "build/build_config.h" class Profile; @@ -36,6 +37,14 @@ bool IsExternalExtensionUninstalled(content::BrowserContext* context, const std::string& extension_id); +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) +// Returns whether |extension_id| is a Chrome App and should be blocked by the +// Chrome Apps Deprecation. Policy installed Chrome Apps are still allowed, and +// all apps are allowed if the deprecation feature flag is not enabled. +bool IsExtensionUnsupportedDeprecatedApp(content::BrowserContext* context, + const std::string& extension_id); +#endif + // Waits for extension system ready to run callback. void OnExtensionSystemReady(content::BrowserContext* context, base::OnceClosure callback);
diff --git a/chrome/browser/web_applications/extensions/bookmark_app_browsertest.cc b/chrome/browser/web_applications/extensions/bookmark_app_browsertest.cc new file mode 100644 index 0000000..2d31a9a5 --- /dev/null +++ b/chrome/browser/web_applications/extensions/bookmark_app_browsertest.cc
@@ -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. + +#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/components/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/extension_status_utils.cc b/chrome/browser/web_applications/extensions/extension_status_utils.cc index 3878af4..b2ffd6c 100644 --- a/chrome/browser/web_applications/extensions/extension_status_utils.cc +++ b/chrome/browser/web_applications/extensions/extension_status_utils.cc
@@ -5,8 +5,10 @@ #include "chrome/browser/web_applications/extension_status_utils.h" #include "base/one_shot_event.h" +#include "build/build_config.h" #include "chrome/browser/extensions/extension_management.h" #include "chrome/browser/extensions/preinstalled_apps.h" +#include "chrome/common/chrome_features.h" #include "chrome/common/extensions/extension_constants.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" @@ -72,6 +74,27 @@ return prefs && prefs->IsExternalExtensionUninstalled(extension_id); } +#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) +bool IsExtensionUnsupportedDeprecatedApp(content::BrowserContext* context, + const std::string& extension_id) { + auto* registry = ExtensionRegistry::Get(context); + // May be nullptr in unit tests. + if (!registry) + return false; + + const extensions::Extension* app = registry->GetExtensionById( + extension_id, extensions::ExtensionRegistry::EVERYTHING); + if (!app) + return false; + + // TODO(crbug.com/1235894): Figure out if "hosted apps" should be checked as + // well. + return base::FeatureList::IsEnabled(features::kChromeAppsDeprecation) && + (app->is_platform_app() || app->is_legacy_packaged_app()) && + !IsExtensionForceInstalled(context, extension_id, nullptr); +} +#endif + void OnExtensionSystemReady(content::BrowserContext* context, base::OnceClosure callback) { ExtensionSystem::Get(context)->ready().Post(FROM_HERE, std::move(callback));
diff --git a/chrome/common/extensions/manifest_unittest.cc b/chrome/common/extensions/manifest_unittest.cc index 2edc46e..8171c1a 100644 --- a/chrome/common/extensions/manifest_unittest.cc +++ b/chrome/common/extensions/manifest_unittest.cc
@@ -57,9 +57,10 @@ void MutateManifest(std::unique_ptr<Manifest>* manifest, const std::string& key, std::unique_ptr<base::Value> value) { - auto manifest_value = manifest->get()->value()->CreateDeepCopy(); + auto manifest_value = base::DictionaryValue::From( + base::Value::ToUniquePtrValue(manifest->get()->value()->Clone())); if (value) - manifest_value->Set(key, std::move(value)); + manifest_value->SetPath(key, std::move(*value)); else manifest_value->RemovePath(key); ExtensionId extension_id = manifest->get()->extension_id(); @@ -71,7 +72,8 @@ // and uses the |for_login_screen| during creation to determine its type. void MutateManifestForLoginScreen(std::unique_ptr<Manifest>* manifest, bool for_login_screen) { - auto manifest_value = manifest->get()->value()->CreateDeepCopy(); + auto manifest_value = base::DictionaryValue::From( + base::Value::ToUniquePtrValue(manifest->get()->value()->Clone())); ExtensionId extension_id = manifest->get()->extension_id(); if (for_login_screen) { *manifest = Manifest::CreateManifestForLoginScreen( @@ -118,7 +120,9 @@ // Test EqualsForTesting. auto manifest2 = std::make_unique<Manifest>( - ManifestLocation::kInternal, manifest->value()->CreateDeepCopy(), + ManifestLocation::kInternal, + base::DictionaryValue::From( + base::Value::ToUniquePtrValue(manifest->value()->Clone())), crx_file::id_util::GenerateId("extid")); EXPECT_TRUE(manifest->EqualsForTesting(*manifest2)); EXPECT_TRUE(manifest2->EqualsForTesting(*manifest)); @@ -129,8 +133,8 @@ // Verifies that key restriction based on type works. TEST_F(ManifestUnitTest, ExtensionTypes) { std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue()); - value->SetString(keys::kName, "extension"); - value->SetString(keys::kVersion, "1"); + value->SetStringKey(keys::kName, "extension"); + value->SetStringKey(keys::kVersion, "1"); std::unique_ptr<Manifest> manifest( new Manifest(ManifestLocation::kInternal, std::move(value),
diff --git a/chrome/installer/linux/BUILD.gn b/chrome/installer/linux/BUILD.gn index 338fc08..4d9054e 100644 --- a/chrome/installer/linux/BUILD.gn +++ b/chrome/installer/linux/BUILD.gn
@@ -34,8 +34,8 @@ packaging_files_executables = [ "$root_out_dir/chrome", + "$root_out_dir/chrome_crashpad_handler", "$root_out_dir/chrome_sandbox", - "$root_out_dir/crashpad_handler", ] packaging_files_shlibs = [] @@ -322,8 +322,8 @@ "//chrome", "//chrome:packed_resources", "//chrome/browser/resources/media/mei_preload:component", + "//components/crash/core/app:chrome_crashpad_handler", "//sandbox/linux:chrome_sandbox", - "//third_party/crashpad/crashpad/handler:crashpad_handler", ] if (enable_nacl) { public_deps += [
diff --git a/chrome/installer/linux/common/installer.include b/chrome/installer/linux/common/installer.include index 409a433..ee22774 100644 --- a/chrome/installer/linux/common/installer.include +++ b/chrome/installer/linux/common/installer.include
@@ -143,11 +143,11 @@ install -m 755 "${STRIPPEDFILE}" "${STAGEDIR}/${INSTALLDIR}/${PROGNAME}" # crashpad - buildfile="${OUTPUTDIR}/crashpad_handler" + buildfile="${OUTPUTDIR}/chrome_crashpad_handler" strippedfile="${buildfile}.stripped" debugfile="${buildfile}.debug" "${OUTPUTDIR}/installer/common/eu-strip" -o "${strippedfile}" -f "${debugfile}" "${buildfile}" - install -m 755 "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/crashpad_handler" + install -m 755 "${strippedfile}" "${STAGEDIR}/${INSTALLDIR}/chrome_crashpad_handler" # resources install -m 644 "${OUTPUTDIR}/resources.pak" "${STAGEDIR}/${INSTALLDIR}/"
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 6545ad6..251019c 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1990,6 +1990,7 @@ "../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", @@ -3309,6 +3310,7 @@ "../browser/ui/views/extensions/extension_dialog_bounds_browsertest.cc", "../browser/ui/views/frame/browser_frame_ash_browsertest.cc", "../browser/ui/views/frame/browser_non_client_frame_view_chromeos_browsertest.cc", + "../browser/ui/views/frame/immersive_mode_browser_view_test.cc", "../browser/ui/views/frame/immersive_mode_controller_chromeos_browsertest.cc", "../browser/ui/views/frame/system_menu_model_builder_browsertest_chromeos.cc", "../browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc", @@ -3875,6 +3877,7 @@ "../browser/lacros/browser_test_util.cc", "../browser/lacros/browser_test_util.h", "../browser/lacros/device_attributes_lacros_browsertest.cc", + "../browser/lacros/download_controller_client_lacros_browsertest.cc", "../browser/lacros/file_manager_lacros_browsertest.cc", "../browser/lacros/holding_space_service_lacros_browsertest.cc", "../browser/lacros/idle_service_lacros_browsertest.cc",
diff --git a/chrome/test/data/banners/manifest_display_browser.json b/chrome/test/data/banners/manifest_display_browser.json new file mode 100644 index 0000000..d0c7c4e4 --- /dev/null +++ b/chrome/test/data/banners/manifest_display_browser.json
@@ -0,0 +1,38 @@ +{ + "name": "Manifest test app with browser display", + "icons": [ + { + "src": "launcher-icon-1x.png", + "sizes": "48x48", + "type": "image/png" + }, + { + "src": "launcher-icon-1-5x.png", + "sizes": "72x72", + "type": "image/png" + }, + { + "src": "launcher-icon-2x.png", + "sizes": "96x96", + "type": "image/png", + "purpose": "any monochrome" + }, + { + "src": "launcher-icon-3x.png", + "sizes": "144x144", + "type": "image/png" + }, + { + "src": "launcher-icon-4x.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "image-512px.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "start_url": "manifest_test_page.html", + "display": "browser" +}
diff --git a/chrome/test/data/extensions/app_with_tab_container/empty.html b/chrome/test/data/extensions/app_with_tab_container/empty.html index 602e06c..d5fbcecc 100644 --- a/chrome/test/data/extensions/app_with_tab_container/empty.html +++ b/chrome/test/data/extensions/app_with_tab_container/empty.html
@@ -1,5 +1,8 @@ <html> +<title> +app_with_tab_container/empty.html title +</title> <body> Empty.html </body> -</html> \ No newline at end of file +</html>
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index a306c2bb..08bdb3c 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -12512,6 +12512,34 @@ } ] }, + + "AssistantVoiceMatchEnabledDuringOobe": { + "os": [ + "chromeos_ash" + ], + "policy_pref_mapping_tests": [ + { + "note": "Checking default value (no policies set)", + "policies": {}, + "prefs": { + "settings.voice_interaction.oobe_voice_match.enabled": { + "default_value": true + } + } + }, + { + "policies": { + "AssistantVoiceMatchEnabledDuringOobe": false + }, + "prefs": { + "settings.voice_interaction.oobe_voice_match.enabled": { + "value": false + } + } + } + ] + }, + "VoiceInteractionContextEnabled": { "os": [ "chromeos_ash"
diff --git a/chrome/test/data/printing/embedded_images.pdf b/chrome/test/data/printing/embedded_images.pdf new file mode 100644 index 0000000..82adbeaa --- /dev/null +++ b/chrome/test/data/printing/embedded_images.pdf Binary files differ
diff --git a/chrome/test/data/printing/embedded_images_ps_level2.emf b/chrome/test/data/printing/embedded_images_ps_level2.emf new file mode 100644 index 0000000..f40096f --- /dev/null +++ b/chrome/test/data/printing/embedded_images_ps_level2.emf Binary files differ
diff --git a/chrome/test/data/printing/embedded_images_ps_level3.emf b/chrome/test/data/printing/embedded_images_ps_level3.emf new file mode 100644 index 0000000..615fc27 --- /dev/null +++ b/chrome/test/data/printing/embedded_images_ps_level3.emf Binary files differ
diff --git a/chrome/test/data/webui/chromeos/scanning/multi_page_scan_test.js b/chrome/test/data/webui/chromeos/scanning/multi_page_scan_test.js index b955895..f620af7 100644 --- a/chrome/test/data/webui/chromeos/scanning/multi_page_scan_test.js +++ b/chrome/test/data/webui/chromeos/scanning/multi_page_scan_test.js
@@ -53,4 +53,15 @@ multiPageScan.$$('#scanButton').textContent.trim()); }); }); + + // Verify clicking the Scan button fires the 'scan-next-page' event. + test('scanButtonFiresEvent', () => { + let scanNextPageEventFired = false; + multiPageScan.addEventListener('scan-next-page', function() { + scanNextPageEventFired = true; + }); + + multiPageScan.$$('#scanButton').click(); + assertTrue(scanNextPageEventFired); + }); }
diff --git a/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js b/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js index 07e248b..84abfd5 100644 --- a/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js +++ b/chrome/test/data/webui/chromeos/scanning/scanning_app_test.js
@@ -7,7 +7,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js'; import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js'; import {setScanServiceForTesting} from 'chrome://scanning/mojo_interface_provider.js'; -import {MAX_NUM_SAVED_SCANNERS, ScannerArr, ScannerSetting, ScanSettings} from 'chrome://scanning/scanning_app_types.js'; +import {MAX_NUM_SAVED_SCANNERS, ScannerArr, ScannerSetting, ScanSettings, StartMultiPageScanResponse} from 'chrome://scanning/scanning_app_types.js'; import {tokenToString} from 'chrome://scanning/scanning_app_util.js'; import {ScanningBrowserProxyImpl} from 'chrome://scanning/scanning_browser_proxy.js'; @@ -87,6 +87,9 @@ /** @private {!Map<string, !PromiseResolver>} */ this.resolverMap_ = new Map(); + /** @private {?ash.scanning.mojom.MultiPageScanControllerInterface} */ + this.multiPageScanController_ = null; + /** @private {!ScannerArr} */ this.scanners_ = []; @@ -113,6 +116,7 @@ this.resolverMap_.set('getScanners', new PromiseResolver()); this.resolverMap_.set('getScannerCapabilities', new PromiseResolver()); this.resolverMap_.set('startScan', new PromiseResolver()); + this.resolverMap_.set('startMultiPageScan', new PromiseResolver()); this.resolverMap_.set('cancelScan', new PromiseResolver()); } @@ -146,6 +150,13 @@ }); } + /** + * @param {?ash.scanning.mojom.MultiPageScanControllerInterface} controller + */ + setMultiPageScanController(controller) { + this.multiPageScanController_ = controller; + } + /** @param {!ScannerArr} scanners */ setScanners(scanners) { this.scanners_ = scanners; @@ -245,13 +256,85 @@ }); } - startMultiPageScan() {} + /** + * @param {!mojoBase.mojom.UnguessableToken} scanner_id + * @param {!ash.scanning.mojom.ScanSettings} settings + * @param {!ash.scanning.mojom.ScanJobObserverRemote} remote + * @return {!Promise<StartMultiPageScanResponse>} + */ + startMultiPageScan(scanner_id, settings, remote) { + return new Promise(resolve => { + this.scanJobObserverRemote_ = remote; + this.methodCalled('startMultiPageScan'); + resolve({ + controller: this.failStartScan_ ? null : this.multiPageScanController_ + }); + }); + } cancelScan() { this.methodCalled('cancelScan'); } } +/** @implements {ash.scanning.mojom.MultiPageScanControllerInterface} */ +class FakeMultiPageScanController { + constructor() { + /** @private {!Map<string, !PromiseResolver>} */ + this.resolverMap_ = new Map(); + + this.resetForTest(); + } + + resetForTest() { + this.resolverMap_.set('scanNextPage', new PromiseResolver()); + } + + /** + * @param {string} methodName + * @return {!PromiseResolver} + * @private + */ + getResolver_(methodName) { + let method = this.resolverMap_.get(methodName); + assertTrue(!!method, `Method '${methodName}' not found.`); + return method; + } + + /** + * @param {string} methodName + * @protected + */ + methodCalled(methodName) { + this.getResolver_(methodName).resolve(); + } + + /** + * @param {string} methodName + * @return {!Promise} + */ + whenCalled(methodName) { + return this.getResolver_(methodName).promise.then(() => { + // Support sequential calls to whenCalled() by replacing the promise. + this.resolverMap_.set(methodName, new PromiseResolver()); + }); + } + + /** + * @param {!mojoBase.mojom.UnguessableToken} scanner_id + * @param {!ash.scanning.mojom.ScanSettings} settings + * @return {!Promise<{success: boolean}>} + */ + scanNextPage(scanner_id, settings) { + return new Promise(resolve => { + this.methodCalled('scanNextPage'); + resolve({success: true}); + }); + } + + completeMultiPageScan() {} +} + export function scanningAppTest() { /** @type {?ScanningAppElement} */ let scanningApp = null; @@ -259,6 +342,9 @@ /** @type {?FakeScanService} */ let fakeScanService_ = null; + /** @type {?FakeMultiPageScanController} */ + let fakeMultiPageScanController_ = null; + /** @type {?TestScanningBrowserProxy} */ let testBrowserProxy = null; @@ -321,6 +407,7 @@ suiteSetup(() => { fakeScanService_ = new FakeScanService(); setScanServiceForTesting(fakeScanService_); + fakeMultiPageScanController_ = new FakeMultiPageScanController(); testBrowserProxy = new TestScanningBrowserProxy(); ScanningBrowserProxyImpl.instance_ = testBrowserProxy; testBrowserProxy.setMyFilesPath(MY_FILES_PATH); @@ -360,6 +447,7 @@ * @return {!Promise} */ function initializeScanningApp(scanners, capabilities) { + fakeScanService_.setMultiPageScanController(fakeMultiPageScanController_); fakeScanService_.setScanners(scanners); fakeScanService_.setCapabilities(capabilities); scanningApp = /** @type {!ScanningAppElement} */ ( @@ -671,16 +759,38 @@ const scanButton = scanningApp.$$('#scanButton'); assertEquals('Scan page 1', scanButton.textContent.trim()); scanButton.click(); - return fakeScanService_.whenCalled('startScan'); + return fakeScanService_.whenCalled('startMultiPageScan'); }) .then(() => { return fakeScanService_.simulatePageComplete(1); }) .then(() => { + // The scanned images and multi-page scan page should be visible. assertTrue(isVisible(/** @type {!HTMLElement} */ ( scanningApp.$$('#scanPreview').$$('#scannedImages')))); assertTrue(isVisible( /** @type {!HTMLElement} */ (scanningApp.$$('multi-page-scan')))); + + const scanNextPageButton = + scanningApp.$$('multi-page-scan').$$('#scanButton'); + assertEquals('Scan page 2', scanNextPageButton.textContent.trim()); + scanNextPageButton.click(); + return fakeMultiPageScanController_.whenCalled('scanNextPage'); + }) + .then(() => { + return fakeScanService_.simulatePageComplete(1); + }) + .then(() => { + // The scanned images and multi-page scan page should still be visible + // after scanning the next page. + assertTrue(isVisible(/** @type {!HTMLElement} */ ( + scanningApp.$$('#scanPreview').$$('#scannedImages')))); + assertTrue(isVisible( + /** @type {!HTMLElement} */ (scanningApp.$$('multi-page-scan')))); + + const scanNextPageButton = + scanningApp.$$('multi-page-scan').$$('#scanButton'); + assertEquals('Scan page 3', scanNextPageButton.textContent.trim()); }); });
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.js index e228f46..6a1f11e 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.js +++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.js
@@ -4,7 +4,7 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {AcceleratorEditDialogElement} from 'chrome://shortcut-customization/accelerator_edit_dialog.js'; -import {Modifier} from 'chrome://shortcut-customization/shortcut_types.js'; +import {AcceleratorInfo, AcceleratorKeys, AcceleratorState, AcceleratorType, Modifier} from 'chrome://shortcut-customization/shortcut_types.js'; import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; @@ -24,15 +24,33 @@ }); test('LoadsBasicDialog', async () => { - // TODO(jimmyxgong): Update the type of the test accelerator with the mojom - // version. - const accelerators = [ - {modifiers: Modifier.SHIFT | Modifier.CONTROL, key: 'g', rawKey: 0x0}, - {modifiers: Modifier.CONTROL, key: 'c', rawKey: 0x0} - ]; + /** @type {!AcceleratorInfo} */ + const acceleratorInfo1 = { + accelerator: /** @type {!AcceleratorKeys} */ ({ + modifiers: Modifier.CONTROL | Modifier.SHIFT, + key: 71, + key_display: 'g', + }), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, + }; + + /** @type {!AcceleratorInfo} */ + const acceleratorInfo2 = { + accelerator: /** @type {!AcceleratorKeys} */ ({ + modifiers: Modifier.CONTROL, + key: 67, + key_display: 'c', + }), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, + }; + + const accelerators = [acceleratorInfo1, acceleratorInfo2]; + const description = 'test shortcut'; - viewElement.accelerators = accelerators; + viewElement.acceleratorInfos = accelerators; viewElement.description = description; await flush(); const dialog = viewElement.shadowRoot.querySelector('cr-dialog'); @@ -72,15 +90,32 @@ }); test('AddShortcut', async () => { - // TODO(jimmyxgong): Update the type of the test accelerator with the mojom - // version. - const accelerators = [ - {modifiers: Modifier.SHIFT | Modifier.CONTROL, key: 'g', rawKey: 0x0}, - {modifiers: Modifier.CONTROL, key: 'c', rawKey: 0x0} - ]; + /** @type {!AcceleratorInfo} */ + const acceleratorInfo1 = { + accelerator: /** @type {!AcceleratorKeys} */ ({ + modifiers: Modifier.CONTROL | Modifier.SHIFT, + key: 71, + key_display: 'g', + }), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, + }; + + /** @type {!AcceleratorInfo} */ + const acceleratorInfo2 = { + accelerator: /** @type {!AcceleratorKeys} */ ({ + modifiers: Modifier.CONTROL, + key: 67, + key_display: 'c', + }), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, + }; + + const acceleratorInfos = [acceleratorInfo1, acceleratorInfo2]; const description = 'test shortcut'; - viewElement.accelerators = accelerators; + viewElement.acceleratorInfos = acceleratorInfos; viewElement.description = description; await flush(); const dialog = viewElement.shadowRoot.querySelector('cr-dialog');
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.js index ef75a8c..7314777 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.js +++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_view_test.js
@@ -4,7 +4,7 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {AcceleratorEditViewElement} from 'chrome://shortcut-customization/accelerator_edit_view.js'; -import {Modifier} from 'chrome://shortcut-customization/shortcut_types.js'; +import {AcceleratorInfo, AcceleratorKeys, AcceleratorState, AcceleratorType, Modifier} from 'chrome://shortcut-customization/shortcut_types.js'; import {assertEquals, assertFalse, assertTrue} from '../../chai_assert.js'; @@ -24,15 +24,18 @@ }); test('LoadsBasicEditView', async () => { - // TODO(jimmyxgong): Update the type of the test accelerator with the mojom - // version. - const accelerator = { - modifiers: Modifier.SHIFT | Modifier.CONTROL, - key: 'g', - rawKey: 0x0 + /** @type {!AcceleratorInfo} */ + const acceleratorInfo = { + accelerator: /** @type {!AcceleratorKeys} */ ({ + modifiers: Modifier.CONTROL | Modifier.SHIFT, + key: 71, + key_display: 'g', + }), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, }; - editViewElement.accelerator = accelerator; + editViewElement.acceleratorInfo = acceleratorInfo; await flush(); // Check that the edit buttons are visible.
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_row_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_row_test.js index b64fd054..69105dda 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_row_test.js +++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_row_test.js
@@ -4,7 +4,7 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {AcceleratorRowElement} from 'chrome://shortcut-customization/accelerator_row.js'; -import {Modifier} from 'chrome://shortcut-customization/shortcut_types.js'; +import {AcceleratorInfo, AcceleratorKeys, AcceleratorState, AcceleratorType, Modifier} from 'chrome://shortcut-customization/shortcut_types.js'; import {assertEquals} from '../../chai_assert.js'; @@ -24,15 +24,32 @@ }); test('LoadsBasicRow', async () => { - // TODO(jimmyxgong): Update the type of the test accelerator with the mojom - // version. - const accelerators = [ - {modifiers: Modifier.SHIFT | Modifier.CONTROL, key: 'g', rawKey: 0x0}, - {modifiers: Modifier.CONTROL, key: 'c', rawKey: 0x0} - ]; + /** @type {!AcceleratorInfo} */ + const acceleratorInfo1 = { + accelerator: /** @type {!AcceleratorKeys} */ ({ + modifiers: Modifier.CONTROL | Modifier.SHIFT, + key: 71, + key_display: 'g', + }), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, + }; + + /** @type {!AcceleratorInfo} */ + const acceleratorInfo2 = { + accelerator: /** @type {!AcceleratorKeys} */ ({ + modifiers: Modifier.CONTROL, + key: 67, + key_display: 'c', + }), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, + }; + + const accelerators = [acceleratorInfo1, acceleratorInfo2]; const description = 'test shortcut'; - rowElement.accelerators = accelerators; + rowElement.acceleratorInfos = accelerators; rowElement.description = description; await flush(); const acceleratorElements =
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.js index fe5caf9..58a6a77 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.js +++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_subsection_test.js
@@ -4,7 +4,8 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {AcceleratorSubsectionElement} from 'chrome://shortcut-customization/accelerator_subsection.js'; -import {Modifier} from 'chrome://shortcut-customization/shortcut_types.js'; +import {AcceleratorInfo, AcceleratorKeys, AcceleratorState, AcceleratorType, Modifier} from 'chrome://shortcut-customization/shortcut_types.js'; + import {assertEquals} from '../../chai_assert.js'; @@ -28,18 +29,38 @@ test('LoadsBasicSection', async () => { // TODO(jimmyxgong): Update the type of the test accelerator with the mojom // version. - const accelerators = [ - {modifiers: Modifier.SHIFT | Modifier.CONTROL, key: 'g', rawKey: 0x0}, - {modifiers: Modifier.CONTROL, key: 'c', rawKey: 0x0} - ]; + /** @type {!AcceleratorInfo} */ + const acceleratorInfo1 = { + accelerator: /** @type {!AcceleratorKeys} */ ({ + modifiers: Modifier.CONTROL | Modifier.SHIFT, + key: 71, + key_display: 'g', + }), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, + }; + + /** @type {!AcceleratorInfo} */ + const acceleratorInfo2 = { + accelerator: /** @type {!AcceleratorKeys} */ ({ + modifiers: Modifier.CONTROL, + key: 67, + key_display: 'c', + }), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, + }; + + const accelerators = [acceleratorInfo1, acceleratorInfo2]; const description = 'test shortcut'; const title = 'test title'; sectionElement.title = title; sectionElement.acceleratorContainer = [{ description: description, - accelerators: accelerators, + acceleratorInfos: accelerators, }]; + await flush(); assertEquals( title,
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.js b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.js index e2f59351..16034e26 100644 --- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.js +++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_view_test.js
@@ -4,7 +4,7 @@ import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {AcceleratorViewElement} from 'chrome://shortcut-customization/accelerator_view.js'; -import {Modifier} from 'chrome://shortcut-customization/shortcut_types.js'; +import {AcceleratorInfo, AcceleratorKeys, AcceleratorState, AcceleratorType, Modifier} from 'chrome://shortcut-customization/shortcut_types.js'; import {assertEquals, assertTrue} from '../../chai_assert.js'; @@ -24,15 +24,18 @@ }); test('LoadsBasicAccelerator', async () => { - // TODO(jimmyxgong): Update the type of the test accelerator with the mojom - // version. - const accelerator = { - modifiers: Modifier.SHIFT | Modifier.CONTROL, - key: 'g', - rawKey: 0x0, + /** @type {!AcceleratorInfo} */ + const acceleratorInfo = { + accelerator: /** @type {!AcceleratorKeys} */ ({ + modifiers: Modifier.CONTROL | Modifier.SHIFT, + key: 71, + key_display: 'g', + }), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, }; - viewElement.accelerator = accelerator; + viewElement.acceleratorInfo = acceleratorInfo; await flush(); const keys = viewElement.shadowRoot.querySelectorAll('input-key'); // Three keys: shift, control, g @@ -47,15 +50,18 @@ }); test('EditableAccelerator', async () => { - // TODO(jimmyxgong): Update the type of the test accelerator with the mojom - // version. - const accelerator = { - modifiers: Modifier.SHIFT | Modifier.CONTROL, - key: 'g', - rawKey: 0x0, + /** @type {!AcceleratorInfo} */ + const acceleratorInfo = { + accelerator: /** @type {!AcceleratorKeys} */ ({ + modifiers: Modifier.CONTROL | Modifier.SHIFT, + key: 71, + key_display: 'g', + }), + type: AcceleratorType.kDefault, + state: AcceleratorState.kEnabled, }; - viewElement.accelerator = accelerator; + viewElement.acceleratorInfo = acceleratorInfo; await flush(); // Enable the edit view. viewElement.isEditable = true;
diff --git a/chrome/test/data/webui/settings/chromeos/os_bluetooth_page_tests.js b/chrome/test/data/webui/settings/chromeos/os_bluetooth_page_tests.js index 4c334ed..94dba62 100644 --- a/chrome/test/data/webui/settings/chromeos/os_bluetooth_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_bluetooth_page_tests.js
@@ -19,7 +19,10 @@ setup(function() { // TODO(crbug.com/1010321): Replace this with fake_cros_bluetooth_config // when it is created. - setBluetoothConfigForTesting({observeSystemProperties: (observer) => {}}); + setBluetoothConfigForTesting({ + observeSystemProperties: (observer) => {}, + setBluetoothEnabledState: (enabled) => {} + }); bluetoothPage = document.createElement('os-settings-bluetooth-page'); document.body.appendChild(bluetoothPage); Polymer.dom.flush();
diff --git a/chrome/test/data/webui/settings/chromeos/os_bluetooth_summary_tests.js b/chrome/test/data/webui/settings/chromeos/os_bluetooth_summary_tests.js index 53d4cd4..7b274eb 100644 --- a/chrome/test/data/webui/settings/chromeos/os_bluetooth_summary_tests.js +++ b/chrome/test/data/webui/settings/chromeos/os_bluetooth_summary_tests.js
@@ -10,6 +10,7 @@ // #import {flush, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; // #import {Router, Route, routes} from 'chrome://os-settings/chromeos/os_settings.js'; // #import {assertTrue} from '../../../chai_assert.js'; +// #import {setBluetoothConfigForTesting} from 'chrome://resources/cr_components/chromeos/bluetooth/cros_bluetooth_config.js'; // clang-format on suite('OsBluetoothSummaryTest', function() { @@ -17,6 +18,9 @@ let bluetoothSummary; setup(function() { + // TODO(crbug.com/1010321): Replace this with fake_cros_bluetooth_config + // when it is created. + setBluetoothConfigForTesting({setBluetoothEnabledState: (enabled) => {}}); bluetoothSummary = document.createElement('os-settings-bluetooth-summary'); document.body.appendChild(bluetoothSummary); Polymer.dom.flush(); @@ -37,4 +41,26 @@ settings.Router.getInstance().getCurrentRoute(), settings.routes.BLUETOOTH_DEVICES); }); + + test('Toggle button states', async function() { + // TODO(crbug.com/1010321): Remove |mockSystemProperties| once + // fake_cros_bluetooth_config has been added. + const mockSystemProperties = { + systemState: chromeos.bluetoothConfig.mojom.BluetoothSystemState.kEnabled, + }; + bluetoothSummary.systemProperties = {...mockSystemProperties}; + + const enableBluettonToggle = bluetoothSummary.$$('#enableBluetoothToggle'); + assertTrue(!!enableBluettonToggle); + assertTrue(enableBluettonToggle.checked); + + // Simulate disabled state. + mockSystemProperties.systemState = + chromeos.bluetoothConfig.mojom.BluetoothSystemState.kDisabled; + bluetoothSummary.systemProperties = {...mockSystemProperties}; + await flushAsync(); + + assertFalse(enableBluettonToggle.checked); + }); + }); \ No newline at end of file
diff --git a/chrome/tools/build/chromeos/FILES.cfg b/chrome/tools/build/chromeos/FILES.cfg index 6e346a4..e48a540b 100644 --- a/chrome/tools/build/chromeos/FILES.cfg +++ b/chrome/tools/build/chromeos/FILES.cfg
@@ -47,7 +47,7 @@ 'buildtype': ['dev', 'official'], }, { - 'filename': 'crashpad_handler', + 'filename': 'chrome_crashpad_handler', 'buildtype': ['dev', 'official'], }, {
diff --git a/chrome/tools/build/linux/FILES.cfg b/chrome/tools/build/linux/FILES.cfg index c621b0d1..3af51ef 100644 --- a/chrome/tools/build/linux/FILES.cfg +++ b/chrome/tools/build/linux/FILES.cfg
@@ -48,7 +48,7 @@ 'buildtype': ['dev', 'official'], }, { - 'filename': 'crashpad_handler', + 'filename': 'chrome_crashpad_handler', 'buildtype': ['dev', 'official'], }, {
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn index 182c0e6..425c72b 100644 --- a/chrome/updater/BUILD.gn +++ b/chrome/updater/BUILD.gn
@@ -87,8 +87,6 @@ "enum_traits.h", "external_constants.cc", "external_constants.h", - "external_constants_builder.cc", - "external_constants_builder.h", "external_constants_default.cc", "external_constants_default.h", "installer.cc", @@ -173,8 +171,8 @@ "launchd_util.cc", "launchd_util.h", "lib_util_mac.mm", - "mac/installer_dmg.h", - "mac/installer_dmg.mm", + "mac/install_from_archive.h", + "mac/install_from_archive.mm", "mac/mac_util.h", "mac/mac_util.mm", "mac/net/network.h", @@ -195,6 +193,7 @@ "prefs_mac.mm", "service_factory_mac.mm", "setup_mac.mm", + "util_mac.mm", ] deps += [ @@ -433,6 +432,8 @@ "device_management/dm_response_validator_unittest.cc", "device_management/dm_storage_unittest.cc", "enum_traits_unittest.cc", + "external_constants_builder.cc", + "external_constants_builder.h", "external_constants_builder_unittest.cc", "external_constants_override_unittest.cc", "lib_util_unittest.cc",
diff --git a/chrome/updater/check_for_updates_task.cc b/chrome/updater/check_for_updates_task.cc index dcf48bd..86b1c7104 100644 --- a/chrome/updater/check_for_updates_task.cc +++ b/chrome/updater/check_for_updates_task.cc
@@ -19,19 +19,59 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "base/time/time.h" #include "base/version.h" +#include "chrome/updater/configurator.h" #include "chrome/updater/constants.h" #include "chrome/updater/persisted_data.h" +#include "chrome/updater/policy/manager.h" +#include "chrome/updater/policy/service.h" #include "chrome/updater/prefs.h" #include "chrome/updater/update_service_impl.h" #include "chrome/updater/util.h" #include "components/prefs/pref_service.h" -#include "components/update_client/configurator.h" #include "components/update_client/update_client.h" namespace updater { +namespace { + +bool ShouldSkipCheck(scoped_refptr<Configurator> config) { + // Skip if periodic updates are disabled altogether. + const int check_delay_seconds = config->NextCheckDelay(); + if (check_delay_seconds == 0) { + VLOG(0) << "Skipping checking for updates: NextCheckDelay is 0."; + return true; + } + + // Skip if the most recent check was too recent (and not in the future). + const base::TimeDelta time_since_update = + base::Time::NowFromSystemTime() - + config->GetPrefService()->GetTime(kPrefUpdateTime); + if (base::TimeDelta() < time_since_update && + time_since_update < base::TimeDelta::FromSeconds(check_delay_seconds)) { + VLOG(0) << "Skipping checking for updates: last update was " + << time_since_update.InMinutes() << " minutes ago."; + return true; + } + + // Skip if the updater is in the update suppression period. + UpdatesSuppressedTimes suppression; + if (config->GetPolicyService()->GetUpdatesSuppressedTimes(nullptr, + &suppression) && + suppression.valid()) { + base::Time::Exploded now; + base::Time::Now().LocalExplode(&now); + if (suppression.contains(now.hour, now.minute)) { + VLOG(0) << "Skipping checking for updates: in update suppression period."; + return true; + } + } + + return false; +} + +} // namespace CheckForUpdatesTask::CheckForUpdatesTask( - scoped_refptr<update_client::Configurator> config, + scoped_refptr<Configurator> config, base::OnceCallback<void(UpdateService::Callback)> update_checker, base::OnceClosure callback) : config_(config), @@ -69,16 +109,8 @@ void CheckForUpdatesTask::MaybeCheckForUpdates() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - const base::Time lastUpdateTime = - config_->GetPrefService()->GetTime(kPrefUpdateTime); - const base::TimeDelta timeSinceUpdate = - base::Time::NowFromSystemTime() - lastUpdateTime; - if (base::TimeDelta() < timeSinceUpdate && - timeSinceUpdate < - base::TimeDelta::FromSeconds(config_->NextCheckDelay())) { - VLOG(0) << "Skipping checking for updates: " - << timeSinceUpdate.InMinutes(); + if (ShouldSkipCheck(config_)) { base::SequencedTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&CheckForUpdatesTask::MaybeCheckForUpdatesDone, this)); @@ -90,8 +122,7 @@ base::BindOnce( std::move(update_checker_), base::BindOnce( - [](base::OnceClosure closure, - scoped_refptr<update_client::Configurator> config, + [](base::OnceClosure closure, scoped_refptr<Configurator> config, UpdateService::Result result) { const int exit_code = static_cast<int>(result); VLOG(0) << "Check for update task complete: exit_code = "
diff --git a/chrome/updater/check_for_updates_task.h b/chrome/updater/check_for_updates_task.h index 0fe8a9a9..2d5fb4e 100644 --- a/chrome/updater/check_for_updates_task.h +++ b/chrome/updater/check_for_updates_task.h
@@ -16,19 +16,19 @@ #include "chrome/updater/update_service.h" namespace update_client { -class Configurator; class UpdateClient; enum class Error; } // namespace update_client namespace updater { +class Configurator; class PersistedData; class CheckForUpdatesTask : public base::RefCountedThreadSafe<CheckForUpdatesTask> { public: CheckForUpdatesTask( - scoped_refptr<update_client::Configurator> config, + scoped_refptr<Configurator> config, base::OnceCallback<void(UpdateService::Callback)> update_checker, base::OnceClosure callback); void Run(); @@ -97,7 +97,7 @@ void UnregisterMissingAppsDone(); SEQUENCE_CHECKER(sequence_checker_); - scoped_refptr<update_client::Configurator> config_; + scoped_refptr<Configurator> config_; base::OnceCallback<void(UpdateService::Callback)> update_checker_; scoped_refptr<updater::PersistedData> persisted_data_; scoped_refptr<update_client::UpdateClient> update_client_;
diff --git a/chrome/updater/configurator.cc b/chrome/updater/configurator.cc index 7d0e0d0e..ffb6d212 100644 --- a/chrome/updater/configurator.cc +++ b/chrome/updater/configurator.cc
@@ -65,7 +65,10 @@ } int Configurator::NextCheckDelay() const { - return 5 * kDelayOneHour; + int minutes = 0; + return policy_service_->GetLastCheckPeriodMinutes(nullptr, &minutes) + ? minutes * kDelayOneMinute + : 5 * kDelayOneHour; } int Configurator::OnDemandDelay() const { @@ -114,7 +117,10 @@ } std::string Configurator::GetDownloadPreference() const { - return {}; + std::string preference; + return policy_service_->GetDownloadPreferenceGroupPolicy(nullptr, &preference) + ? preference + : std::string(); } scoped_refptr<update_client::NetworkFetcherFactory>
diff --git a/chrome/updater/installer_mac.cc b/chrome/updater/installer_mac.cc index ff1ddd2d..9e1ee38 100644 --- a/chrome/updater/installer_mac.cc +++ b/chrome/updater/installer_mac.cc
@@ -9,7 +9,7 @@ #include "base/logging.h" #include "base/strings/strcat.h" #include "chrome/updater/constants.h" -#include "chrome/updater/mac/installer_dmg.h" +#include "chrome/updater/mac/install_from_archive.h" namespace updater { @@ -18,11 +18,11 @@ const std::string& arguments, ProgressCallback /*progress_callback*/) { DVLOG(1) << "Running application install from DMG"; - // InstallFromDMG() returns the exit code of the script. 0 is success and + // InstallFromArchive() returns the exit code of the script. 0 is success and // anything else should be an error. const int exit_code = - InstallFromDMG(app_installer, checker_path_, - base::StrCat({pv_.GetString(), " ", arguments})); + InstallFromArchive(app_installer, checker_path_, + base::StrCat({pv_.GetString(), " ", arguments})); return exit_code == 0 ? Result() : Result(kErrorApplicationInstallerFailed, exit_code);
diff --git a/chrome/updater/mac/install_from_archive.h b/chrome/updater/mac/install_from_archive.h new file mode 100644 index 0000000..bb68c59f --- /dev/null +++ b/chrome/updater/mac/install_from_archive.h
@@ -0,0 +1,52 @@ +// 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_UPDATER_MAC_INSTALL_FROM_ARCHIVE_H_ +#define CHROME_UPDATER_MAC_INSTALL_FROM_ARCHIVE_H_ + +#include <string> + +namespace base { +class FilePath; +} + +namespace updater { + +enum class InstallErrors { + // Failed to mount the DMG. + kFailMountDmg = -1, + + // No mount point was created from the DMG, even though mounting succeeded. + kNoMountPoint = -2, + + // Failed to find the mounted DMG path, even though mounting succeeded and a + // mount point was created. + kMountedDmgPathDoesNotExist = -3, + + // Failed to find a path to the install executable. + kExecutableFilePathDoesNotExist = -4, + + // Executable path does not contain an executable file. + kExecutablePathNotExecutable = -5, + + // Zip file failed to expand. + kFailedToExpandZip = -6, + + // The installer type given by the run command is not valid. + kNotSupportedInstallerType = -7, + + // Correct permissions could not be validated for the install path. + kCouldNotConfirmAppPermissions = -8, +}; + +// Choose which type of archive to install from. Possible types of archives are +// DMG, Zip and just the App. From there, it calls the archive specific +// installation method. +int InstallFromArchive(const base::FilePath& file_path, + const base::FilePath& existence_checker_path, + const std::string& arguments); + +} // namespace updater + +#endif // CHROME_UPDATER_MAC_INSTALL_FROM_ARCHIVE_H_
diff --git a/chrome/updater/mac/install_from_archive.mm b/chrome/updater/mac/install_from_archive.mm new file mode 100644 index 0000000..08e81bd --- /dev/null +++ b/chrome/updater/mac/install_from_archive.mm
@@ -0,0 +1,332 @@ +// 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/updater/mac/install_from_archive.h" + +#import <Cocoa/Cocoa.h> + +#include <string> +#include <vector> + +#include "base/files/file_enumerator.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/mac/scoped_nsobject.h" +#include "base/path_service.h" +#include "base/process/launch.h" +#include "base/strings/strcat.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/strings/sys_string_conversions.h" +#include "chrome/updater/util.h" + +namespace updater { +namespace { + +bool RunHDIUtil(const std::vector<std::string>& args, + std::string* command_output) { + base::FilePath hdiutil_path("/usr/bin/hdiutil"); + if (!base::PathExists(hdiutil_path)) { + VLOG(1) << "hdiutil path (" << hdiutil_path << ") does not exist."; + return false; + } + + base::CommandLine command(hdiutil_path); + for (const auto& arg : args) + command.AppendArg(arg); + + std::string output; + bool result = base::GetAppOutput(command, &output); + if (!result) + VLOG(1) << "hdiutil failed."; + + if (command_output) + *command_output = output; + + return result; +} + +bool MountDMG(const base::FilePath& dmg_path, std::string* mount_point) { + if (!base::PathExists(dmg_path)) { + VLOG(1) << "The DMG file path (" << dmg_path << ") does not exist."; + return false; + } + + std::string command_output; + std::vector<std::string> args{"attach", dmg_path.value(), "-plist", + "-nobrowse", "-readonly"}; + if (!RunHDIUtil(args, &command_output)) { + VLOG(1) << "Mounting DMG (" << dmg_path + << ") failed. Output: " << command_output; + return false; + } + @autoreleasepool { + NSString* output = base::SysUTF8ToNSString(command_output); + NSDictionary* plist = [output propertyList]; + // Look for the mountpoint. + NSArray* system_entities = [plist objectForKey:@"system-entities"]; + NSString* dmg_mount_point = nil; + for (NSDictionary* entry in system_entities) { + NSString* entry_mount_point = entry[@"mount-point"]; + if ([entry_mount_point length]) { + dmg_mount_point = [entry_mount_point stringByStandardizingPath]; + break; + } + } + if (mount_point) + *mount_point = base::SysNSStringToUTF8(dmg_mount_point); + } + return true; +} + +bool UnmountDMG(const base::FilePath& mounted_dmg_path) { + if (!base::PathExists(mounted_dmg_path)) { + VLOG(1) << "The mounted DMG path (" << mounted_dmg_path + << ") does not exist."; + return false; + } + + std::vector<std::string> args{"detach", mounted_dmg_path.value(), "-force"}; + if (!RunHDIUtil(args, nullptr)) { + VLOG(1) << "Unmounting DMG (" << mounted_dmg_path << ") failed."; + return false; + } + return true; +} + +bool IsInstallScriptExecutable(const base::FilePath& script_path) { + int permissions = 0; + if (!base::GetPosixFilePermissions(script_path, &permissions)) + return false; + + constexpr int kExecutableMask = base::FILE_PERMISSION_EXECUTE_BY_USER; + return (permissions & kExecutableMask) == kExecutableMask; +} + +bool ConfirmFilePermissions(const base::FilePath& root_path) { + constexpr int kPermissionsMask = base::FILE_PERMISSION_USER_MASK | + base::FILE_PERMISSION_GROUP_MASK | + base::FILE_PERMISSION_READ_BY_OTHERS | + base::FILE_PERMISSION_EXECUTE_BY_OTHERS; + + base::FileEnumerator file_enumerator( + root_path, false, + base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES | + base::FileEnumerator::SHOW_SYM_LINKS); + + for (base::FilePath path = file_enumerator.Next(); !path.empty(); + path = file_enumerator.Next()) { + if (!SetPosixFilePermissions(path, kPermissionsMask)) { + VLOG(0) << "Couldn't set file permissions for for: " << path.value(); + return false; + } + + base::File::Info file_info; + if (!base::GetFileInfo(path, &file_info)) { + VLOG(0) << "Couldn't get file info for: " << path.value(); + return false; + } + + // If file path is real directory and not a link, recurse into it. + if (file_info.is_directory && !base::IsLink(path)) { + if (!ConfirmFilePermissions(path)) + return false; + } + } + + return true; +} + +int RunExecutable(const base::FilePath& mounted_dmg_path, + const base::FilePath& existence_checker_path, + const base::FilePath::StringPieceType executable_name, + const std::string& arguments) { + if (!base::PathExists(mounted_dmg_path)) { + VLOG(1) << "File path (" << mounted_dmg_path << ") does not exist."; + return static_cast<int>(InstallErrors::kMountedDmgPathDoesNotExist); + } + base::FilePath executable_file_path = + mounted_dmg_path.Append(executable_name); + if (!base::PathExists(executable_file_path)) { + VLOG(1) << "Executable file path (" << executable_file_path + << ") does not exist."; + return static_cast<int>(InstallErrors::kExecutableFilePathDoesNotExist); + } + + if (!IsInstallScriptExecutable(executable_file_path)) { + VLOG(1) << "Executable file path (" << executable_file_path + << ") is not executable"; + return static_cast<int>(InstallErrors::kExecutablePathNotExecutable); + } + + // TODO(crbug.com/1056818): Improve the way we parse args for CommandLine + // object. + base::CommandLine command(executable_file_path); + command.AppendArgPath(mounted_dmg_path); + if (!arguments.empty()) { + base::CommandLine::StringVector argv = + base::SplitString(arguments, base::kWhitespaceASCII, + base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + argv.insert(argv.begin(), existence_checker_path.value()); + argv.insert(argv.begin(), mounted_dmg_path.value()); + argv.insert(argv.begin(), executable_file_path.value()); + command = base::CommandLine(argv); + } + + std::string output; + int exit_code = 0; + base::GetAppOutputWithExitCode(command, &output, &exit_code); + + return exit_code; +} + +base::FilePath AlterFileExtension(const base::FilePath& path, + const std::string& extension) { + return path.RemoveExtension().AddExtension(extension); +} + +void CopyDMGContents(const base::FilePath& dmg_path, + const base::FilePath& destination_path) { + base::FileEnumerator file_enumerator( + dmg_path, false, + base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES); + + for (base::FilePath path = file_enumerator.Next(); !path.empty(); + path = file_enumerator.Next()) { + base::File::Info file_info; + if (!base::GetFileInfo(path, &file_info)) { + VLOG(0) << "Couldn't get file info for: " << path.value(); + continue; + } + + if (base::IsLink(path)) { + VLOG(0) << "File is symbolic link: " << path.value(); + continue; + } + + if (file_info.is_directory) { + if (!base::CopyDirectory(path, destination_path, true)) { + VLOG(0) << "Couldn't copy directory for: " << path.value() << " to " + << destination_path.value(); + continue; + } + } else { + if (!base::CopyFile(path, destination_path.Append(path.BaseName()))) { + VLOG(0) << "Couldn't copy file for: " << path.value() << " to " + << destination_path.value(); + continue; + } + } + } +} + +// Mounts the DMG specified by `dmg_file_path`. The install executable located +// at "/.install" in the mounted volume is executed, and then the DMG is +// un-mounted. Returns an error code if mounting the DMG or executing the +// executable failed. +int InstallFromDMG(const base::FilePath& dmg_file_path, + const base::FilePath& existence_checker_path, + const std::string& arguments) { + std::string mount_point; + if (!MountDMG(dmg_file_path, &mount_point)) + return static_cast<int>(InstallErrors::kFailMountDmg); + + if (mount_point.empty()) { + VLOG(1) << "No mount point."; + return static_cast<int>(InstallErrors::kNoMountPoint); + } + const base::FilePath mounted_dmg_path = base::FilePath(mount_point); + int result = RunExecutable(mounted_dmg_path, existence_checker_path, + ".install", arguments); + + // After running the executable, before unmount, copy the contents of the DMG + // into the cache folder. This will allow for differentials. + CopyDMGContents(mounted_dmg_path, dmg_file_path.DirName()); + + if (!UnmountDMG(mounted_dmg_path)) + VLOG(1) << "Could not unmount the DMG: " << mounted_dmg_path; + + // Delete the DMG from the cached folder after we are done. + if (!base::DeleteFile(dmg_file_path)) { + VPLOG(1) << "Couldn't remove the DMG."; + } + + return result; +} + +// Unzips the zip using the existing unzip utility in Mac. Path to the zip is +// specified by the `zip_file_path`. The install executable located at +// "/.install" in the contents of the zip is executed, and then the zip is +// deleted. Returns an error code if unzipping the archive or executing the +// executable failed. +int InstallFromZip(const base::FilePath& zip_file_path, + const base::FilePath& existence_checker_path, + const std::string& arguments) { + const base::FilePath dest_path = zip_file_path.DirName(); + + if (!UnzipWithExe(zip_file_path, dest_path)) { + VLOG(1) << "Failed to unzip zip file."; + return static_cast<int>(InstallErrors::kFailedToExpandZip); + } + + if (!ConfirmFilePermissions(dest_path)) { + return static_cast<int>(InstallErrors::kCouldNotConfirmAppPermissions); + } + + int result = + RunExecutable(dest_path, existence_checker_path, ".install", arguments); + + // Remove the zip file, keep the expanded. + base::DeleteFile(zip_file_path); + + return result; +} + +// Installs with a path to the app specified by the `app_file_path`. The install +// executable located at "/.install" next to the .app is executed. This function +// is important for the differential installs, as applying the differential +// creates a .app file within the caching folder. +int InstallFromApp(const base::FilePath& app_file_path, + const base::FilePath& existence_checker_path, + const std::string& arguments) { + if (!base::PathExists(app_file_path) || + app_file_path.FinalExtension() != ".app") { + VLOG(1) << "Path to the app does not exist!"; + return static_cast<int>(InstallErrors::kNotSupportedInstallerType); + } + + // Need to make sure that the app at the path being installed has the correect + // permissions. + if (!ConfirmFilePermissions(app_file_path)) { + return static_cast<int>(InstallErrors::kCouldNotConfirmAppPermissions); + } + + int result = RunExecutable(app_file_path.DirName(), existence_checker_path, + ".install", arguments); + + return result; +} +} // namespace + +int InstallFromArchive(const base::FilePath& file_path, + const base::FilePath& existence_checker_path, + const std::string& arguments) { + // Go through all file extensions to see if a path exists. + base::FilePath new_path = AlterFileExtension(file_path, ".dmg"); + if (base::PathExists(new_path)) + return InstallFromDMG(new_path, existence_checker_path, arguments); + + new_path = AlterFileExtension(file_path, ".zip"); + if (base::PathExists(new_path)) + return InstallFromZip(new_path, existence_checker_path, arguments); + + new_path = AlterFileExtension(file_path, ".app"); + if (base::PathExists(new_path)) + return InstallFromApp(new_path, existence_checker_path, arguments); + + VLOG(0) << "Could not find a supported installer to install."; + return static_cast<int>(InstallErrors::kNotSupportedInstallerType); +} +} // namespace updater
diff --git a/chrome/updater/mac/installer_dmg.h b/chrome/updater/mac/installer_dmg.h deleted file mode 100644 index dd7d5db1..0000000 --- a/chrome/updater/mac/installer_dmg.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_UPDATER_MAC_INSTALLER_DMG_H_ -#define CHROME_UPDATER_MAC_INSTALLER_DMG_H_ - -#include <string> - -namespace base { -class FilePath; -} - -namespace updater { - -enum class InstallErrors { - // Failed to mount the DMG. - kFailMountDmg = -1, - - // No mount point was created from the DMG, even though mounting succeeded. - kNoMountPoint = -2, - - // Failed to find the mounted DMG path, even though mounting succeeded and a - // mount point was created. - kMountedDmgPathDoesNotExist = -3, - - // Failed to find a path to the install executable. - kExecutableFilePathDoesNotExist = -4, - - // Executable path does not contain an executable file. - kExecutablePathNotExecutable = -5 -}; - -// Mounts the DMG specified by |dmg_file_path|. The install executable located -// at "/.install" in the mounted volume is executed, and then the DMG is -// un-mounted. Returns an error code if mounting the DMG or executing the -// executable failed. -int InstallFromDMG(const base::FilePath& dmg_file_path, - const base::FilePath& existence_checker_path, - const std::string& arguments); - -} // namespace updater - -#endif // CHROME_UPDATER_MAC_INSTALLER_DMG_H_
diff --git a/chrome/updater/mac/installer_dmg.mm b/chrome/updater/mac/installer_dmg.mm deleted file mode 100644 index 8901971..0000000 --- a/chrome/updater/mac/installer_dmg.mm +++ /dev/null
@@ -1,172 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/updater/mac/installer_dmg.h" - -#import <Cocoa/Cocoa.h> - -#include <vector> - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/logging.h" -#include "base/mac/scoped_nsobject.h" -#include "base/path_service.h" -#include "base/process/launch.h" -#include "base/strings/strcat.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/strings/sys_string_conversions.h" - -namespace updater { - -namespace { - -bool RunHDIUtil(const std::vector<std::string>& args, - std::string* command_output) { - base::FilePath hdiutil_path("/usr/bin/hdiutil"); - if (!base::PathExists(hdiutil_path)) { - DLOG(ERROR) << "hdiutil path (" << hdiutil_path << ") does not exist."; - return false; - } - - base::CommandLine command(hdiutil_path); - for (const auto& arg : args) - command.AppendArg(arg); - - std::string output; - bool result = base::GetAppOutput(command, &output); - if (!result) - DLOG(ERROR) << "hdiutil failed."; - - if (command_output) - *command_output = output; - - return result; -} - -bool MountDMG(const base::FilePath& dmg_path, std::string* mount_point) { - if (!base::PathExists(dmg_path)) { - DLOG(ERROR) << "The DMG file path (" << dmg_path << ") does not exist."; - return false; - } - - std::string command_output; - std::vector<std::string> args{"attach", dmg_path.value(), "-plist", - "-nobrowse", "-readonly"}; - if (!RunHDIUtil(args, &command_output)) { - DLOG(ERROR) << "Mounting DMG (" << dmg_path - << ") failed. Output: " << command_output; - return false; - } - @autoreleasepool { - NSString* output = base::SysUTF8ToNSString(command_output); - NSDictionary* plist = [output propertyList]; - // Look for the mountpoint. - NSArray* system_entities = [plist objectForKey:@"system-entities"]; - NSString* dmg_mount_point = nil; - for (NSDictionary* entry in system_entities) { - NSString* entry_mount_point = entry[@"mount-point"]; - if ([entry_mount_point length]) { - dmg_mount_point = [entry_mount_point stringByStandardizingPath]; - break; - } - } - if (mount_point) - *mount_point = base::SysNSStringToUTF8(dmg_mount_point); - } - return true; -} - -bool UnmountDMG(const base::FilePath& mounted_dmg_path) { - if (!base::PathExists(mounted_dmg_path)) { - DLOG(ERROR) << "The mounted DMG path (" << mounted_dmg_path - << ") does not exist."; - return false; - } - - std::vector<std::string> args{"detach", mounted_dmg_path.value(), "-force"}; - if (!RunHDIUtil(args, nullptr)) { - DLOG(ERROR) << "Unmounting DMG (" << mounted_dmg_path << ") failed."; - return false; - } - return true; -} - -bool IsInstallScriptExecutable(const base::FilePath& script_path) { - int permissions = 0; - if (!base::GetPosixFilePermissions(script_path, &permissions)) - return false; - - constexpr int kExecutableMask = base::FILE_PERMISSION_EXECUTE_BY_USER; - return (permissions & kExecutableMask) == kExecutableMask; -} - -int RunExecutable(const base::FilePath& mounted_dmg_path, - const base::FilePath& existence_checker_path, - const base::FilePath::StringPieceType executable_name, - const std::string& arguments) { - if (!base::PathExists(mounted_dmg_path)) { - DLOG(ERROR) << "File path (" << mounted_dmg_path << ") does not exist."; - return static_cast<int>(InstallErrors::kMountedDmgPathDoesNotExist); - } - base::FilePath executable_file_path = - mounted_dmg_path.Append(executable_name); - if (!base::PathExists(executable_file_path)) { - DLOG(ERROR) << "Executable file path (" << executable_file_path - << ") does not exist."; - return static_cast<int>(InstallErrors::kExecutableFilePathDoesNotExist); - } - - if (!IsInstallScriptExecutable(executable_file_path)) { - DLOG(ERROR) << "Executable file path (" << executable_file_path - << ") is not executable"; - return static_cast<int>(InstallErrors::kExecutablePathNotExecutable); - } - - // TODO(copacitt): Improve the way we parse args for CommandLine object. - // http://crbug.com/1056818 - base::CommandLine command(executable_file_path); - command.AppendArgPath(mounted_dmg_path); - if (!arguments.empty()) { - base::CommandLine::StringVector argv = - base::SplitString(arguments, base::kWhitespaceASCII, - base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - argv.insert(argv.begin(), existence_checker_path.value()); - argv.insert(argv.begin(), mounted_dmg_path.value()); - argv.insert(argv.begin(), executable_file_path.value()); - command = base::CommandLine(argv); - } - - std::string output; - int exit_code = 0; - base::GetAppOutputWithExitCode(command, &output, &exit_code); - - return exit_code; -} - -} // namespace - -int InstallFromDMG(const base::FilePath& dmg_file_path, - const base::FilePath& existence_checker_path, - const std::string& arguments) { - std::string mount_point; - if (!MountDMG(dmg_file_path, &mount_point)) - return static_cast<int>(InstallErrors::kFailMountDmg); - - if (mount_point.empty()) { - DLOG(ERROR) << "No mount point."; - return static_cast<int>(InstallErrors::kNoMountPoint); - } - const base::FilePath mounted_dmg_path = base::FilePath(mount_point); - int result = RunExecutable(mounted_dmg_path, existence_checker_path, - ".install", arguments); - - if (!UnmountDMG(mounted_dmg_path)) - DLOG(WARNING) << "Could not unmount the DMG: " << mounted_dmg_path; - - return result; -} - -} // namespace updater
diff --git a/chrome/updater/mac/setup/setup_unittest.mm b/chrome/updater/mac/setup/setup_unittest.mm index f72e997..11d3c98 100644 --- a/chrome/updater/mac/setup/setup_unittest.mm +++ b/chrome/updater/mac/setup/setup_unittest.mm
@@ -13,7 +13,7 @@ #include "base/strings/sys_string_conversions.h" #include "base/test/task_environment.h" #include "chrome/common/chrome_paths.h" -#include "chrome/updater/mac/installer_dmg.h" +#include "chrome/updater/mac/install_from_archive.h" #include "testing/gtest/include/gtest/gtest.h" namespace updater_setup { @@ -153,25 +153,25 @@ base::FilePath test_dir_; }; -TEST_F(ChromeUpdaterMacSetupTest, InstallFromDMGNoArgs) { +TEST_F(ChromeUpdaterMacSetupTest, InstallFromArchiveNoArgs) { // Get the path of the dmg based on the test directory path and validate it // exists. const base::FilePath dmg_file_path = GetTestDir().Append(FILE_PATH_LITERAL(kUpdaterTestDMGName)); ASSERT_TRUE(base::PathExists(dmg_file_path)); - ASSERT_NE(updater::InstallFromDMG(dmg_file_path, {}, {}), 0); + ASSERT_NE(updater::InstallFromArchive(dmg_file_path, {}, {}), 0); } -TEST_F(ChromeUpdaterMacSetupTest, InstallFromDMGWithArgsFail) { +TEST_F(ChromeUpdaterMacSetupTest, InstallFromArchiveWithArgsFail) { // Get the path of the dmg based on the test directory path and validate it // exists. const base::FilePath dmg_file_path = GetTestDir().Append(FILE_PATH_LITERAL(kUpdaterTestDMGName)); ASSERT_TRUE(base::PathExists(dmg_file_path)); - ASSERT_NE(updater::InstallFromDMG(dmg_file_path, {}, "arg2"), 0); + ASSERT_NE(updater::InstallFromArchive(dmg_file_path, {}, "arg2"), 0); } -TEST_F(ChromeUpdaterMacSetupTest, InstallFromDMGWithArgsPass) { +TEST_F(ChromeUpdaterMacSetupTest, InstallFromArchiveWithArgsPass) { // Get the path of the dmg based on the test directory path and validate it // exists. const base::FilePath dmg_file_path = @@ -182,12 +182,12 @@ GetTestDir().Append(FILE_PATH_LITERAL(kTestAppNameWithExtension)); ASSERT_TRUE(base::PathExists(installed_app_path)); - ASSERT_EQ(updater::InstallFromDMG(dmg_file_path, installed_app_path, - kTestAppVersion), + ASSERT_EQ(updater::InstallFromArchive(dmg_file_path, installed_app_path, + kTestAppVersion), 0); } -TEST_F(ChromeUpdaterMacSetupTest, InstallFromDMGWithExtraneousArgsPass) { +TEST_F(ChromeUpdaterMacSetupTest, InstallFromArchiveWithExtraneousArgsPass) { // Get the path of the dmg based on the test directory path and validate it // exists. const base::FilePath dmg_file_path = @@ -200,8 +200,8 @@ ASSERT_TRUE(base::PathExists(installed_app_path)); std::string args = base::StrCat({kTestAppVersion, " arg1 arg2"}); - ASSERT_EQ(updater::InstallFromDMG(dmg_file_path, installed_app_path, args), - 0); + ASSERT_EQ( + updater::InstallFromArchive(dmg_file_path, installed_app_path, args), 0); } } // namespace updater_setup
diff --git a/chrome/updater/policy/dm_policy_manager.cc b/chrome/updater/policy/dm_policy_manager.cc index c786299..d8787ac 100644 --- a/chrome/updater/policy/dm_policy_manager.cc +++ b/chrome/updater/policy/dm_policy_manager.cc
@@ -84,9 +84,9 @@ !updates_suppressed.has_duration_min()) return false; - suppressed_times->start_hour = updates_suppressed.start_hour(); - suppressed_times->start_minute = updates_suppressed.start_minute(); - suppressed_times->duration_minute = updates_suppressed.duration_min(); + suppressed_times->start_hour_ = updates_suppressed.start_hour(); + suppressed_times->start_minute_ = updates_suppressed.start_minute(); + suppressed_times->duration_minute_ = updates_suppressed.duration_min(); return true; }
diff --git a/chrome/updater/policy/dm_policy_manager_unittest.cc b/chrome/updater/policy/dm_policy_manager_unittest.cc index 4e04e1c..a29dc19f 100644 --- a/chrome/updater/policy/dm_policy_manager_unittest.cc +++ b/chrome/updater/policy/dm_policy_manager_unittest.cc
@@ -192,9 +192,9 @@ UpdatesSuppressedTimes suppressed_times; EXPECT_TRUE(policy_manager->GetUpdatesSuppressedTimes(&suppressed_times)); - EXPECT_EQ(suppressed_times.start_hour, 9); - EXPECT_EQ(suppressed_times.start_minute, 30); - EXPECT_EQ(suppressed_times.duration_minute, 120); + EXPECT_EQ(suppressed_times.start_hour_, 9); + EXPECT_EQ(suppressed_times.start_minute_, 30); + EXPECT_EQ(suppressed_times.duration_minute_, 120); std::string download_preference; EXPECT_TRUE(
diff --git a/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm b/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm index 38e2795..eeb9b10 100644 --- a/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm +++ b/chrome/updater/policy/mac/managed_preference_policy_manager_impl.mm
@@ -117,11 +117,11 @@ [policyDict objectForKey:kDownloadPreferenceKey]); _defaultUpdatePolicy = updater::TranslateUpdatePolicyValue( updater::ReadPolicyInteger(policyDict[kUpdateDefaultKey])); - _updatesSuppressed.start_hour = + _updatesSuppressed.start_hour_ = updater::ReadPolicyInteger(policyDict[kUpdatesSuppressedStartHourKey]); - _updatesSuppressed.start_minute = updater::ReadPolicyInteger( + _updatesSuppressed.start_minute_ = updater::ReadPolicyInteger( policyDict[kUpdatesSuppressedStartMinuteKey]); - _updatesSuppressed.duration_minute = updater::ReadPolicyInteger( + _updatesSuppressed.duration_minute_ = updater::ReadPolicyInteger( policyDict[kUpdatesSuppressedDurationMinuteKey]); } return self;
diff --git a/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm b/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm index 816692a7..1b6771d 100644 --- a/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm +++ b/chrome/updater/policy/mac/managed_preference_policy_manager_impl_unittest.mm
@@ -40,9 +40,9 @@ EXPECT_EQ([policyManager lastCheckPeriodMinutes], kPolicyNotSet); EXPECT_EQ([policyManager defaultUpdatePolicy], kPolicyDisabled); EXPECT_NSEQ([policyManager downloadPreference], @"cacheable"); - EXPECT_EQ([policyManager updatesSuppressed].start_hour, 12); - EXPECT_EQ([policyManager updatesSuppressed].start_minute, 15); - EXPECT_EQ([policyManager updatesSuppressed].duration_minute, 30); + EXPECT_EQ([policyManager updatesSuppressed].start_hour_, 12); + EXPECT_EQ([policyManager updatesSuppressed].start_minute_, 15); + EXPECT_EQ([policyManager updatesSuppressed].duration_minute_, 30); EXPECT_EQ([policyManager proxyMode], nil); EXPECT_EQ([policyManager proxyServer], nil); EXPECT_EQ([policyManager proxyPacURL], nil); @@ -84,9 +84,9 @@ EXPECT_EQ([policyManager lastCheckPeriodMinutes], kPolicyNotSet); EXPECT_EQ([policyManager defaultUpdatePolicy], kPolicyNotSet); EXPECT_NSEQ([policyManager downloadPreference], nil); - EXPECT_EQ([policyManager updatesSuppressed].start_hour, kPolicyNotSet); - EXPECT_EQ([policyManager updatesSuppressed].start_minute, kPolicyNotSet); - EXPECT_EQ([policyManager updatesSuppressed].duration_minute, kPolicyNotSet); + EXPECT_EQ([policyManager updatesSuppressed].start_hour_, kPolicyNotSet); + EXPECT_EQ([policyManager updatesSuppressed].start_minute_, kPolicyNotSet); + EXPECT_EQ([policyManager updatesSuppressed].duration_minute_, kPolicyNotSet); EXPECT_EQ([policyManager proxyMode], nil); EXPECT_EQ([policyManager proxyServer], nil); EXPECT_EQ([policyManager proxyPacURL], nil); @@ -123,9 +123,9 @@ EXPECT_EQ([policyManager lastCheckPeriodMinutes], kPolicyNotSet); EXPECT_EQ([policyManager defaultUpdatePolicy], kPolicyNotSet); EXPECT_EQ([policyManager downloadPreference], nil); - EXPECT_EQ([policyManager updatesSuppressed].start_hour, kPolicyNotSet); - EXPECT_EQ([policyManager updatesSuppressed].start_minute, kPolicyNotSet); - EXPECT_EQ([policyManager updatesSuppressed].duration_minute, kPolicyNotSet); + EXPECT_EQ([policyManager updatesSuppressed].start_hour_, kPolicyNotSet); + EXPECT_EQ([policyManager updatesSuppressed].start_minute_, kPolicyNotSet); + EXPECT_EQ([policyManager updatesSuppressed].duration_minute_, kPolicyNotSet); EXPECT_EQ([policyManager proxyMode], nil); EXPECT_EQ([policyManager proxyServer], nil); EXPECT_EQ([policyManager proxyPacURL], nil);
diff --git a/chrome/updater/policy/manager.cc b/chrome/updater/policy/manager.cc index 34cc1a8b..96dd9b9d 100644 --- a/chrome/updater/policy/manager.cc +++ b/chrome/updater/policy/manager.cc
@@ -4,8 +4,46 @@ #include "chrome/updater/policy/manager.h" +#include "chrome/updater/constants.h" + namespace updater { +UpdatesSuppressedTimes::UpdatesSuppressedTimes() = default; + +UpdatesSuppressedTimes::~UpdatesSuppressedTimes() = default; + +bool UpdatesSuppressedTimes::operator==( + const UpdatesSuppressedTimes& other) const { + return start_hour_ == other.start_hour_ && + start_minute_ == other.start_minute_ && + duration_minute_ == other.duration_minute_; +} + +bool UpdatesSuppressedTimes::operator!=( + const UpdatesSuppressedTimes& other) const { + return !(*this == other); +} + +bool UpdatesSuppressedTimes::valid() const { + return start_hour_ != kPolicyNotSet && start_minute_ != kPolicyNotSet && + duration_minute_ != kPolicyNotSet; +} + +bool UpdatesSuppressedTimes::contains(int hour, int minute) const { + int elapsed_minutes = (hour - start_hour_) * 60 + (minute - start_minute_); + if (elapsed_minutes >= 0 && elapsed_minutes < duration_minute_) { + // The given time is in the suppression period that started today. + // This can be off by up to an hour on the day of a DST transition. + return true; + } + if (elapsed_minutes < 0 && elapsed_minutes + 60 * 24 < duration_minute_) { + // The given time is in the suppression period that started yesterday. + // This can be off by up to an hour on the day after a DST transition. + return true; + } + return false; +} + // TODO: crbug 1070833. // The DefaultPolicyManager is just a stub manager at the moment that returns // |false| or failure for all methods. This policy manager would be in effect
diff --git a/chrome/updater/policy/manager.h b/chrome/updater/policy/manager.h index 686c5d2..da305c1 100644 --- a/chrome/updater/policy/manager.h +++ b/chrome/updater/policy/manager.h
@@ -17,25 +17,23 @@ // For instance, if the start time is 22:00 hours, and with a duration of 8 // hours, the updates will be suppressed for 8 hours regardless of whether // daylight savings time changes happen in between. -struct UpdatesSuppressedTimes { - int start_hour = kPolicyNotSet; - int start_minute = kPolicyNotSet; - int duration_minute = kPolicyNotSet; +class UpdatesSuppressedTimes { + public: + UpdatesSuppressedTimes(); + ~UpdatesSuppressedTimes(); - bool operator==(const UpdatesSuppressedTimes& other) const { - return start_hour == other.start_hour && - start_minute == other.start_minute && - duration_minute == other.duration_minute; - } + bool operator==(const UpdatesSuppressedTimes& other) const; + bool operator!=(const UpdatesSuppressedTimes& other) const; - bool operator!=(const UpdatesSuppressedTimes& other) const { - return !(*this == other); - } + bool valid() const; - bool valid() const { - return start_hour != kPolicyNotSet && start_minute != kPolicyNotSet && - duration_minute != kPolicyNotSet; - } + // Returns true if and only if the `hour`:`minute` wall clock time falls + // within this suppression period. + bool contains(int hour, int minute) const; + + int start_hour_ = kPolicyNotSet; + int start_minute_ = kPolicyNotSet; + int duration_minute_ = kPolicyNotSet; }; // The Policy Manager Interface is implemented by policy managers such as Group
diff --git a/chrome/updater/policy/manager_unittest.cc b/chrome/updater/policy/manager_unittest.cc index 3d4b24d..d8ea05a 100644 --- a/chrome/updater/policy/manager_unittest.cc +++ b/chrome/updater/policy/manager_unittest.cc
@@ -12,4 +12,29 @@ ASSERT_TRUE(policy_manager->IsManaged()); } +TEST(PolicyManager, UpdateSuppressedTimes) { + UpdatesSuppressedTimes suppression; + suppression.start_hour_ = 13; + suppression.start_minute_ = 35; + suppression.duration_minute_ = 22; + ASSERT_FALSE(suppression.contains(12, 45)); + ASSERT_TRUE(suppression.contains(13, 35)); + ASSERT_TRUE(suppression.contains(13, 45)); + ASSERT_TRUE(suppression.contains(13, 55)); + ASSERT_FALSE(suppression.contains(13, 59)); + ASSERT_FALSE(suppression.contains(14, 45)); + + suppression.start_hour_ = 21; + suppression.start_minute_ = 0; + suppression.duration_minute_ = 360; + ASSERT_FALSE(suppression.contains(20, 30)); + ASSERT_TRUE(suppression.contains(21, 30)); + ASSERT_TRUE(suppression.contains(22, 30)); + ASSERT_TRUE(suppression.contains(23, 30)); + ASSERT_TRUE(suppression.contains(0, 30)); + ASSERT_TRUE(suppression.contains(1, 30)); + ASSERT_TRUE(suppression.contains(2, 30)); + ASSERT_FALSE(suppression.contains(3, 30)); +} + } // namespace updater
diff --git a/chrome/updater/policy/service_unittest.cc b/chrome/updater/policy/service_unittest.cc index af2f084..4e78e72 100644 --- a/chrome/updater/policy/service_unittest.cc +++ b/chrome/updater/policy/service_unittest.cc
@@ -166,7 +166,10 @@ PolicyService::PolicyManagerVector managers; auto manager = std::make_unique<FakePolicyManager>(true, "group_policy"); - UpdatesSuppressedTimes updates_suppressed_times = {5, 10, 30}; + UpdatesSuppressedTimes updates_suppressed_times; + updates_suppressed_times.start_hour_ = 5; + updates_suppressed_times.start_minute_ = 10; + updates_suppressed_times.duration_minute_ = 30; manager->SetUpdatesSuppressedTimes(updates_suppressed_times); manager->SetChannel("app1", "channel_gp"); manager->SetUpdatePolicy("app2", 1); @@ -179,7 +182,9 @@ managers.push_back(std::move(manager)); manager = std::make_unique<FakePolicyManager>(true, "imaginary"); - updates_suppressed_times = {1, 1, 20}; + updates_suppressed_times.start_hour_ = 1; + updates_suppressed_times.start_minute_ = 1; + updates_suppressed_times.duration_minute_ = 20; manager->SetUpdatesSuppressedTimes(updates_suppressed_times); manager->SetChannel("app1", "channel_imaginary"); manager->SetUpdatePolicy("app1", 2); @@ -200,9 +205,9 @@ EXPECT_TRUE(suppressed_time_status.conflict_policy()); EXPECT_EQ(suppressed_time_status.effective_policy().value().source, "group_policy"); - EXPECT_EQ(updates_suppressed_times.start_hour, 5); - EXPECT_EQ(updates_suppressed_times.start_minute, 10); - EXPECT_EQ(updates_suppressed_times.duration_minute, 30); + EXPECT_EQ(updates_suppressed_times.start_hour_, 5); + EXPECT_EQ(updates_suppressed_times.start_minute_, 10); + EXPECT_EQ(updates_suppressed_times.duration_minute_, 30); PolicyStatus<std::string> channel_status; std::string channel; @@ -268,14 +273,19 @@ PolicyService::PolicyManagerVector managers; auto manager = std::make_unique<FakePolicyManager>(true, "device_management"); - UpdatesSuppressedTimes updates_suppressed_times = {5, 10, 30}; + UpdatesSuppressedTimes updates_suppressed_times; + updates_suppressed_times.start_hour_ = 5; + updates_suppressed_times.start_minute_ = 10; + updates_suppressed_times.duration_minute_ = 30; manager->SetUpdatesSuppressedTimes(updates_suppressed_times); manager->SetChannel("app1", "channel_dm"); manager->SetUpdatePolicy("app1", 3); managers.push_back(std::move(manager)); manager = std::make_unique<FakePolicyManager>(true, "imaginary"); - updates_suppressed_times = {1, 1, 20}; + updates_suppressed_times.start_hour_ = 1; + updates_suppressed_times.start_minute_ = 1; + updates_suppressed_times.duration_minute_ = 20; manager->SetUpdatesSuppressedTimes(updates_suppressed_times); manager->SetChannel("app1", "channel_imaginary"); manager->SetUpdatePolicy("app1", 2); @@ -286,7 +296,9 @@ managers.push_back(GetPolicyManager()); manager = std::make_unique<FakePolicyManager>(false, "group_policy"); - updates_suppressed_times = {5, 10, 30}; + updates_suppressed_times.start_hour_ = 5; + updates_suppressed_times.start_minute_ = 10; + updates_suppressed_times.duration_minute_ = 30; manager->SetUpdatesSuppressedTimes(updates_suppressed_times); manager->SetChannel("app1", "channel_gp"); manager->SetUpdatePolicy("app2", 1); @@ -302,9 +314,9 @@ EXPECT_TRUE(suppressed_time_status.conflict_policy()); EXPECT_EQ(suppressed_time_status.effective_policy().value().source, "device_management"); - EXPECT_EQ(updates_suppressed_times.start_hour, 5); - EXPECT_EQ(updates_suppressed_times.start_minute, 10); - EXPECT_EQ(updates_suppressed_times.duration_minute, 30); + EXPECT_EQ(updates_suppressed_times.start_hour_, 5); + EXPECT_EQ(updates_suppressed_times.start_minute_, 10); + EXPECT_EQ(updates_suppressed_times.duration_minute_, 30); PolicyStatus<std::string> channel_status; std::string channel;
diff --git a/chrome/updater/policy/win/group_policy_manager.cc b/chrome/updater/policy/win/group_policy_manager.cc index 488ebb3..4c582bb 100644 --- a/chrome/updater/policy/win/group_policy_manager.cc +++ b/chrome/updater/policy/win/group_policy_manager.cc
@@ -95,11 +95,11 @@ bool GroupPolicyManager::GetUpdatesSuppressedTimes( UpdatesSuppressedTimes* suppressed_times) const { return GetIntPolicy(kRegValueUpdatesSuppressedStartHour, - &suppressed_times->start_hour) && + &suppressed_times->start_hour_) && GetIntPolicy(kRegValueUpdatesSuppressedStartMin, - &suppressed_times->start_minute) && + &suppressed_times->start_minute_) && GetIntPolicy(kRegValueUpdatesSuppressedDurationMin, - &suppressed_times->duration_minute); + &suppressed_times->duration_minute_); } bool GroupPolicyManager::GetDownloadPreferenceGroupPolicy(
diff --git a/chrome/updater/policy/win/group_policy_manager_unittest.cc b/chrome/updater/policy/win/group_policy_manager_unittest.cc index be1a314..e12ba54 100644 --- a/chrome/updater/policy/win/group_policy_manager_unittest.cc +++ b/chrome/updater/policy/win/group_policy_manager_unittest.cc
@@ -143,9 +143,9 @@ UpdatesSuppressedTimes suppressed_times = {}; EXPECT_TRUE(policy_manager->GetUpdatesSuppressedTimes(&suppressed_times)); - EXPECT_EQ(suppressed_times.start_hour, 2); - EXPECT_EQ(suppressed_times.start_minute, 30); - EXPECT_EQ(suppressed_times.duration_minute, 500); + EXPECT_EQ(suppressed_times.start_hour_, 2); + EXPECT_EQ(suppressed_times.start_minute_, 30); + EXPECT_EQ(suppressed_times.duration_minute_, 500); std::string download_preference; EXPECT_TRUE(
diff --git a/chrome/updater/util.h b/chrome/updater/util.h index e49767e..f214894 100644 --- a/chrome/updater/util.h +++ b/chrome/updater/util.h
@@ -8,6 +8,7 @@ #include "base/files/file_path.h" #include "base/strings/string_piece.h" #include "base/strings/string_util.h" +#include "build/build_config.h" #include "third_party/abseil-cpp/absl/types/optional.h" class GURL; @@ -86,6 +87,16 @@ const std::string& name, const std::string& value); +#if defined(OS_MAC) +// Uses the builtin unzip utility within macOS /usr/bin/unzip to unzip instead +// of using the configurator's UnzipperFactory. The UnzipperFactory utilizes the +// //third_party/zlib/google, which has a bug that does not preserve the +// permissions when it extracts the contents. For updates via zip or +// differentials, use UnzipWithExe. +bool UnzipWithExe(const base::FilePath& src_path, + const base::FilePath& dest_path); +#endif // defined(OS_MAC) + } // namespace updater #endif // CHROME_UPDATER_UTIL_H_
diff --git a/chrome/updater/util_mac.mm b/chrome/updater/util_mac.mm new file mode 100644 index 0000000..b6d5ef4 --- /dev/null +++ b/chrome/updater/util_mac.mm
@@ -0,0 +1,45 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/updater/util.h" + +#include <string> + +#include "base/command_line.h" +#include "base/files/file_path.h" +#include "base/logging.h" +#include "base/process/launch.h" + +namespace updater { +namespace { +constexpr base::FilePath::CharType kZipExePath[] = + FILE_PATH_LITERAL("/usr/bin/unzip"); +} + +bool UnzipWithExe(const base::FilePath& src_path, + const base::FilePath& dest_path) { + base::FilePath fp(kZipExePath); + base::CommandLine command(fp); + command.AppendArg(src_path.value()); + command.AppendArg("-d"); + command.AppendArg(dest_path.value()); + + std::string output; + int exit_code = 0; + if (!base::GetAppOutputWithExitCode(command, &output, &exit_code)) { + VLOG(0) << "Something went wrong while running the unzipping with " + << kZipExePath; + return false; + } + + // Unzip utility having 0 is success and 1 is a warning. + if (exit_code > 1) { + VLOG(0) << "Output from unzipping: " << output; + VLOG(0) << "Exit code: " << exit_code; + } + + return exit_code <= 1; +} + +} // namespace updater
diff --git a/chromecast/cast_core/BUILD.gn b/chromecast/cast_core/BUILD.gn index 1a506006..61cae5a 100644 --- a/chromecast/cast_core/BUILD.gn +++ b/chromecast/cast_core/BUILD.gn
@@ -123,7 +123,6 @@ cast_source_set("core_runtime") { sources = [ - "cast_core_switches.h", "runtime_application_service.cc", "runtime_application_service.h", "runtime_service.cc", @@ -174,6 +173,7 @@ cast_source_set("browser") { sources = [ + "cast_core_switches.h", "cast_runtime_content_browser_client.cc", "cast_runtime_content_browser_client.h", ] @@ -183,6 +183,7 @@ "//base", "//chromecast/browser", "//chromecast/common:cors_exempt_headers", + "//media", ] if (chromecast_branding == "public") { @@ -277,6 +278,21 @@ } } +executable("demo_platform_service") { + sources = [ + "demo_platform_service.cc", + "demo_platform_service.h", + ] + + public_deps = [ + "//base", + "//third_party/openscreen/src/cast/cast_core/api:cast_core_service_proto", + "//third_party/openscreen/src/cast/cast_core/api:platform_service_proto", + ] + + deps = [ "//third_party/grpc:grpc++" ] +} + # TODO(b/194439829): Upstream additional metrics unit tests. test("cast_cast_core_unittests") { sources = [
diff --git a/chromecast/cast_core/cast_runtime_content_browser_client.cc b/chromecast/cast_core/cast_runtime_content_browser_client.cc index acf26aaa..a8fd925 100644 --- a/chromecast/cast_core/cast_runtime_content_browser_client.cc +++ b/chromecast/cast_core/cast_runtime_content_browser_client.cc
@@ -5,8 +5,11 @@ #include "chromecast/cast_core/cast_runtime_content_browser_client.h" #include "chromecast/browser/service_manager_connection.h" +#include "chromecast/cast_core/cast_core_switches.h" #include "chromecast/cast_core/cast_runtime_service.h" #include "chromecast/common/cors_exempt_headers.h" +#include "media/base/cdm_factory.h" +#include "third_party/blink/public/common/web_preferences/web_preferences.h" namespace chromecast { namespace shell { @@ -56,4 +59,25 @@ pref_service); } +void CastRuntimeContentBrowserClient::OverrideWebkitPrefs( + content::WebContents* web_contents, + blink::web_pref::WebPreferences* web_prefs) { + CastContentBrowserClient::OverrideWebkitPrefs(web_contents, web_prefs); + + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + kAllowRunningInsecureContentInRuntime)) { + // This is needed to unblock MSPs that still use insecure content. For + // example, Amazon Prime uses HTTPS as app URL, but media stream is done + // via HTTP. + LOG(INFO) << "Insecure content is enabled"; + web_prefs->allow_running_insecure_content = true; + } +} + +std::unique_ptr<::media::CdmFactory> +CastRuntimeContentBrowserClient::CreateCdmFactory( + ::media::mojom::FrameInterfaceFactory* frame_interfaces) { + return nullptr; +} + } // namespace chromecast
diff --git a/chromecast/cast_core/cast_runtime_content_browser_client.h b/chromecast/cast_core/cast_runtime_content_browser_client.h index 096127e..b568cf0 100644 --- a/chromecast/cast_core/cast_runtime_content_browser_client.h +++ b/chromecast/cast_core/cast_runtime_content_browser_client.h
@@ -27,6 +27,10 @@ PrefService* pref_service, media::VideoPlaneController* video_plane_controller, CastWindowManager* window_manager) final; + void OverrideWebkitPrefs(content::WebContents* web_contents, + blink::web_pref::WebPreferences* prefs) override; + std::unique_ptr<::media::CdmFactory> CreateCdmFactory( + ::media::mojom::FrameInterfaceFactory* frame_interfaces) override; }; } // namespace chromecast
diff --git a/chromecast/cast_core/demo_platform_service.cc b/chromecast/cast_core/demo_platform_service.cc new file mode 100644 index 0000000..676a4a0 --- /dev/null +++ b/chromecast/cast_core/demo_platform_service.cc
@@ -0,0 +1,213 @@ +// 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 "chromecast/cast_core/demo_platform_service.h" + +#include <stdlib.h> +#include <unistd.h> + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/message_loop/message_pump.h" +#include "base/message_loop/message_pump_type.h" +#include "base/path_service.h" +#include "base/process/launch.h" +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "base/threading/thread_task_runner_handle.h" +#include "third_party/grpc/src/include/grpcpp/channel.h" +#include "third_party/grpc/src/include/grpcpp/create_channel.h" +#include "third_party/grpc/src/include/grpcpp/server.h" +#include "third_party/grpc/src/include/grpcpp/server_builder.h" + +namespace { + +constexpr const char* kCastCoreServiceAddress = "unix:/tmp/cast-core-service"; +constexpr const char* kPlatformServiceAddress = "unix:/tmp/platform-service"; + +} // namespace + +namespace cast { +namespace platform { + +DemoPlatformService::DemoPlatformService(base::FilePath exe_dir) + : sequence_manager_( + base::sequence_manager::CreateSequenceManagerOnCurrentThreadWithPump( + base::MessagePump::Create(base::MessagePumpType::DEFAULT), + base::sequence_manager::SequenceManager::Settings::Builder() + .SetMessagePumpType(base::MessagePumpType::DEFAULT) + .Build())), + task_queue_(sequence_manager_->CreateTaskQueue( + base::sequence_manager::TaskQueue::Spec("platform service tasks"))), + task_runner_(task_queue_->task_runner()), + exe_dir_(exe_dir) { + auto cast_core_channel = grpc::CreateChannel( + kCastCoreServiceAddress, grpc::InsecureChannelCredentials()); + + if (!cast_core_channel) { + LOG(ERROR) << "Failed to connect to cast core grpc channel"; + return; + } + + cast_core_stub_ = + cast::core::CastCoreService::NewStub(std::move(cast_core_channel)); +} + +DemoPlatformService::~DemoPlatformService() = default; + +void DemoPlatformService::RunLoop() { + base::ThreadTaskRunnerHandle thread_handle(task_runner_); + base::RunLoop().Run(); +} + +grpc::Status DemoPlatformService::StartRuntime( + grpc::ServerContext* context, + const StartRuntimeRequest* request, + StartRuntimeResponse* response) { + LOG(INFO) << "StartRuntime"; + int tee_pipe[2]; + if (pipe(tee_pipe) != 0) { + LOG(ERROR) << "Can't create a pipe"; + return grpc::Status::CANCELLED; + } + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&DemoPlatformService::StartRuntimeOnSequence, + base::Unretained(this), tee_pipe[0], tee_pipe[1], + request->runtime_service_info().grpc_endpoint())); + return grpc::Status::OK; +} + +grpc::Status DemoPlatformService::StopRuntime(grpc::ServerContext* context, + const StopRuntimeRequest* request, + StopRuntimeResponse* response) { + LOG(INFO) << "StopRuntime"; + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&DemoPlatformService::StopRuntimeOnSequence, + base::Unretained(this))); + return grpc::Status::OK; +} + +grpc::Status DemoPlatformService::GetDeviceInfo( + grpc::ServerContext* context, + const GetDeviceInfoRequest* request, + GetDeviceInfoResponse* response) { + LOG(INFO) << "GetDeviceInfo"; + return grpc::Status::OK; +} + +void DemoPlatformService::ThreadMain() { + base::PlatformThread::SetName("gRPCThread"); + + if (!cast_core_stub_) { + return; + } + + grpc::ServerBuilder builder; + builder.AddListeningPort(kPlatformServiceAddress, + grpc::InsecureServerCredentials()); + builder.RegisterService(this); + std::unique_ptr<grpc::Server> grpc_server = builder.BuildAndStart(); + + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&DemoPlatformService::RegisterRuntimeOnSequence, + base::Unretained(this))); + + LOG(INFO) << "PlatformService initialized, waiting for start request"; + grpc_server->Wait(); +} + +void DemoPlatformService::RegisterRuntimeOnSequence() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + grpc::ClientContext context; + cast::core::RegisterRuntimeRequest register_request; + cast::common::RuntimeMetadata* metadata = + register_request.mutable_runtime_metadata(); + base::FilePath exe_path = exe_dir_.Append("core_runtime"); + metadata->set_name(exe_path.value()); + metadata->set_type(cast::common::RuntimeType_Type_CAST_WEB); + cast::common::RuntimeCapabilities* runtime_capabilities = + metadata->mutable_runtime_capabilities(); + runtime_capabilities->mutable_media_capabilities()->set_audio_supported(true); + runtime_capabilities->mutable_media_capabilities()->set_video_supported(true); + runtime_capabilities->set_metrics_recorder_supported(true); + + cast::core::RegisterRuntimeResponse register_response; + grpc::Status status = cast_core_stub_->RegisterRuntime( + &context, register_request, ®ister_response); + if (!status.ok()) { + LOG(FATAL) << "Failed to register runtime: " << status.error_message(); + } else { + runtime_id_ = register_response.runtime_id(); + CHECK(!runtime_id_.empty()) << "Core returned an empty runtime ID"; + } +} + +void DemoPlatformService::StartRuntimeOnSequence( + int tee_pipe0, + int tee_pipe1, + const std::string& runtime_service_path) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::LaunchOptions tee_options; + base::LaunchOptions runtime_options; + tee_options.fds_to_remap.emplace_back(tee_pipe0, STDIN_FILENO); + runtime_options.fds_to_remap.emplace_back(tee_pipe1, STDOUT_FILENO); + runtime_options.fds_to_remap.emplace_back(tee_pipe1, STDERR_FILENO); + + base::CommandLine tee_cmdline(base::FilePath("tee")); + const char* log_filename = getenv("DEMO_RUNTIME_LOG"); + if (!log_filename) { + log_filename = "runtime_log.txt"; + } + tee_cmdline.AppendArg(log_filename); + LOG(INFO) << "Logging runtime to file: " << log_filename; + base::LaunchProcess(tee_cmdline, tee_options); + + base::CommandLine runtime_cmdline(exe_dir_.Append("core_runtime")); + runtime_cmdline.AppendSwitch("--no-sandbox"); + runtime_cmdline.AppendSwitch("--no-wifi"); +#if !defined(__arm__) + runtime_cmdline.AppendSwitchASCII("--ozone-platform", "x11"); +#endif + runtime_cmdline.AppendSwitchASCII("--vmodule", "*runtime_*=2"); + runtime_cmdline.AppendSwitchASCII("--cast-core-runtime-id", runtime_id_); + runtime_cmdline.AppendSwitchASCII("--runtime-service-path", + runtime_service_path); + // TODO(btolsch): Maybe support forwarding flags after '--' to the runtime. + runtime_process_ = base::LaunchProcess(runtime_cmdline, runtime_options); + + close(tee_pipe0); + close(tee_pipe1); +} + +void DemoPlatformService::StopRuntimeOnSequence() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + bool terminated = runtime_process_.Terminate(0, true); + LOG_IF(WARNING, !terminated) + << "Unable to terminate runtime process before timeout."; +} + +} // namespace platform +} // namespace cast + +int main(int argc, char** argv) { + base::CommandLine::Init(argc, argv); + logging::LoggingSettings logging_settings; + logging_settings.logging_dest = logging::LOG_TO_STDERR; + logging::InitLogging(logging_settings); + + base::FilePath exe_dir; + if (!base::PathService::Get(base::DIR_EXE, &exe_dir)) { + LOG(ERROR) << "Couldn't get our path for launching the runtime."; + return 1; + } + cast::platform::DemoPlatformService platform_service(exe_dir); + + base::PlatformThreadHandle thread_handle; + base::PlatformThread::Create(0, &platform_service, &thread_handle); + base::PlatformThread::Detach(thread_handle); + platform_service.RunLoop(); + + return 0; +}
diff --git a/chromecast/cast_core/demo_platform_service.h b/chromecast/cast_core/demo_platform_service.h new file mode 100644 index 0000000..d3cb69f --- /dev/null +++ b/chromecast/cast_core/demo_platform_service.h
@@ -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. + +#ifndef CHROMECAST_CAST_CORE_DEMO_PLATFORM_SERVICE_H_ +#define CHROMECAST_CAST_CORE_DEMO_PLATFORM_SERVICE_H_ + +#include <memory> + +#include "base/files/file_path.h" +#include "base/process/process.h" +#include "base/sequence_checker.h" +#include "base/single_thread_task_runner.h" +#include "base/task/sequence_manager/sequence_manager.h" +#include "base/task/sequence_manager/task_queue.h" +#include "base/threading/platform_thread.h" +#include "third_party/openscreen/src/cast/cast_core/api/core/cast_core_service.grpc.pb.h" +#include "third_party/openscreen/src/cast/cast_core/api/platform/platform_service.grpc.pb.h" + +namespace cast { +namespace platform { + +class DemoPlatformService final : public PlatformService::Service, + public base::PlatformThread::Delegate { + public: + explicit DemoPlatformService(base::FilePath exe_dir); + ~DemoPlatformService() override; + + void RunLoop(); + + // PlatformService::Service implementation: + grpc::Status StartRuntime(grpc::ServerContext* context, + const StartRuntimeRequest* request, + StartRuntimeResponse* response) override; + grpc::Status StopRuntime(grpc::ServerContext* context, + const StopRuntimeRequest* request, + StopRuntimeResponse* response) override; + grpc::Status GetDeviceInfo(grpc::ServerContext* context, + const GetDeviceInfoRequest* request, + GetDeviceInfoResponse* response) override; + + private: + void RegisterRuntimeOnSequence(); + void StartRuntimeOnSequence(int tee_pipe0, + int tee_pipe1, + const std::string& runtime_service_path); + void StopRuntimeOnSequence(); + + // base::PlatformThread::Delegate implementation: + void ThreadMain() override; + + std::unique_ptr<base::sequence_manager::SequenceManager> sequence_manager_; + scoped_refptr<base::sequence_manager::TaskQueue> task_queue_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + base::FilePath exe_dir_; + std::unique_ptr<cast::core::CastCoreService::Stub> cast_core_stub_; + std::string runtime_id_; + base::Process runtime_process_; + + SEQUENCE_CHECKER(sequence_checker_); +}; + +} // namespace platform +} // namespace cast + +#endif // CHROMECAST_CAST_CORE_DEMO_PLATFORM_SERVICE_H_
diff --git a/chromecast/net/connectivity_checker_impl.cc b/chromecast/net/connectivity_checker_impl.cc index a5a2002..7b4bfa33 100644 --- a/chromecast/net/connectivity_checker_impl.cc +++ b/chromecast/net/connectivity_checker_impl.cc
@@ -200,12 +200,15 @@ resource_request->url = GURL(*connectivity_check_url_); resource_request->method = "HEAD"; resource_request->priority = net::MAXIMUM_PRIORITY; - // To enable ssl_info in the response. - resource_request->report_raw_headers = true; url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request), MISSING_TRAFFIC_ANNOTATION); + // To enable ssl_info in the response. + url_loader_->SetURLLoaderFactoryOptions( + network::mojom::kURLLoadOptionSendSSLInfoWithResponse | + network::mojom::kURLLoadOptionSendSSLInfoForCertificateError); + // Configure the loader to treat HTTP error status codes as successful loads. // This setting allows us to inspect the status code and log it as an error. url_loader_->SetAllowHttpErrorResults(true);
diff --git a/chromeos/components/personalization_app/resources/common/styles.js b/chromeos/components/personalization_app/resources/common/styles.js index e0621d06..6dfd9621 100644 --- a/chromeos/components/personalization_app/resources/common/styles.js +++ b/chromeos/components/personalization_app/resources/common/styles.js
@@ -92,6 +92,7 @@ outline: none; } .photo-images-container { + background-color: var(--google-grey-300); border-radius: 12px; box-sizing: border-box; display: flex;
diff --git a/chromeos/components/personalization_app/resources/trusted/personalization_router_element.html b/chromeos/components/personalization_app/resources/trusted/personalization_router_element.html index d68d4db..81c9664 100644 --- a/chromeos/components/personalization_app/resources/trusted/personalization_router_element.html +++ b/chromeos/components/personalization_app/resources/trusted/personalization_router_element.html
@@ -42,11 +42,12 @@ </wallpaper-breadcrumb> <wallpaper-selected path=[[path_]] collection-id="[[queryParams_.id]]"> </wallpaper-selected> + <!-- do not use hidden$ here - need to listen on property change in + these elements. --> <wallpaper-collections hidden="[[!shouldShowCollections_(path_)]]"> </wallpaper-collections> <wallpaper-images collection-id="[[queryParams_.id]]" - hidden$="[[!shouldShowCollectionImages_(path_)]]"></wallpaper-images> - <!-- do not use hidden$ here - need to listen on property change in element. --> + hidden="[[!shouldShowCollectionImages_(path_)]]"></wallpaper-images> <local-images hidden="[[!shouldShowLocalCollection_(path_)]]"></local-images> <!-- Prevent the right margin from collapsing when window gets very narrow --> <div id="rightspacer"></div>
diff --git a/chromeos/components/personalization_app/resources/trusted/wallpaper_images_element.js b/chromeos/components/personalization_app/resources/trusted/wallpaper_images_element.js index 32602f40..ba5613a 100644 --- a/chromeos/components/personalization_app/resources/trusted/wallpaper_images_element.js +++ b/chromeos/components/personalization_app/resources/trusted/wallpaper_images_element.js
@@ -12,7 +12,7 @@ import 'chrome://resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js'; import './styles.js'; import {afterNextRender, html} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {sendImages, sendSelectedWallpaperAssetId} from '../common/iframe_api.js'; +import {sendImages, sendSelectedWallpaperAssetId, sendVisible} from '../common/iframe_api.js'; import {isNonEmptyArray, promisifyOnload} from '../common/utils.js'; import {WallpaperType} from './personalization_reducers.js'; import {WithPersonalizationStore} from './personalization_store.js'; @@ -57,6 +57,16 @@ static get properties() { return { /** + * Hidden state of this element. Used to notify iframe of visibility + * changes. + */ + hidden: { + type: Boolean, + reflectToAttribute: true, + observer: 'onHiddenChanged_', + }, + + /** * The current collection id to display. */ collectionId: { @@ -134,6 +144,16 @@ } /** + * Notify iframe that this element visibility has changed. + * @param {boolean} hidden + * @private + */ + async onHiddenChanged_(hidden) { + const iframe = await this.iframePromise_; + sendVisible(/** @type {!Window} */ (iframe.contentWindow), !hidden); + } + + /** * Check if this collection with id |collectionid| is still loading. * @param {?Object<string, boolean>} imagesLoading * @param {?string} collectionId
diff --git a/chromeos/components/personalization_app/resources/untrusted/images_grid.js b/chromeos/components/personalization_app/resources/untrusted/images_grid.js index a9a91547..7104b1e 100644 --- a/chromeos/components/personalization_app/resources/untrusted/images_grid.js +++ b/chromeos/components/personalization_app/resources/untrusted/images_grid.js
@@ -83,6 +83,20 @@ this.selectedAssetId_ = validateReceivedData( message, EventType.SEND_SELECTED_WALLPAPER_ASSET_ID); return; + case EventType.SEND_VISIBLE: + const visible = validateReceivedData(message, EventType.SEND_VISIBLE); + if (!visible) { + // When the iframe is hidden, do some dom magic to hide old image + // content. This is in preparation for a user switching to a new + // wallpaper collection and loading a new set of images. + const ironList = this.shadowRoot.querySelector('iron-list'); + const images = ironList.querySelectorAll('.photo-container img'); + for (const image of images) { + image.src = ''; + } + this.images_ = []; + } + return; default: throw new Error('unexpected event type'); }
diff --git a/chromeos/crosapi/mojom/download_controller.mojom b/chromeos/crosapi/mojom/download_controller.mojom index 2b5e5b3..56b8428 100644 --- a/chromeos/crosapi/mojom/download_controller.mojom +++ b/chromeos/crosapi/mojom/download_controller.mojom
@@ -5,6 +5,7 @@ module crosapi.mojom; import "mojo/public/mojom/base/file_path.mojom"; +import "mojo/public/mojom/base/time.mojom"; // This mirrors `download::DownloadItem::DownloadState`, anything added or // removed here must also be added or removed there. @@ -24,7 +25,7 @@ // non-nullable `field`. This is for backwards compatibility, so that older // clients know when values are present or are absent by default. // -// Next MinVersion: 2 +// Next MinVersion: 3 // Next ID: 13 [Stable, RenamedFrom="crosapi.mojom.DownloadEvent"] struct DownloadItem { @@ -41,12 +42,20 @@ [MinVersion=1] int64 received_bytes@10; [MinVersion=1] bool has_total_bytes@11; [MinVersion=1] int64 total_bytes@12; + [MinVersion=2] mojo_base.mojom.Time? start_time@13; }; // A client implemented in lacros-chrome for the DownloadController which is // implemented in ash-chrome. +// +// Next MinVersion: 2 +// Next ID: 6 [Stable, Uuid="eccf720b-538a-4943-a6fd-d073639c4140"] interface DownloadControllerClient { + // Returns all downloads, no matter the type or state, sorted chronologically + // by start time. This method will ultimately invoke + // `download::SimpleDownloadManager::GetAllDownloads()`. + [MinVersion=1] GetAllDownloads@5() => (array<DownloadItem> downloads); // Pauses the download associated with the specified `download_guid`. This // method will ultimately invoke `download::DownloadItem::Pause()`.
diff --git a/chromeos/services/assistant/public/cpp/assistant_prefs.cc b/chromeos/services/assistant/public/cpp/assistant_prefs.cc index 90fee60..9ddd07d3 100644 --- a/chromeos/services/assistant/public/cpp/assistant_prefs.cc +++ b/chromeos/services/assistant/public/cpp/assistant_prefs.cc
@@ -55,6 +55,10 @@ // A preference that indicates the mode of the Assistant onboarding experience. // This preference should only be changed via policy. const char kAssistantOnboardingMode[] = "settings.assistant.onboarding_mode"; +// A preference that indicates whether Voice Match is enabled during OOBE. +// This preference should only be changed via policy. +const char kAssistantVoiceMatchEnabledDuringOobe[] = + "settings.voice_interaction.oobe_voice_match.enabled"; void RegisterProfilePrefs(PrefRegistrySimple* registry) { registry->RegisterIntegerPref(kAssistantConsentStatus, @@ -66,6 +70,7 @@ registry->RegisterBooleanPref(kAssistantHotwordEnabled, false); registry->RegisterBooleanPref(kAssistantLaunchWithMicOpen, false); registry->RegisterBooleanPref(kAssistantNotificationEnabled, true); + registry->RegisterBooleanPref(kAssistantVoiceMatchEnabledDuringOobe, true); registry->RegisterStringPref(kAssistantOnboardingMode, kAssistantOnboardingModeDefault); }
diff --git a/chromeos/services/assistant/public/cpp/assistant_prefs.h b/chromeos/services/assistant/public/cpp/assistant_prefs.h index 81d7a773..99f130dd 100644 --- a/chromeos/services/assistant/public/cpp/assistant_prefs.h +++ b/chromeos/services/assistant/public/cpp/assistant_prefs.h
@@ -65,6 +65,8 @@ extern const char kAssistantNotificationEnabled[]; COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) extern const char kAssistantOnboardingMode[]; +COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) +extern const char kAssistantVoiceMatchEnabledDuringOobe[]; // Registers Assistant specific profile preferences for browser prefs. COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC)
diff --git a/components/arc/compat_mode/DEPS b/components/arc/compat_mode/DEPS index 812439b2..b9455bf 100644 --- a/components/arc/compat_mode/DEPS +++ b/components/arc/compat_mode/DEPS
@@ -1,8 +1,8 @@ include_rules = [ "+ash/frame/non_client_frame_view_ash.h", + "+ash/public/cpp/style/scoped_light_mode_as_default.h", "+ash/resources/vector_icons", "+ash/shell.h", - "+ash/style/scoped_light_mode_as_default.h", "+chromeos/ui/base/window_properties.h", "+chromeos/ui/frame/caption_buttons/frame_center_button.h", "+chromeos/ui/frame/default_frame_header.h",
diff --git a/components/arc/compat_mode/style/arc_color_provider.cc b/components/arc/compat_mode/style/arc_color_provider.cc index 6ba3a82..7fedfed 100644 --- a/components/arc/compat_mode/style/arc_color_provider.cc +++ b/components/arc/compat_mode/style/arc_color_provider.cc
@@ -5,7 +5,7 @@ #include "components/arc/compat_mode/style/arc_color_provider.h" #include "ash/constants/ash_features.h" -#include "ash/style/scoped_light_mode_as_default.h" +#include "ash/public/cpp/style/scoped_light_mode_as_default.h" namespace arc {
diff --git a/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java b/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java index 1dd4d4d..ce8d8617 100644 --- a/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java +++ b/components/browser_ui/bottomsheet/android/test/java/src/org/chromium/components/browser_ui/bottomsheet/BottomSheetTestSupport.java
@@ -7,6 +7,7 @@ import org.chromium.base.test.util.CallbackHelper; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.SheetState; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController.StateChangeReason; +import org.chromium.content_public.browser.test.util.TestThreadUtils; import java.util.concurrent.TimeoutException; @@ -123,19 +124,55 @@ public static void waitForState(BottomSheetController controller, @SheetState int state) { if (controller.getSheetState() == state) return; CallbackHelper stateChangeHelper = new CallbackHelper(); - BottomSheetObserver observer = new EmptyBottomSheetObserver() { + final BottomSheetObserver observer = new EmptyBottomSheetObserver() { @Override public void onSheetStateChanged(int newState) { if (state == newState) stateChangeHelper.notifyCalled(); } }; - controller.addObserver(observer); + + TestThreadUtils.runOnUiThreadBlocking(() -> controller.addObserver(observer)); + try { stateChangeHelper.waitForFirst(); } catch (TimeoutException ex) { assert false : "Bottom sheet state never changed to " + sheetStateToString(state); } - controller.removeObserver(observer); + + TestThreadUtils.runOnUiThreadBlocking(() -> controller.removeObserver(observer)); + } + + /** + * Wait for the bottom sheet to enter the half or full state. If the sheet is already in either + * state, this method returns immediately. + * @param controller The controller for the bottom sheet. + */ + public static void waitForOpen(BottomSheetController controller) { + if (controller.getSheetState() == BottomSheetController.SheetState.HALF + || controller.getSheetState() == BottomSheetController.SheetState.FULL) { + return; + } + CallbackHelper stateChangeHelper = new CallbackHelper(); + + final BottomSheetObserver observer = new EmptyBottomSheetObserver() { + @Override + public void onSheetStateChanged(int newState) { + if (newState == BottomSheetController.SheetState.HALF + || newState == SheetState.FULL) { + stateChangeHelper.notifyCalled(); + } + } + }; + + TestThreadUtils.runOnUiThreadBlocking(() -> controller.addObserver(observer)); + + try { + stateChangeHelper.waitForFirst(); + } catch (TimeoutException ex) { + assert false : "Bottom sheet state never half or full"; + } + + TestThreadUtils.runOnUiThreadBlocking(() -> controller.removeObserver(observer)); } /**
diff --git a/components/browser_ui/strings/android/browser_ui_strings.grd b/components/browser_ui/strings/android/browser_ui_strings.grd index ffa4d21d..4f1fdb1d6 100644 --- a/components/browser_ui/strings/android/browser_ui_strings.grd +++ b/components/browser_ui/strings/android/browser_ui_strings.grd
@@ -528,10 +528,10 @@ Site settings </message> <message name="IDS_PAGE_INFO_COOKIES_CLEAR" desc="Text on the button to clear cookies for a site."> - Clear cookies + Clear cookies? </message> <message name="IDS_PAGE_INFO_COOKIES_CLEAR_CONFIRMATION" desc="Description of the confirmation dialog when the user clicked 'Clear cookies'."> - Are you sure you want to clear cookies and other site data for this website? + This choice will clear cookies for <ph name="WEBSITE">%1$s<ex>example.com</ex></ph> </message> <message name="IDS_PAGE_INFO_COOKIES_CLEAR_CONFIRMATION_BUTTON" desc="Button in the confirmation dialog when the user clicked 'Clear cookies'."> Clear
diff --git a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_CLEAR.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_CLEAR.png.sha1 index 711a924..18bc6527 100644 --- a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_CLEAR.png.sha1 +++ b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_CLEAR.png.sha1
@@ -1 +1 @@ -0cb81b39f83707f165dbd91808566d46dbb0e2d8 \ No newline at end of file +5a35d68b252bf45d9fa9d7a13c8f112a926aceae \ No newline at end of file
diff --git a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_CLEAR_CONFIRMATION.png.sha1 b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_CLEAR_CONFIRMATION.png.sha1 index db332ba..18bc6527 100644 --- a/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_CLEAR_CONFIRMATION.png.sha1 +++ b/components/browser_ui/strings/android/browser_ui_strings_grd/IDS_PAGE_INFO_COOKIES_CLEAR_CONFIRMATION.png.sha1
@@ -1 +1 @@ -b67be807b56273761fdff65ad91dd8dd99cec9ba \ No newline at end of file +5a35d68b252bf45d9fa9d7a13c8f112a926aceae \ No newline at end of file
diff --git a/components/crash/core/app/BUILD.gn b/components/crash/core/app/BUILD.gn index 6b77473..4396b44 100644 --- a/components/crash/core/app/BUILD.gn +++ b/components/crash/core/app/BUILD.gn
@@ -128,10 +128,6 @@ if (is_ios) { sources += [ "crashpad_ios.mm" ] } - - if (is_linux || is_chromeos) { - data_deps = [ "//third_party/crashpad/crashpad/handler:crashpad_handler" ] - } } if (is_win) { @@ -214,7 +210,7 @@ } } -if (is_mac || is_android) { +if (is_mac || is_android || is_linux || is_chromeos) { # We build a chromium-specific crashpad_handler executable so that we can # define custom UserStreamDataSources. executable("chrome_crashpad_handler") {
diff --git a/components/crash/core/app/crashpad_linux.cc b/components/crash/core/app/crashpad_linux.cc index 5f97c1e..1abde7fa 100644 --- a/components/crash/core/app/crashpad_linux.cc +++ b/components/crash/core/app/crashpad_linux.cc
@@ -115,7 +115,7 @@ if (!base::PathService::Get(base::DIR_EXE, &handler_path)) { return database_path; } - handler_path = handler_path.Append("crashpad_handler"); + handler_path = handler_path.Append("chrome_crashpad_handler"); // When --use-cros-crash-reporter is set (below), the handler passes dumps // to ChromeOS's /sbin/crash_reporter which in turn passes the dump to
diff --git a/components/download/database/BUILD.gn b/components/download/database/BUILD.gn index fae90003..63a6f76 100644 --- a/components/download/database/BUILD.gn +++ b/components/download/database/BUILD.gn
@@ -31,7 +31,8 @@ deps = [ "//base", - "//components/download/database/proto", + "//components/download/database/proto:download_entry_proto", + "//components/download/database/proto:download_source_proto", "//components/leveldb_proto", "//net", "//services/metrics/public/cpp:metrics_cpp", @@ -50,7 +51,8 @@ deps = [ ":database", "//base/test:test_support", - "//components/download/database/proto", + "//components/download/database/proto:download_entry_proto", + "//components/download/database/proto:download_source_proto", "//components/leveldb_proto:test_support", "//content/test:test_support", "//testing/gmock",
diff --git a/components/download/database/DEPS b/components/download/database/DEPS index 4e8777c3..f6afe848 100644 --- a/components/download/database/DEPS +++ b/components/download/database/DEPS
@@ -1,5 +1,6 @@ include_rules = [ "+components/download/public/common", + "+components/enterprise/common/proto", "+components/leveldb_proto", "+services/metrics/public" ]
diff --git a/components/download/database/download_db_conversions.cc b/components/download/database/download_db_conversions.cc index b6019e0..4c8662c5 100644 --- a/components/download/database/download_db_conversions.cc +++ b/components/download/database/download_db_conversions.cc
@@ -218,7 +218,12 @@ in_progress_info.download_schedule.value())); proto.set_allocated_download_schedule(download_schedule_proto.release()); } - + // Fill in the output proto's |reroute_info| iff |in_progress_info|'s + // |reroute_info| is initialized, because it has a required field and parsing + // an uninitialized one to and from serialized strings would fail. + if (in_progress_info.reroute_info.IsInitialized()) { + *proto.mutable_reroute_info() = in_progress_info.reroute_info; + } return proto; } @@ -275,6 +280,9 @@ proto.download_schedule(), !proto.metered() /*only_on_wifi*/); DCHECK_NE(info.download_schedule->only_on_wifi(), info.metered); } + if (proto.has_reroute_info()) { + info.reroute_info = proto.reroute_info(); + } return info; }
diff --git a/components/download/database/download_db_conversions_unittest.cc b/components/download/database/download_db_conversions_unittest.cc index 226f5d8..056cf007 100644 --- a/components/download/database/download_db_conversions_unittest.cc +++ b/components/download/database/download_db_conversions_unittest.cc
@@ -55,6 +55,13 @@ return info; } +InProgressInfo CreateInProgressInfoWithRerouteInfo( + DownloadItemRerouteInfo reroute_info) { + InProgressInfo info = CreateInProgressInfo(); + info.reroute_info = std::move(reroute_info); + return info; +} + DownloadInfo CreateDownloadInfo() { DownloadInfo info; info.guid = "abcdefg"; @@ -160,6 +167,19 @@ EXPECT_EQ(info, InProgressInfoFromProto(InProgressInfoToProto(info))); } +TEST_F(DownloadDBConversionsTest, RerouteInfo) { + DownloadItemRerouteInfo reroute_info; + reroute_info.set_service_provider( + enterprise_connectors::FileSystemServiceProvider::BOX); + reroute_info.mutable_box()->set_file_id("12345"); + + // InProgressInfo with valid fields. + InProgressInfo info = CreateInProgressInfoWithRerouteInfo(reroute_info); + EXPECT_EQ(info, InProgressInfoFromProto(InProgressInfoToProto(info))); + EXPECT_EQ(reroute_info.SerializeAsString(), + info.reroute_info.SerializeAsString()); +} + TEST_F(DownloadDBConversionsTest, UkmInfo) { UkmInfo info(DownloadSource::FROM_RENDERER, 100); EXPECT_EQ(info, UkmInfoFromProto(UkmInfoToProto(info)));
diff --git a/components/download/database/download_db_impl_unittest.cc b/components/download/database/download_db_impl_unittest.cc index 89cdd4d3..4dde367 100644 --- a/components/download/database/download_db_impl_unittest.cc +++ b/components/download/database/download_db_impl_unittest.cc
@@ -179,6 +179,10 @@ in_progress_info.current_path = base::FilePath(FILE_PATH_LITERAL("/tmp.crdownload")); in_progress_info.target_path = base::FilePath(FILE_PATH_LITERAL("/tmp")); + in_progress_info.reroute_info = DownloadItemRerouteInfo(); + in_progress_info.reroute_info.set_service_provider( + enterprise_connectors::BOX); + in_progress_info.reroute_info.mutable_box()->set_file_id("12345"); in_progress_info.url_chain.emplace_back("http://foo"); in_progress_info.url_chain.emplace_back("http://foo2"); first.download_info->in_progress_info = in_progress_info;
diff --git a/components/download/database/in_progress/in_progress_info.cc b/components/download/database/in_progress/in_progress_info.cc index 61a7afb..596b4a9 100644 --- a/components/download/database/in_progress/in_progress_info.cc +++ b/components/download/database/in_progress/in_progress_info.cc
@@ -31,7 +31,8 @@ interrupt_reason == other.interrupt_reason && paused == other.paused && metered == other.metered && bytes_wasted == other.bytes_wasted && auto_resume_count == other.auto_resume_count && - download_schedule == other.download_schedule; + download_schedule == other.download_schedule && + RerouteInfosEqual(reroute_info, other.reroute_info); } } // namespace download
diff --git a/components/download/database/in_progress/in_progress_info.h b/components/download/database/in_progress/in_progress_info.h index fda2de6..42039d35 100644 --- a/components/download/database/in_progress/in_progress_info.h +++ b/components/download/database/in_progress/in_progress_info.h
@@ -10,6 +10,7 @@ #include "components/download/public/common/download_danger_type.h" #include "components/download/public/common/download_item.h" +#include "components/download/public/common/download_item_rename_progress_update.h" #include "components/download/public/common/download_schedule.h" #include "components/download/public/common/download_url_parameters.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -91,6 +92,9 @@ // by their offset. std::vector<DownloadItem::ReceivedSlice> received_slices; + // The download's |reroute_info|. + download::DownloadItemRerouteInfo reroute_info; + // Hash of the downloaded content. std::string hash;
diff --git a/components/download/database/proto/BUILD.gn b/components/download/database/proto/BUILD.gn index 8e2baf93..9abe030 100644 --- a/components/download/database/proto/BUILD.gn +++ b/components/download/database/proto/BUILD.gn
@@ -4,11 +4,17 @@ import("//third_party/protobuf/proto_library.gni") -proto_library("proto") { - visibility = [ "//components/download/database:*" ] +proto_library("download_source_proto") { + proto_in_dir = "//" + sources = [ "download_source.proto" ] +} - sources = [ - "download_entry.proto", - "download_source.proto", +proto_library("download_entry_proto") { + proto_in_dir = "//" + visibility = [ "//components/download/database:*" ] + sources = [ "download_entry.proto" ] + deps = [ + ":download_source_proto", + "//components/enterprise/common:download_item_reroute_info", ] }
diff --git a/components/download/database/proto/download_entry.proto b/components/download/database/proto/download_entry.proto index af788572..b5b99b7 100644 --- a/components/download/database/proto/download_entry.proto +++ b/components/download/database/proto/download_entry.proto
@@ -8,7 +8,10 @@ package download_pb; -import "download_source.proto"; +import "components/download/database/proto/download_source.proto"; + +// For DownloadItemRerouteInfo. +import "components/enterprise/common/proto/download_item_reroute_info.proto"; message HttpRequestHeader { optional string key = 1; @@ -79,6 +82,7 @@ optional int64 bytes_wasted = 26; optional int32 auto_resume_count = 27; optional DownloadSchedule download_schedule = 28; + optional enterprise_connectors.DownloadItemRerouteInfo reroute_info = 29; } // Stores various metadata related to a download. @@ -90,7 +94,7 @@ optional InProgressInfo in_progress_info = 4; } -// database entry for download information. +// In progress database entry for download information. message DownloadDBEntry { // Add field for offline page download. oneof entry { DownloadInfo download_info = 1; }
diff --git a/components/download/internal/common/BUILD.gn b/components/download/internal/common/BUILD.gn index 0c6ef46..02bfc598 100644 --- a/components/download/internal/common/BUILD.gn +++ b/components/download/internal/common/BUILD.gn
@@ -72,7 +72,7 @@ "//base", "//components/download/database", "//components/download/public/common:interfaces", - "//components/enterprise/common/proto:download_item_reroute_info_proto", + "//components/enterprise/common:download_item_reroute_info", "//components/filename_generation", "//components/leveldb_proto", "//components/safe_browsing:buildflags", @@ -171,7 +171,7 @@ "//build:chromeos_buildflags", "//components/download/database", "//components/download/public/common:test_support", - "//components/enterprise/common/proto:download_item_reroute_info_proto", + "//components/enterprise/common:download_item_reroute_info", "//components/leveldb_proto", "//components/leveldb_proto:test_support", "//components/ukm:test_support",
diff --git a/components/download/internal/common/DEPS b/components/download/internal/common/DEPS index b8b2107a..d07f473 100644 --- a/components/download/internal/common/DEPS +++ b/components/download/internal/common/DEPS
@@ -3,7 +3,7 @@ "+components/download/downloader/in_progress", "+components/download/internal/common/jni_headers", "+components/download/public/common", - "+components/enterprise/common/proto", + "+components/enterprise/common/download_item_reroute_info.h", "+components/filename_generation/filename_generation.h", "+components/leveldb_proto", "+components/safe_browsing/buildflags.h",
diff --git a/components/download/internal/common/download_db_cache.cc b/components/download/internal/common/download_db_cache.cc index eeb30cf..51e7269 100644 --- a/components/download/internal/common/download_db_cache.cc +++ b/components/download/internal/common/download_db_cache.cc
@@ -37,6 +37,10 @@ previous_info = previous->download_info->in_progress_info; base::FilePath previous_path = previous_info ? previous_info->current_path : base::FilePath(); + + download::DownloadItemRerouteInfo previous_reroute_info; + if (previous_info) + previous_reroute_info = previous_info->reroute_info; bool previous_paused = previous_info ? previous_info->paused : false; absl::optional<InProgressInfo> current_info; @@ -44,12 +48,14 @@ current_info = current.download_info->in_progress_info; base::FilePath current_path; + download::DownloadItemRerouteInfo reroute_info; bool paused = false; GURL url; DownloadItem::DownloadState state = DownloadItem::DownloadState::IN_PROGRESS; DownloadInterruptReason interrupt_reason = DOWNLOAD_INTERRUPT_REASON_NONE; if (current_info) { - base::FilePath current_path = current_info->current_path; + current_path = current_info->current_path; + reroute_info = current_info->reroute_info; paused = current_info->paused; if (!current_info->url_chain.empty()) url = current_info->url_chain.back(); @@ -60,8 +66,11 @@ // When download path is determined, Chrome should commit the history // immediately. Otherwise the file will be left permanently on the external // storage if Chrome crashes right away. - if (current_path != previous_path || paused != previous_paused) + if (current_path != previous_path || + !RerouteInfosEqual(reroute_info, previous_reroute_info) || + paused != previous_paused) { return ShouldUpdateDownloadDBResult::UPDATE_IMMEDIATELY; + } if (previous.value() == current) return ShouldUpdateDownloadDBResult::NO_UPDATE;
diff --git a/components/download/internal/common/download_db_cache_unittest.cc b/components/download/internal/common/download_db_cache_unittest.cc index 02c3228..f353ad6 100644 --- a/components/download/internal/common/download_db_cache_unittest.cc +++ b/components/download/internal/common/download_db_cache_unittest.cc
@@ -239,6 +239,47 @@ test_path); } +// Test that modifying reroute info will immediately update the DB. +TEST_F(DownloadDBCacheTest, RerouteInfoChange) { + DownloadDBEntry entry = CreateDownloadDBEntry(); + InProgressInfo info; + DownloadItemRerouteInfo test_reroute_info; + info.reroute_info = test_reroute_info; + entry.download_info->in_progress_info = info; + db_entries_.insert( + std::make_pair(GetKey(entry.GetGuid()), + DownloadDBConversions::DownloadDBEntryToProto(entry))); + CreateDBCache(); + std::vector<DownloadDBEntry> loaded_entries; + db_cache_->Initialize(base::BindOnce(&DownloadDBCacheTest::InitCallback, + base::Unretained(this), + &loaded_entries)); + db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); + db_->LoadCallback(true); + ASSERT_EQ(loaded_entries.size(), 1u); + absl::optional<InProgressInfo> loaded_info = + loaded_entries[0].download_info->in_progress_info; + ASSERT_TRUE(RerouteInfosEqual(loaded_info->reroute_info, test_reroute_info)) + << "Expected: " << loaded_info->reroute_info.DebugString() + << "\nActual:" << test_reroute_info.DebugString(); + + test_reroute_info.mutable_box()->set_file_id("12345"); + loaded_info->reroute_info = test_reroute_info; + db_cache_->AddOrReplaceEntry(loaded_entries[0]); + db_->UpdateCallback(true); + + loaded_entries.clear(); + DownloadDB* download_db = GetDownloadDB(); + download_db->LoadEntries(base::BindOnce(&DownloadDBCacheTest::InitCallback, + base::Unretained(this), + &loaded_entries)); + db_->LoadCallback(true); + ASSERT_EQ(loaded_entries.size(), 1u); + ASSERT_TRUE(RerouteInfosEqual(loaded_info->reroute_info, test_reroute_info)) + << "Expected: " << loaded_info->reroute_info.DebugString() + << "\nActual:" << test_reroute_info.DebugString(); +} + TEST_F(DownloadDBCacheTest, RemoveEntry) { PrepopulateSampleEntries(); CreateDBCache();
diff --git a/components/download/internal/common/download_item_impl.cc b/components/download/internal/common/download_item_impl.cc index 937ad745..e7fa367 100644 --- a/components/download/internal/common/download_item_impl.cc +++ b/components/download/internal/common/download_item_impl.cc
@@ -55,7 +55,7 @@ #include "components/download/public/common/download_ukm_helper.h" #include "components/download/public/common/download_url_parameters.h" #include "components/download/public/common/download_utils.h" -#include "components/enterprise/common/proto/download_item_reroute_info.pb.h" +#include "components/enterprise/common/download_item_reroute_info.h" #include "net/base/network_change_notifier.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" @@ -318,6 +318,7 @@ base::Time last_access_time, bool transient, const std::vector<DownloadItem::ReceivedSlice>& received_slices, + const DownloadItemRerouteInfo& reroute_info, absl::optional<DownloadSchedule> download_schedule, std::unique_ptr<DownloadEntry> download_entry) : request_info_(url_chain, @@ -358,7 +359,8 @@ etag_(etag), received_slices_(received_slices), is_updating_observers_(false), - download_schedule_(std::move(download_schedule)) { + download_schedule_(std::move(download_schedule)), + reroute_info_(reroute_info) { delegate_->Attach(); DCHECK(state_ == COMPLETE_INTERNAL || state_ == INTERRUPTED_INTERNAL || state_ == CANCELLED_INTERNAL); @@ -1251,6 +1253,8 @@ " current_path = \"%" PRFilePath "\"\n\t" " target_path = \"%" PRFilePath + "\"\n\t" + " rereoute_info = '%s'" "\"" " referrer = \"%s\"" " site_url = \"%s\"", @@ -1261,7 +1265,8 @@ GetLastModifiedTime().c_str(), GetETag().c_str(), download_file_ ? "true" : "false", url_list.c_str(), GetFullPath().value().c_str(), GetTargetFilePath().value().c_str(), - GetReferrerUrl().spec().c_str(), GetSiteUrl().spec().c_str()); + reroute_info_.DebugString().c_str(), GetReferrerUrl().spec().c_str(), + GetSiteUrl().spec().c_str()); } else { description += base::StringPrintf(" url = \"%s\"", url_list.c_str()); }
diff --git a/components/download/internal/common/download_item_impl_unittest.cc b/components/download/internal/common/download_item_impl_unittest.cc index 6e0ad05..fc0ce4f4 100644 --- a/components/download/internal/common/download_item_impl_unittest.cc +++ b/components/download/internal/common/download_item_impl_unittest.cc
@@ -277,9 +277,10 @@ return download; } - std::unique_ptr<DownloadItemImpl> CreateDownloadItem( + std::unique_ptr<DownloadItemImpl> CreateReroutedDownloadItem( DownloadItem::DownloadState state, - download::DownloadInterruptReason reason) { + download::DownloadInterruptReason reason, + const download::DownloadItemRerouteInfo& reroute_info) { auto item = std::make_unique<download::DownloadItemImpl>( mock_delegate(), kGuid, 10, base::FilePath(), base::FilePath(), std::vector<GURL>(), GURL("http://example.com/a"), @@ -291,11 +292,18 @@ 10, 0, std::string(), state, download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, reason, false, false, false, base::Time::Now(), true, - std::vector<download::DownloadItem::ReceivedSlice>(), + std::vector<download::DownloadItem::ReceivedSlice>(), reroute_info, absl::nullopt /*download_schedule*/, nullptr /* download_entry */); return item; } + std::unique_ptr<DownloadItemImpl> CreateDownloadItem( + DownloadItem::DownloadState state, + download::DownloadInterruptReason reason) { + download::DownloadItemRerouteInfo empty_reroute_info; + return CreateReroutedDownloadItem(state, reason, empty_reroute_info); + } + // Add DownloadFile to DownloadItem. MockDownloadFile* CallDownloadItemStart( DownloadItemImpl* item, @@ -2851,11 +2859,10 @@ TestDownloadItemObserver observer(item); // Invoke the update callback. This should update the target name and stored - // reroute info, regardless of |update_observers|. + // reroute info. base::FilePath file_name(FILE_PATH_LITERAL("foo.txt")); DownloadItemRerouteInfo reroute_info; reroute_info.set_service_provider(RerouteProvider::GOOGLE_DRIVE); - reroute_info.mutable_box()->set_file_id("12345"); update_callback.Run(ProgressUpdate{file_name, reroute_info}); EXPECT_EQ(item->GetFileNameToReportUser(), file_name); @@ -2883,5 +2890,30 @@ rename_handler_ptr->VerifyAndClearExpectations(); } +TEST_F(DownloadItemTest, RerouteInfoLoadedFromDB) { + using RerouteProvider = enterprise_connectors::FileSystemServiceProvider; + DownloadItemRerouteInfo reroute_info; + reroute_info.set_service_provider(RerouteProvider::BOX); + reroute_info.mutable_box()->set_file_id("12345"); + // reroute_info.mutable_box()->set_folder_id("67890"); + ASSERT_TRUE(reroute_info.IsInitialized()); + + std::unique_ptr<DownloadItemImpl> item = CreateReroutedDownloadItem( + DownloadItem::COMPLETE, DOWNLOAD_INTERRUPT_REASON_NONE, reroute_info); + ASSERT_EQ(reroute_info.SerializeAsString(), + item->GetRerouteInfo().SerializeAsString()); + + auto rename_handler = + std::make_unique<MockDownloadItemRenameHandler>(item.get()); + MockDownloadItemRenameHandler* rename_handler_ptr = rename_handler.get(); + + ASSERT_EQ(item.get(), rename_handler->download_item()); + EXPECT_CALL(*mock_delegate(), GetRenameHandlerForDownload(item.get())) + .WillOnce(Return(ByMove(std::move(rename_handler)))); + + ASSERT_TRUE(item->GetRenameHandler()); + rename_handler_ptr->VerifyAndClearExpectations(); +} + } // namespace } // namespace download
diff --git a/components/download/internal/common/download_utils.cc b/components/download/internal/common/download_utils.cc index e53e6c3..fe5303a 100644 --- a/components/download/internal/common/download_utils.cc +++ b/components/download/internal/common/download_utils.cc
@@ -427,6 +427,7 @@ in_progress_info.total_bytes = item.GetTotalBytes(); in_progress_info.current_path = item.GetFullPath(); in_progress_info.target_path = item.GetTargetFilePath(); + in_progress_info.reroute_info = item.GetRerouteInfo(); in_progress_info.received_bytes = item.GetReceivedBytes(); in_progress_info.start_time = item.GetStartTime(); in_progress_info.end_time = item.GetEndTime();
diff --git a/components/download/internal/common/in_progress_download_manager.cc b/components/download/internal/common/in_progress_download_manager.cc index 44b316e..a632b9d 100644 --- a/components/download/internal/common/in_progress_download_manager.cc +++ b/components/download/internal/common/in_progress_download_manager.cc
@@ -70,7 +70,8 @@ in_progress_info->interrupt_reason, in_progress_info->paused, in_progress_info->metered, false, base::Time(), in_progress_info->transient, in_progress_info->received_slices, - in_progress_info->download_schedule, std::move(download_entry)); + in_progress_info->reroute_info, in_progress_info->download_schedule, + std::move(download_entry)); } void OnUrlDownloadHandlerCreated(
diff --git a/components/download/public/common/BUILD.gn b/components/download/public/common/BUILD.gn index 0c01e940..44018d7 100644 --- a/components/download/public/common/BUILD.gn +++ b/components/download/public/common/BUILD.gn
@@ -77,7 +77,7 @@ "//base", "//components/download/network", "//components/download/public/background_service:public", - "//components/enterprise/common/proto:download_item_reroute_info_proto", + "//components/enterprise/common:download_item_reroute_info", "//components/services/quarantine/public/mojom", "//mojo/public/cpp/bindings", "//services/network/public/cpp",
diff --git a/components/download/public/common/DEPS b/components/download/public/common/DEPS index 9462dbe..2ebb3b7 100644 --- a/components/download/public/common/DEPS +++ b/components/download/public/common/DEPS
@@ -2,7 +2,7 @@ "+crypto", "+components/keyed_service/core", "+components/services/quarantine/public/mojom/quarantine.mojom.h", - "+components/enterprise/common/proto", + "+components/enterprise/common/download_item_reroute_info.h", "+mojo/public/cpp/bindings", "+mojo/public/cpp/system", "+net/base/io_buffer.h",
diff --git a/components/download/public/common/download_item.h b/components/download/public/common/download_item.h index 5bde89d6..c717ffe3 100644 --- a/components/download/public/common/download_item.h +++ b/components/download/public/common/download_item.h
@@ -29,6 +29,7 @@ #include "components/download/public/common/download_danger_type.h" #include "components/download/public/common/download_export.h" #include "components/download/public/common/download_interrupt_reasons.h" +#include "components/download/public/common/download_item_rename_progress_update.h" #include "components/download/public/common/download_schedule.h" #include "components/download/public/common/download_source.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -47,14 +48,9 @@ class HttpResponseHeaders; } -namespace enterprise_connectors { -class DownloadItemRerouteInfo; -} - namespace download { class DownloadFile; class DownloadItemRenameHandler; -using enterprise_connectors::DownloadItemRerouteInfo; // One DownloadItem per download. This is the model class that stores all the // state for a download.
diff --git a/components/download/public/common/download_item_factory.h b/components/download/public/common/download_item_factory.h index bd00f9e..d50e2b3f 100644 --- a/components/download/public/common/download_item_factory.h +++ b/components/download/public/common/download_item_factory.h
@@ -64,7 +64,8 @@ bool opened, base::Time last_access_time, bool transient, - const std::vector<DownloadItem::ReceivedSlice>& received_slices) = 0; + const std::vector<DownloadItem::ReceivedSlice>& received_slices, + const download::DownloadItemRerouteInfo& reroute_info) = 0; virtual DownloadItemImpl* CreateActiveItem( DownloadItemImplDelegate* delegate,
diff --git a/components/download/public/common/download_item_impl.h b/components/download/public/common/download_item_impl.h index aa0a039..5a35042 100644 --- a/components/download/public/common/download_item_impl.h +++ b/components/download/public/common/download_item_impl.h
@@ -197,6 +197,7 @@ base::Time last_access_time, bool transient, const std::vector<DownloadItem::ReceivedSlice>& received_slices, + const DownloadItemRerouteInfo& reroute_info, absl::optional<DownloadSchedule> download_schedule, std::unique_ptr<DownloadEntry> download_entry);
diff --git a/components/download/public/common/download_item_rename_progress_update.h b/components/download/public/common/download_item_rename_progress_update.h index 7840bf0..07d85a1 100644 --- a/components/download/public/common/download_item_rename_progress_update.h +++ b/components/download/public/common/download_item_rename_progress_update.h
@@ -6,7 +6,7 @@ #define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_DOWNLOAD_ITEM_RENAME_PROGRESS_UPDATE_H_ #include "base/files/file_path.h" -#include "components/enterprise/common/proto/download_item_reroute_info.pb.h" +#include "components/enterprise/common/download_item_reroute_info.h" namespace download {
diff --git a/components/download/public/common/mock_download_item_impl.cc b/components/download/public/common/mock_download_item_impl.cc index d5d1472..ef565da7 100644 --- a/components/download/public/common/mock_download_item_impl.cc +++ b/components/download/public/common/mock_download_item_impl.cc
@@ -37,6 +37,7 @@ base::Time(), true, DownloadItem::ReceivedSlices(), + DownloadItemRerouteInfo(), absl::nullopt /*download_schedule*/, nullptr /* download_entry */) {}
diff --git a/components/enterprise/common/BUILD.gn b/components/enterprise/common/BUILD.gn index cea78da08..539447a 100644 --- a/components/enterprise/common/BUILD.gn +++ b/components/enterprise/common/BUILD.gn
@@ -8,3 +8,11 @@ "strings.h", ] } + +static_library("download_item_reroute_info") { + sources = [ + "download_item_reroute_info.cc", + "download_item_reroute_info.h", + ] + deps = [ "proto:download_item_reroute_info_proto" ] +}
diff --git a/components/enterprise/common/download_item_reroute_info.cc b/components/enterprise/common/download_item_reroute_info.cc new file mode 100644 index 0000000..e89d6a8 --- /dev/null +++ b/components/enterprise/common/download_item_reroute_info.cc
@@ -0,0 +1,18 @@ +// 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/enterprise/common/download_item_reroute_info.h" + +namespace enterprise_connectors { + +bool RerouteInfosEqual(const DownloadItemRerouteInfo& info, + const DownloadItemRerouteInfo& other) { + return info.GetTypeName() == other.GetTypeName() && + info.IsInitialized() == other.IsInitialized() && + (info.IsInitialized() + ? (info.SerializeAsString() == other.SerializeAsString()) + : true); +} + +} // namespace enterprise_connectors
diff --git a/components/enterprise/common/download_item_reroute_info.h b/components/enterprise/common/download_item_reroute_info.h new file mode 100644 index 0000000..c78a411d --- /dev/null +++ b/components/enterprise/common/download_item_reroute_info.h
@@ -0,0 +1,17 @@ +// 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_ENTERPRISE_COMMON_DOWNLOAD_ITEM_REROUTE_INFO_H_ +#define COMPONENTS_ENTERPRISE_COMMON_DOWNLOAD_ITEM_REROUTE_INFO_H_ + +#include "components/enterprise/common/proto/download_item_reroute_info.pb.h" + +namespace enterprise_connectors { + +bool RerouteInfosEqual(const DownloadItemRerouteInfo& info, + const DownloadItemRerouteInfo& other); + +} // namespace enterprise_connectors + +#endif // COMPONENTS_ENTERPRISE_COMMON_DOWNLOAD_ITEM_REROUTE_INFO_H_
diff --git a/components/feature_engagement/internal/android/tracker_impl_android.cc b/components/feature_engagement/internal/android/tracker_impl_android.cc index 6416a7e..4ff9d193 100644 --- a/components/feature_engagement/internal/android/tracker_impl_android.cc +++ b/components/feature_engagement/internal/android/tracker_impl_android.cc
@@ -6,7 +6,6 @@ #include <memory> #include <utility> -#include <vector> #include "base/android/callback_android.h" #include "base/android/jni_android.h"
diff --git a/components/feature_engagement/internal/availability_model_impl_unittest.cc b/components/feature_engagement/internal/availability_model_impl_unittest.cc index 6610a3cf..143ce3e 100644 --- a/components/feature_engagement/internal/availability_model_impl_unittest.cc +++ b/components/feature_engagement/internal/availability_model_impl_unittest.cc
@@ -6,7 +6,6 @@ #include <memory> #include <utility> -#include <vector> #include "base/bind.h" #include "base/callback.h"
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc index 0fe4468..aa9219e2 100644 --- a/components/history/core/browser/history_backend.cc +++ b/components/history/core/browser/history_backend.cc
@@ -1433,39 +1433,44 @@ // and even returns a similar structure. We should investigate combining the // two, while somehow still avoiding fetching unnecessary fields, such as // `VisitContextAnnotations`. Probably we need to expand `QueryOptions`. - VisitVector visits; + VisitVector visit_rows; // Ignore the return value, as we don't care if we have more visits. - db_->GetVisibleVisitsInRange(options, &visits); - DCHECK_LE(static_cast<int>(visits.size()), options.EffectiveMaxCount()); + db_->GetVisibleVisitsInRange(options, &visit_rows); + DCHECK_LE(static_cast<int>(visit_rows.size()), options.EffectiveMaxCount()); std::vector<AnnotatedVisit> annotated_visits; - for (const auto& visit : visits) { + for (const auto& visit_row : visit_rows) { // Add a result row for this visit, get the URL info from the DB. URLRow url_row; - if (!db_->GetURLRow(visit.url_id, &url_row)) { - DVLOG(0) << "Failed to get id " << visit.url_id << " from history.urls."; + if (!db_->GetURLRow(visit_row.url_id, &url_row)) { + DVLOG(0) << "Failed to get id " << visit_row.url_id + << " from history.urls."; continue; // DB out of sync and URL doesn't exist, try to recover. } VisitContextAnnotations context_annotations; - if (!db_->GetContextAnnotationsForVisit(visit.visit_id, + if (!db_->GetContextAnnotationsForVisit(visit_row.visit_id, &context_annotations)) { - // Redirects don't have context annotations. That's not an execeptional + // Redirects don't have context annotations. That's not an exceptional // case. We just skip these as normal. continue; } - VisitContentAnnotations content_annotations; - // The return value of GetContentAnnotationsForVisit() is not checked for // failures, because the feature flag may be legitimately switched off. // Moreover, some visits may legitimately not have any content annotations. // In those cases, `content_annotations` is left unchanged, and this is // the intended behavior. - db_->GetContentAnnotationsForVisit(visit.visit_id, &content_annotations); + VisitContentAnnotations content_annotations; + db_->GetContentAnnotationsForVisit(visit_row.visit_id, + &content_annotations); - annotated_visits.emplace_back(url_row, visit, context_annotations, - content_annotations); + VisitID referring_visit_of_redirect_chain_start = + GetRedirectChainStart(visit_row).referring_visit; + + annotated_visits.emplace_back(url_row, visit_row, context_annotations, + content_annotations, + referring_visit_of_redirect_chain_start); } return annotated_visits; @@ -1564,7 +1569,11 @@ if (db_->GetRowForVisit(annotated_visit_row.visit_id, &visit_row) && db_->GetURLRow(visit_row.url_id, &url_row)) { annotated_visits.push_back( - {url_row, visit_row, annotated_visit_row.context_annotations, {}}); + {url_row, + visit_row, + annotated_visit_row.context_annotations, + {}, + GetRedirectChainStart(visit_row).referring_visit}); } else { // Ignore corrupt data but do not crash, as user DBs can be in bad states. DVLOG(0) << "HistoryBackend: AnnotatedVisit found with missing associated" @@ -1575,6 +1584,24 @@ return annotated_visits; } +VisitRow HistoryBackend::GetRedirectChainStart(VisitRow visit) { + // Iterate up `visit.referring_visit` while `visit.transition` is a redirect. + if (db_) { + base::flat_set<VisitID> visit_set; + while (!(visit.transition & ui::PAGE_TRANSITION_CHAIN_START)) { + visit_set.insert(visit.visit_id); + // `GetRowForVisit()` should not return false if the DB is correct. + if (!db_->GetRowForVisit(visit.referring_visit, &visit)) + return {}; + if (visit_set.count(visit.visit_id)) { + NOTREACHED() << "Loop in visit redirect chain, giving up"; + break; + } + } + } + return visit; +} + // Observers ------------------------------------------------------------------- void HistoryBackend::AddObserver(HistoryBackendObserver* observer) {
diff --git a/components/history/core/browser/history_backend.h b/components/history/core/browser/history_backend.h index 47f7e8a2..c551c4c 100644 --- a/components/history/core/browser/history_backend.h +++ b/components/history/core/browser/history_backend.h
@@ -443,6 +443,14 @@ std::vector<Cluster> GetClusters(int max_results); + // Finds the 1st visit in the redirect chain containing `visit`. Similar to + // `GetRedirectsToSpecificVisit()`, except 1) only returns the 1st visit of + // the redirect chain instead of the entire chain, and 2) ignores referrals. + // May return an invalid `VisitRow` if there's something wrong with the DB. + // The caller is responsible for identifying, by looking at `visit_id`, and + // handling this case. + VisitRow GetRedirectChainStart(VisitRow visit); + // Observers ----------------------------------------------------------------- void AddObserver(HistoryBackendObserver* observer); @@ -631,8 +639,10 @@ void GetRedirectsFromSpecificVisit(VisitID cur_visit, RedirectList* redirects); - // Similar to the above function except returns a redirect list ending - // at `cur_visit`. + // Similar to the above function except returns a redirect-or-referral list + // ending at `cur_visit`. E.g. if visit A redirected to visit B, which + // referred to visit C, then the return list for visit E would include all 3 + // visits. void GetRedirectsToSpecificVisit(VisitID cur_visit, RedirectList* redirects); // Updates the visit_duration information in visits table.
diff --git a/components/history/core/browser/history_backend_unittest.cc b/components/history/core/browser/history_backend_unittest.cc index 780c2d4d..7620cef 100644 --- a/components/history/core/browser/history_backend_unittest.cc +++ b/components/history/core/browser/history_backend_unittest.cc
@@ -518,10 +518,16 @@ // Returns true if `bitmap_data` is equal to `expected_data`. bool BitmapDataEqual(char expected_data, scoped_refptr<base::RefCountedMemory> bitmap_data) { - return bitmap_data.get() && - bitmap_data->size() == 1u && + return bitmap_data.get() && bitmap_data->size() == 1u && *bitmap_data->front() == expected_data; } + + // Helper to get all annotated visits. + std::vector<AnnotatedVisit> GetAnnotatedVisitRowsFromBackend() { + return backend_ + ->GetRecentClusterIdsAndAnnotatedVisits(base::Time::Min(), 100) + .annotated_visits; + } }; class InMemoryHistoryBackendTest : public HistoryBackendTestBase { @@ -3222,16 +3228,19 @@ EXPECT_EQ(annotated_visits[0].visit_row.visit_id, 3); EXPECT_EQ(annotated_visits[0].visit_row.url_id, 1); EXPECT_EQ(annotated_visits[0].context_annotations.omnibox_url_copied, false); + EXPECT_EQ(annotated_visits[0].referring_visit_of_redirect_chain_start, 0); EXPECT_EQ(annotated_visits[1].url_row.id(), 2); EXPECT_EQ(annotated_visits[1].url_row.url(), "http://2.com/"); EXPECT_EQ(annotated_visits[1].visit_row.visit_id, 2); EXPECT_EQ(annotated_visits[1].visit_row.url_id, 2); EXPECT_EQ(annotated_visits[1].context_annotations.omnibox_url_copied, true); + EXPECT_EQ(annotated_visits[1].referring_visit_of_redirect_chain_start, 0); EXPECT_EQ(annotated_visits[2].url_row.id(), 1); EXPECT_EQ(annotated_visits[2].url_row.url(), "http://1.com/"); EXPECT_EQ(annotated_visits[2].visit_row.visit_id, 1); EXPECT_EQ(annotated_visits[2].visit_row.url_id, 1); EXPECT_EQ(annotated_visits[2].context_annotations.omnibox_url_copied, true); + EXPECT_EQ(annotated_visits[2].referring_visit_of_redirect_chain_start, 0); delete_url(2); delete_visit(3); @@ -3368,4 +3377,79 @@ context_id, navigation_entry_id, url)); } +TEST_F(HistoryBackendTest, GetRedirectChainStart) { + auto last_visit_time = base::Time::Now(); + auto add_visit = [&](std::string url, VisitID referring_visit, + bool is_redirect) { + // Each visit should have a unique `visit_time` to avoid deduping visits to + // the same URL. The exact times don't matter, but we use increasing + // values to make the test cases easy to reason about. + last_visit_time += base::TimeDelta::FromMilliseconds(1); + ui::PageTransition transition = + is_redirect ? ui::PageTransition::PAGE_TRANSITION_IS_REDIRECT_MASK + : ui::PageTransition::PAGE_TRANSITION_CHAIN_START; + auto ids = + backend_->AddPageVisit(GURL(url), last_visit_time, referring_visit, + transition, false, SOURCE_BROWSED, false, false); + backend_->AddContextAnnotationsForVisit(ids.second, {}); + }; + + // Navigate to 'google.com'. + add_visit("google.com", 0, false); + // It redirects to 'https://www.google.com'. + add_visit("https://www.google.com", 1, true); + // Perform a search. + add_visit("https://www.google.com/query=wiki", 2, false); + // Navigate to 'https://www.google.com' in a new tab. + add_visit("https://www.google.com", 0, false); + // Perform a search + add_visit("https://www.google.com/query=wiki2", 4, false); + // Follow a search result link. + add_visit("https://www.wiki2.org", 5, false); + // It redirects. + add_visit("https://www.wiki2.org/home", 6, true); + // Follow a search result in the first tab. + add_visit("https://www.wiki.org", 3, false); + + // The redirect/referral chain now look like this: + // 1 ->> 2 -> 3 -> 8 + // 4 -> 5 -> 6 ->> 7 + // where '->' represents a referral, and '->>' represents a redirect. + + struct Expectation { + VisitID referring_visit; + VisitID first_redirect; + VisitID referring_visit_of_redirect_chain_start; + }; + + std::vector<Expectation> expectations = { + {0, 1, 0}, {1, 1, 0}, {2, 3, 2}, {0, 4, 0}, + {4, 5, 4}, {5, 6, 5}, {6, 6, 5}, {3, 8, 3}, + }; + + auto annotated_visits = GetAnnotatedVisitRowsFromBackend(); + ASSERT_EQ(annotated_visits.size(), expectations.size()); + for (size_t i = 0; i < expectations.size(); ++i) { + VisitID visit_id = i + 1; + const auto& expectation = expectations[i]; + VisitRow visit; + backend_->db_->GetRowForVisit(visit_id, &visit); + EXPECT_EQ(visit.referring_visit, expectation.referring_visit) + << "visit id: " << visit_id; + + // Verify `GetRedirectChainStart()`. + auto first_redirect = backend_->GetRedirectChainStart(visit); + EXPECT_EQ(first_redirect.visit_id, expectation.first_redirect) + << "visit id: " << visit_id; + + // Verify `GetAnnotatedVisits()`. + const auto& annotated_visit = annotated_visits[i]; + EXPECT_EQ(annotated_visit.visit_row.visit_id, visit_id) + << "visit id: " << visit_id; + EXPECT_EQ(annotated_visit.referring_visit_of_redirect_chain_start, + expectation.referring_visit_of_redirect_chain_start) + << "visit id: " << visit_id; + } +} + } // namespace history
diff --git a/components/history/core/browser/history_types.cc b/components/history/core/browser/history_types.cc index b5a7a76..de04010 100644 --- a/components/history/core/browser/history_types.cc +++ b/components/history/core/browser/history_types.cc
@@ -374,11 +374,14 @@ AnnotatedVisit::AnnotatedVisit(URLRow url_row, VisitRow visit_row, VisitContextAnnotations context_annotations, - VisitContentAnnotations content_annotations) + VisitContentAnnotations content_annotations, + VisitID referring_visit_of_redirect_chain_start) : url_row(url_row), visit_row(visit_row), context_annotations(context_annotations), - content_annotations(content_annotations) {} + content_annotations(content_annotations), + referring_visit_of_redirect_chain_start( + referring_visit_of_redirect_chain_start) {} AnnotatedVisit::AnnotatedVisit(const AnnotatedVisit&) = default; AnnotatedVisit& AnnotatedVisit::operator=(const AnnotatedVisit&) = default; AnnotatedVisit::~AnnotatedVisit() = default;
diff --git a/components/history/core/browser/history_types.h b/components/history/core/browser/history_types.h index e55ac2bf..803799d 100644 --- a/components/history/core/browser/history_types.h +++ b/components/history/core/browser/history_types.h
@@ -715,7 +715,8 @@ AnnotatedVisit(URLRow url_row, VisitRow visit_row, VisitContextAnnotations context_annotations, - VisitContentAnnotations content_annotations); + VisitContentAnnotations content_annotations, + VisitID referring_visit_of_redirect_chain_start); AnnotatedVisit(const AnnotatedVisit&); AnnotatedVisit& operator=(const AnnotatedVisit&); ~AnnotatedVisit(); @@ -724,6 +725,13 @@ VisitRow visit_row; VisitContextAnnotations context_annotations; VisitContentAnnotations content_annotations; + // The `VisitRow::referring_visit` of the 1st visit in the redirect chain that + // includes this visit. If this visit is not part of a redirect chain or is + // the 1st visit in a redirect chain, then it will be + // `visit_row.referring_visit`. Using the collapsed referring visit is + // important because redirect visits are omitted from AnnotatedVisits, so + // the uncollapsed referring visit could refer to an omitted visit. + VisitID referring_visit_of_redirect_chain_start = 0; }; // A minimal representation of `AnnotationVisit` used when retrieving them from
diff --git a/components/history/core/browser/visit_database.h b/components/history/core/browser/visit_database.h index c8fd949..137df406 100644 --- a/components/history/core/browser/visit_database.h +++ b/components/history/core/browser/visit_database.h
@@ -158,7 +158,8 @@ GURL* to_url); // Similar to the above function except finds a redirect going to a given - // `to_visit`. + // `to_visit`; or, if there is no such redirect, finds the referral going to + // the given `to_visit`. bool GetRedirectToVisit(VisitID to_visit, VisitID* from_visit, GURL* from_url);
diff --git a/components/history_clusters/core/clustering_backend.h b/components/history_clusters/core/clustering_backend.h index bbd0cc8f..4fd3f3d 100644 --- a/components/history_clusters/core/clustering_backend.h +++ b/components/history_clusters/core/clustering_backend.h
@@ -29,4 +29,4 @@ } // namespace history_clusters -#endif // COMPONENTS_HISTORY_CLUSTERS_CORE_MEMORIES_REMOTE_MODEL_HELPER_H_ +#endif // COMPONENTS_HISTORY_CLUSTERS_CORE_CLUSTERING_BACKEND_H_
diff --git a/components/history_clusters/core/history_clusters_service.cc b/components/history_clusters/core/history_clusters_service.cc index 8bfd6793..0bdef2b 100644 --- a/components/history_clusters/core/history_clusters_service.cc +++ b/components/history_clusters/core/history_clusters_service.cc
@@ -21,7 +21,6 @@ #include "components/history/core/browser/history_backend.h" #include "components/history/core/browser/history_database.h" #include "components/history/core/browser/history_db_task.h" -#include "components/history/core/browser/history_types.h" #include "components/history_clusters/core/history_clusters_buildflags.h" #include "components/history_clusters/core/memories_features.h" #include "components/history_clusters/core/remote_clustering_backend.h" @@ -36,16 +35,27 @@ namespace { -// Gets persisted `AnnotatedVisit`s to cluster. +// Gets persisted `AnnotatedVisit`s to cluster including both persisted visits +// from the history DB and incomplete visits. +// - We don't want incomplete visits to be mysteriously missing from the +// Clusters UI. They haven't recorded the page end metrics yet, but that's +// fine. +// - The history backend will return persisted visits with already computed +// `referring_visit_of_redirect_chain_start`, while incomplete visits will have +// to invoke `GetRedirectChainStart()`. class GetAnnotatedVisitsToCluster : public history::HistoryDBTask { public: using Callback = base::OnceCallback<void(std::vector<history::AnnotatedVisit>, base::Time)>; - GetAnnotatedVisitsToCluster(base::Time end_time, - size_t max_count, - Callback callback) - : callback_(std::move(callback)) { + GetAnnotatedVisitsToCluster( + HistoryClustersService::IncompleteVisitMap incomplete_visit_map, + base::Time end_time, + size_t max_count, + Callback callback) + : incomplete_visit_map_(incomplete_visit_map), + original_end_time_(end_time), + callback_(std::move(callback)) { // As a primitive heuristic, fetch 3x the amount of visits as requested // clusters. We don't know in advance how big the clusters will be. max_count_ = max_count > 0 ? max_count * 3 : kMaxVisitsToCluster.Get(); @@ -90,6 +100,51 @@ options_.begin_time = options_.end_time - base::TimeDelta::FromDays(1); } while (!exhausted_history_ && annotated_visits_.size() < max_count_); + // Now we have enough visits for clustering, add all incomplete visits + // between the current `options.begin_time` and `original_end_time`, as + // otherwise they will be mysteriously missing from the Clusters UI. They + // haven't recorded the page end metrics yet, but that's fine. Filter + // incomplete visits to those that have a `url_row`, have a `visit_row`, and + // match `options`. + for (const auto& item : incomplete_visit_map_) { + auto& incomplete_visit_context_annotations = item.second; + // Discard incomplete visits that don't have a `url_row` and `visit_row`. + // It's possible that the `url_row` and `visit_row` will be available + // before they're needed (i.e. before + // `GetAnnotatedVisitsToCluster::RunOnDBThread()`). But since it'll only + // have a copy of the incomplete context annotations, the copy won't have + // the fields updated. A weak ptr won't help since it can't be accessed on + // different threads. A `scoped_refptr` could work. However, only very + // recently opened tabs won't have the rows set, so we don't bother using + // `scoped_refptr`s. + if (!incomplete_visit_context_annotations.status.history_rows) + continue; + + // Discard incomplete visits outside the time bounds. `begin_time` is + // inclusive, and `end_time` is exclusive. + const auto& visit_time = + incomplete_visit_context_annotations.visit_row.visit_time; + if ((!options_.begin_time.is_null() && + visit_time < options_.begin_time) || + (!original_end_time_.is_null() && visit_time >= original_end_time_)) { + continue; + } + + // Compute `referring_visit_of_redirect_chain_start` for each incomplete + // visit. + const auto& first_redirect = backend->GetRedirectChainStart( + incomplete_visit_context_annotations.visit_row); + + annotated_visits_.push_back({ + incomplete_visit_context_annotations.url_row, + incomplete_visit_context_annotations.visit_row, + incomplete_visit_context_annotations.context_annotations, + // TODO(tommycli): Add content annotations. + {}, + first_redirect.referring_visit, + }); + } + return true; } @@ -105,6 +160,14 @@ } private: + // Incomplete visits that have history rows and are withing the time frame of + // the completed visits fetched will be appended to the annotated visits + // returned for clustering. It's used in the DB thread as each filtered visit + // will need to fetch its `referring_visit_of_redirect_chain_start`. + HistoryClustersService::IncompleteVisitMap incomplete_visit_map_; + // The end time used in the initial history request for completed visits. Used + // in the DB thread to filter `incomplete_visit_map_`. + base::Time original_end_time_; // Set to true if all annotated visits were fetched. It's set in the DB thread // and used in the main thread to determine `continuation_end_time`. bool exhausted_history_{false}; @@ -122,52 +185,6 @@ Callback callback_; }; -// Filter and transform the map of `IncompleteVisitContextAnnotations` to a -// vector of `AnnotatedVisit`. -std::vector<history::AnnotatedVisit> GetIncompleteAnnotatedVisits( - HistoryClustersService::IncompleteVisitMap incomplete_visit_map, - base::Time begin_time, - base::Time end_time) { - // Filter incomplete visits to those that have a `url_row`, have a - // `visit_row`, and match `options`. - std::vector<history::AnnotatedVisit> annotated_visits; - for (const auto& item : incomplete_visit_map) { - auto& incomplete_visit_context_annotations = item.second; - // Discard incomplete visits that don't have a `url_row` and `visit_row`. - // It's possible that the `url_row` and `visit_row` will be available - // before they're needed (i.e. before - // `GetAnnotatedVisitsToCluster::RunOnDBThread()`). But since it'll only - // have a copy of the incomplete context annotations, the copy won't have - // the fields updated. A weak ptr won't help since it can't be accessed on - // different threads. A `scoped_refptr` could work. However, only very - // recently opened tabs won't have the rows set, so we don't bother using - // `scoped_refptr`s. - if (!incomplete_visit_context_annotations.status.history_rows) - continue; - - // Discard incomplete visits outside the time bounds. `begin_time` is - // inclusive, and `end_time` is exclusive. - // TODO(manukh): `end_time` is intended for the WebUI pagination and should - // not affect which visits are clustered. Once we have a feature param to - // toggle on-the-fly clustering, we should move the `end_time` check to - // `GetClusters()` when using persisted clusters. - const auto& visit_time = - incomplete_visit_context_annotations.visit_row.visit_time; - if ((!begin_time.is_null() && visit_time < begin_time) || - (!end_time.is_null() && visit_time >= end_time)) { - continue; - } - - annotated_visits.push_back( - {incomplete_visit_context_annotations.url_row, - incomplete_visit_context_annotations.visit_row, - incomplete_visit_context_annotations.context_annotations, - // TODO(tommycli): Add content annotations. - {}}); - } - return annotated_visits; -} - // Filter `clusters` matching `query`. There are additional filters (e.g. // `max_time`) used when requesting `QueryClusters()`, but this function is only // responsible for matching `query`. @@ -364,6 +381,13 @@ DCHECK(history_service_); + size_t max_visit_count = kMaxVisitsToCluster.Get(); + if (max_count > 0) { + // As a primitive heuristic, fetch 3x the amount of visits as requested + // clusters. We don't know in advance how big the clusters will be. + max_visit_count = max_count * 3; + } + NotifyDebugMessage("Starting History Query:"); NotifyDebugMessage(" end_time = " + (end_time.is_null() ? "null" @@ -372,10 +396,10 @@ history_service_->ScheduleDBTask( FROM_HERE, std::make_unique<GetAnnotatedVisitsToCluster>( - end_time, max_count, + incomplete_visit_context_annotations_, end_time, max_visit_count, base::BindOnce(&HistoryClustersService::OnGotHistoryVisits, weak_ptr_factory_.GetWeakPtr(), query, - /*original_end_time=*/end_time, std::move(callback))), + std::move(callback))), task_tracker); } @@ -438,7 +462,6 @@ void HistoryClustersService::OnGotHistoryVisits( const std::string& query, - base::Time original_end_time, QueryClustersCallback callback, std::vector<history::AnnotatedVisit> annotated_visits, base::Time continuation_end_time) const { @@ -449,15 +472,6 @@ (continuation_end_time.is_null() ? "null (i.e. exhausted history)" : base::TimeToISO8601(continuation_end_time))); - - // Now we have enough visits for clustering, add all incomplete visits between - // the current `options.begin_time` and `original_end_time`, as otherwise they - // will be mysteriously missing from the Clusters UI. They haven't recorded - // the page end metrics yet, but that's fine. - auto filtered_incomplete_visits = - GetIncompleteAnnotatedVisits(incomplete_visit_context_annotations_, - continuation_end_time, original_end_time); - NotifyDebugMessage("Calling backend_->GetClusters()"); backend_->GetClusters( base::BindOnce(&HistoryClustersService::OnGotClusters,
diff --git a/components/history_clusters/core/history_clusters_service.h b/components/history_clusters/core/history_clusters_service.h index 96abe26b..3686b70 100644 --- a/components/history_clusters/core/history_clusters_service.h +++ b/components/history_clusters/core/history_clusters_service.h
@@ -122,7 +122,6 @@ // Internally used callback for `QueryClusters()`. void OnGotHistoryVisits(const std::string& query, - base::Time original_end_time, QueryClustersCallback callback, std::vector<history::AnnotatedVisit> annotated_visits, base::Time continuation_end_time) const;
diff --git a/components/history_clusters/core/history_clusters_service_unittest.cc b/components/history_clusters/core/history_clusters_service_unittest.cc index 3201123..11f0e27 100644 --- a/components/history_clusters/core/history_clusters_service_unittest.cc +++ b/components/history_clusters/core/history_clusters_service_unittest.cc
@@ -50,7 +50,7 @@ std::move(callback_).Run(clusters); } - const std::vector<history::AnnotatedVisit>& last_clustered_visits() const { + const std::vector<history::AnnotatedVisit>& LastClusteredVisits() const { return last_clustered_visits_; } @@ -67,6 +67,7 @@ return history::ScoredAnnotatedVisit(); } + // Should be invoked before `GetClusters()` is invoked. void WaitForGetClustersCall() { base::RunLoop loop; wait_for_get_clusters_closure_ = loop.QuitClosure(); @@ -94,6 +95,7 @@ history::CreateHistoryService(history_dir_.GetPath(), true); history_clusters_service_ = std::make_unique<HistoryClustersService>( history_service_.get(), nullptr); + history_clusters_service_test_api_ = std::make_unique<HistoryClustersServiceTestApi>( history_clusters_service_.get(), history_service_.get()); @@ -107,6 +109,8 @@ HistoryClustersServiceTest& operator=(const HistoryClustersServiceTest&) = delete; + // Add hardcoded completed visits with context annotations to the history + // database. void AddHardcodedTestDataToHistoryService() { history::ContextID context_id = reinterpret_cast<history::ContextID>(1); @@ -139,12 +143,30 @@ } } + // Add an incomplete visit context annotations to the in memory incomplete + // visit map. Does not touch the history database. + void AddIncompleteVisit(history::URLID url_id, + history::VisitID visit_id, + base::Time visit_time) { + // It's not possible to have an incomplete visit with URL or visit set but + // not the other. The IDs must either both be 0 or both be non-zero. + ASSERT_FALSE(url_id ^ visit_id); + auto& incomplete_visit_context_annotations = + history_clusters_service_->GetOrCreateIncompleteVisitContextAnnotations( + next_navigation_id_); + incomplete_visit_context_annotations.url_row.set_id(url_id); + incomplete_visit_context_annotations.visit_row.visit_id = visit_id; + incomplete_visit_context_annotations.visit_row.visit_time = visit_time; + incomplete_visit_context_annotations.status.history_rows = url_id; + next_navigation_id_++; + } + // Verifies that the hardcoded visits were passed to the clustering backend. void AwaitAndVerifyTestClusteringBackendRequest() { test_clustering_backend_->WaitForGetClustersCall(); std::vector<history::AnnotatedVisit> visits = - test_clustering_backend_->last_clustered_visits(); + test_clustering_backend_->LastClusteredVisits(); ASSERT_EQ(visits.size(), 2u); auto& visit = visits[0]; EXPECT_EQ(visit.visit_row.visit_id, 2); @@ -251,6 +273,41 @@ history::BlockUntilHistoryProcessesPendingRequests(history_service_.get()); } +TEST_F(HistoryClustersServiceTest, QueryClustersIncompleteAndPersistedVisits) { + // Create persisted visits 1 and 2. + AddHardcodedTestDataToHistoryService(); + + auto days_ago = [](int days) { + return base::Time::Now() - base::TimeDelta::FromDays(days); + }; + + // Create incomplete visits; only 3 & 4 should be returned by the query. + AddIncompleteVisit(3, 3, days_ago(1)); + AddIncompleteVisit(0, 0, days_ago(1)); // Missing history rows. + AddIncompleteVisit(4, 4, days_ago(90)); + AddIncompleteVisit(5, 5, days_ago(0)); // Too recent. + AddIncompleteVisit(6, 6, days_ago(93)); // Too old. + + history_clusters_service_->QueryClusters( + /*query=*/"", /*end_time=*/base::Time::Now(), /* max_count=*/0, + base::DoNothing(), // Only need to verify the correct request is sent. + &task_tracker_); + + test_clustering_backend_->WaitForGetClustersCall(); + history::BlockUntilHistoryProcessesPendingRequests(history_service_.get()); + + // Persisted visits are ordered before incomplete visits. Persisted visits are + // ordered newest first. Incomplete visits are ordered the same as they were + // sent to the `HistoryClustersService`. + std::vector<history::AnnotatedVisit> visits = + test_clustering_backend_->LastClusteredVisits(); + ASSERT_EQ(visits.size(), 4u); + EXPECT_EQ(visits[0].visit_row.visit_id, 2); + EXPECT_EQ(visits[1].visit_row.visit_id, 1); + EXPECT_EQ(visits[2].visit_row.visit_id, 3); + EXPECT_EQ(visits[3].visit_row.visit_id, 4); +} + TEST_F(HistoryClustersServiceTest, QueryClustersVariousQueries) { AddHardcodedTestDataToHistoryService();
diff --git a/components/history_clusters/core/remote_clustering_backend.cc b/components/history_clusters/core/remote_clustering_backend.cc index 904b44b..3c9d21f 100644 --- a/components/history_clusters/core/remote_clustering_backend.cc +++ b/components/history_clusters/core/remote_clustering_backend.cc
@@ -49,7 +49,8 @@ visit.context_annotations.page_end_reason); request_visit->set_page_transition( static_cast<int>(visit.visit_row.transition)); - request_visit->set_referring_visit_id(visit.visit_row.referring_visit); + request_visit->set_referring_visit_id( + visit.referring_visit_of_redirect_chain_start); if (debug_logger) { base::DictionaryValue debug_visit;
diff --git a/components/lens/lens_features.cc b/components/lens/lens_features.cc index 0429f9b..8f4c517 100644 --- a/components/lens/lens_features.cc +++ b/components/lens/lens_features.cc
@@ -25,6 +25,12 @@ const base::FeatureParam<bool> kRegionSearchUseMenuItemAltText3{ &kLensRegionSearch, "use-menu-item-alt-text-3", false}; +const base::FeatureParam<bool> kEnableUKMLoggingForRegionSearch{ + &kLensRegionSearch, "enable-ukm-logging", false}; + +const base::FeatureParam<bool> kEnableUKMLoggingForImageSearch{ + &kLensStandalone, "enable-ukm-logging", false}; + constexpr base::FeatureParam<int> kMaxPixelsForRegionSearch{ &kLensRegionSearch, "dimensions-max-pixels", 1000}; @@ -40,6 +46,14 @@ constexpr base::FeatureParam<std::string> kHomepageURLForRegionSearch{ &kLensRegionSearch, "lens-homepage-url", "https://lens.google.com/"}; +bool GetEnableUKMLoggingForRegionSearch() { + return kEnableUKMLoggingForRegionSearch.Get(); +} + +bool GetEnableUKMLoggingForImageSearch() { + return kEnableUKMLoggingForImageSearch.Get(); +} + int GetMaxPixelsForRegionSearch() { return kMaxPixelsForRegionSearch.Get(); }
diff --git a/components/lens/lens_features.h b/components/lens/lens_features.h index c895112..43cfa393 100644 --- a/components/lens/lens_features.h +++ b/components/lens/lens_features.h
@@ -27,6 +27,18 @@ // Enables alternate option 3 for the Region Search context menu item text. extern const base::FeatureParam<bool> kRegionSearchUseMenuItemAltText3; +// Enables UKM logging for the Lens Region Search feature. +extern const base::FeatureParam<bool> kEnableUKMLoggingForRegionSearch; + +// Enables UKM logging for the LensStandalone feature. +extern const base::FeatureParam<bool> kEnableUKMLoggingForImageSearch; + +// Returns whether to enable UKM logging for Lens Region Search feature. +extern bool GetEnableUKMLoggingForRegionSearch(); + +// Returns whether to enable UKM logging for LensStandalone feature. +extern bool GetEnableUKMLoggingForImageSearch(); + // Returns the max pixel width/height for the image to be sent to Lens via // region search. The images are sent at 1x as PNGs. extern int GetMaxPixelsForRegionSearch();
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java index 205e51c8..2bf3056 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java
@@ -250,14 +250,12 @@ // Create Subcontrollers. mConnectionController = new PageInfoConnectionController(this, mView.getConnectionRowView(), mWebContents, mDelegate, publisher, mIsInternalPage); - mPermissionsController = - new PageInfoPermissionsController(this, mView.getPermissionsRowView(), mDelegate, - mFullUrl.getSpec(), highlightedPermission); - mCookiesController = new PageInfoCookiesController( - this, mView.getCookiesRowView(), mDelegate, mFullUrl.getSpec()); + mPermissionsController = new PageInfoPermissionsController( + this, mView.getPermissionsRowView(), mDelegate, highlightedPermission); + mCookiesController = + new PageInfoCookiesController(this, mView.getCookiesRowView(), mDelegate); if (PageInfoFeatures.PAGE_INFO_HISTORY.isEnabled()) { - mHistoryController = mDelegate.createHistoryController( - this, mView.getHistoryRowView(), mFullUrl.getHost()); + mHistoryController = mDelegate.createHistoryController(this, mView.getHistoryRowView()); // TODO(crbug.com/1173154): Setup forget this site button after history delete is // implemented. // setupForgetSiteButton(mView.getForgetSiteButton()); @@ -547,4 +545,9 @@ public Activity getActivity() { return mWindowAndroid.getActivity().get(); } + + @Override + public GURL getURL() { + return mFullUrl; + } }
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoControllerDelegate.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoControllerDelegate.java index f3848de..00bb8975 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoControllerDelegate.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoControllerDelegate.java
@@ -182,7 +182,7 @@ */ @Nullable public abstract PageInfoSubpageController createHistoryController( - PageInfoMainController mainController, PageInfoRowView rowView, String host); + PageInfoMainController mainController, PageInfoRowView rowView); /** * @return Returns the browser context associated with this dialog.
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java index 8aa69ea..cebd498 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesController.java
@@ -43,11 +43,11 @@ private Website mWebsite; public PageInfoCookiesController(PageInfoMainController mainController, PageInfoRowView rowView, - PageInfoControllerDelegate delegate, String fullUrl) { + PageInfoControllerDelegate delegate) { mMainController = mainController; mRowView = rowView; mDelegate = delegate; - mFullUrl = fullUrl; + mFullUrl = mainController.getURL().getSpec(); mTitle = mRowView.getContext().getResources().getString(R.string.cookies_title); mBridge = mDelegate.createCookieControlsBridge(this); @@ -89,6 +89,7 @@ params.onClearCallback = this::onClearCookiesClicked; params.onCookieSettingsLinkClicked = mDelegate::showCookieSettings; params.disableCookieDeletion = isDeletionDisabled(); + params.hostName = mMainController.getURL().getHost(); mSubPage.setParams(params); mSubPage.setCookiesCount(mAllowedCookies, mBlockedCookies); mSubPage.setCookieBlockingStatus(mStatus, mIsEnforced);
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java index 07e4e4bb..10cd630 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoCookiesPreference.java
@@ -34,6 +34,7 @@ private Dialog mConfirmationDialog; private boolean mDeleteDisabled; private boolean mDataUsed; + private CharSequence mHostName; /** Parameters to configure the cookie controls view. */ public static class PageInfoCookiesViewParams { @@ -43,6 +44,7 @@ public Runnable onClearCallback; public Runnable onCookieSettingsLinkClicked; public boolean disableCookieDeletion; + public CharSequence hostName; } @Override @@ -94,6 +96,7 @@ updateCookieDeleteButton(); mOnClearCallback = params.onClearCallback; + mHostName = params.hostName; } private void showClearCookiesConfirmation() { @@ -103,6 +106,8 @@ new AlertDialog.Builder(getContext(), R.style.Theme_Chromium_AlertDialog) .setTitle(R.string.page_info_cookies_clear) .setMessage(R.string.page_info_cookies_clear_confirmation) + .setMessage( + getString(R.string.page_info_cookies_clear_confirmation, mHostName)) .setPositiveButton(R.string.page_info_cookies_clear_confirmation_button, (dialog, which) -> mOnClearCallback.run()) .setNegativeButton(
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoMainController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoMainController.java index 42ef6ef..38e6fd7 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoMainController.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoMainController.java
@@ -9,6 +9,7 @@ import androidx.annotation.Nullable; import org.chromium.components.embedder_support.browser_context.BrowserContextHandle; +import org.chromium.url.GURL; /** * Interface for a page info main page controller. @@ -41,4 +42,7 @@ /** @return The Activity associated with the controller. */ @Nullable Activity getActivity(); + + /** @return The GURL of the page associated with the controller. */ + GURL getURL(); }
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java index f1d82c8e..5898c16 100644 --- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java +++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoPermissionsController.java
@@ -53,12 +53,12 @@ new PageInfoDiscoverabilityMetrics(); public PageInfoPermissionsController(PageInfoMainController mainController, - PageInfoRowView view, PageInfoControllerDelegate delegate, String pageUrl, + PageInfoRowView view, PageInfoControllerDelegate delegate, @ContentSettingsType int highlightedPermission) { mMainController = mainController; mRowView = view; mDelegate = delegate; - mPageUrl = pageUrl; + mPageUrl = mainController.getURL().getSpec(); mHighlightedPermission = highlightedPermission; Resources resources = mRowView.getContext().getResources(); mHighlightColor = resources.getColor(R.color.iph_highlight_blue);
diff --git a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc index 55f029b5..3e295a6 100644 --- a/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc +++ b/components/page_load_metrics/browser/observers/use_counter/ukm_features.cc
@@ -193,7 +193,6 @@ WebFeature::kWebPImage, WebFeature::kAVIFImage, WebFeature::kGetDisplayMedia, - WebFeature::kGetCurrentBrowsingContextMedia, WebFeature::kLaxAllowingUnsafeCookies, WebFeature::kOpenWebDatabaseThirdPartyContext, WebFeature::kOversrollBehaviorOnViewportBreaks,
diff --git a/components/password_manager/core/browser/android_affiliation/affiliated_match_helper.cc b/components/password_manager/core/browser/android_affiliation/affiliated_match_helper.cc index ab0a0a4..6416817 100644 --- a/components/password_manager/core/browser/android_affiliation/affiliated_match_helper.cc +++ b/components/password_manager/core/browser/android_affiliation/affiliated_match_helper.cc
@@ -58,21 +58,6 @@ } } -void AffiliatedMatchHelper::GetAffiliatedWebRealms( - const PasswordFormDigest& android_form, - AffiliatedRealmsCallback result_callback) { - if (IsValidAndroidCredential(android_form)) { - affiliation_service_->GetAffiliationsAndBranding( - FacetURI::FromPotentiallyInvalidSpec(android_form.signon_realm), - AndroidAffiliationService::StrategyOnCacheMiss::FETCH_OVER_NETWORK, - base::BindOnce(&AffiliatedMatchHelper::CompleteGetAffiliatedWebRealms, - weak_ptr_factory_.GetWeakPtr(), - std::move(result_callback))); - } else { - std::move(result_callback).Run(std::vector<std::string>()); - } -} - void AffiliatedMatchHelper::InjectAffiliationAndBrandingInformation( std::vector<std::unique_ptr<PasswordForm>> forms, AndroidAffiliationService::StrategyOnCacheMiss strategy_on_cache_miss, @@ -184,22 +169,6 @@ std::move(result_callback).Run(affiliated_realms); } -void AffiliatedMatchHelper::CompleteGetAffiliatedWebRealms( - AffiliatedRealmsCallback result_callback, - const AffiliatedFacets& results, - bool success) { - std::vector<std::string> affiliated_realms; - if (success) { - for (const Facet& affiliated_facet : results) { - if (affiliated_facet.uri.IsValidWebFacetURI()) - // Facet URIs have no trailing slash, whereas realms do. - affiliated_realms.push_back(affiliated_facet.uri.canonical_spec() + - "/"); - } - } - std::move(result_callback).Run(affiliated_realms); -} - void AffiliatedMatchHelper::OnLoginsChanged( PasswordStoreInterface* /*store*/, const PasswordStoreChangeList& changes) {
diff --git a/components/password_manager/core/browser/android_affiliation/affiliated_match_helper.h b/components/password_manager/core/browser/android_affiliation/affiliated_match_helper.h index 4174770..8cd73da 100644 --- a/components/password_manager/core/browser/android_affiliation/affiliated_match_helper.h +++ b/components/password_manager/core/browser/android_affiliation/affiliated_match_helper.h
@@ -67,16 +67,6 @@ const PasswordFormDigest& observed_form, AffiliatedRealmsCallback result_callback); - // Retrieves realms of web sites affiliated with the Android application that - // |android_form| belongs to and invokes |result_callback| on the same thread; - // or yields the empty list if |android_form| is not an Android credential. - // NOTE: This will issue an on-demand network request against the Affiliation - // API if affiliations of the Android application are not cached. However, as - // long as the |android_form| is from the PasswordStore, this should rarely - // happen as affiliation information for those applications are prefetched. - virtual void GetAffiliatedWebRealms(const PasswordFormDigest& android_form, - AffiliatedRealmsCallback result_callback); - // Retrieves affiliation and branding information about the Android // credentials in |forms|, sets |affiliated_web_realm|, |app_display_name| and // |app_icon_url| of forms, and invokes |result_callback|. @@ -119,13 +109,6 @@ bool success); // Called back by AndroidAffiliationService to supply the list of facets - // affiliated with the Android application that GetAffiliatedWebRealms() was - // called with, so that the call can be completed. - void CompleteGetAffiliatedWebRealms(AffiliatedRealmsCallback result_callback, - const AffiliatedFacets& results, - bool success); - - // Called back by AndroidAffiliationService to supply the list of facets // affiliated with the Android credential in |form|. Injects affiliation and // branding information by setting |affiliated_web_realm|, |app_display_name| // and |app_icon_url| on |form| if |success| is true and |results| is
diff --git a/components/password_manager/core/browser/android_affiliation/affiliated_match_helper_unittest.cc b/components/password_manager/core/browser/android_affiliation/affiliated_match_helper_unittest.cc index 16afcbaaa..e95ea0e0 100644 --- a/components/password_manager/core/browser/android_affiliation/affiliated_match_helper_unittest.cc +++ b/components/password_manager/core/browser/android_affiliation/affiliated_match_helper_unittest.cc
@@ -297,18 +297,6 @@ return last_result_realms_; } - std::vector<std::string> GetAffiliatedWebRealms( - const PasswordFormDigest& android_form) { - expecting_result_callback_ = true; - match_helper()->GetAffiliatedWebRealms( - android_form, - base::BindOnce(&AffiliatedMatchHelperTest::OnAffiliatedRealmsCallback, - base::Unretained(this))); - RunUntilIdle(); - EXPECT_FALSE(expecting_result_callback_); - return last_result_realms_; - } - std::vector<std::unique_ptr<PasswordForm>> InjectAffiliationAndBrandingInformation( std::vector<std::unique_ptr<PasswordForm>> forms) { @@ -448,43 +436,6 @@ testing::IsEmpty()); } -// GetAffiliatedWebRealms* tests verify that GetAffiliatedWebRealms() returns -// the realms of web sites affiliated with the given Android application, but -// only web sites, and only if an Android application is queried. - -TEST_P(AffiliatedMatchHelperTest, GetAffiliatedWebRealmsYieldsResults) { - mock_affiliation_service() - ->ExpectCallToGetAffiliationsAndBrandingAndSucceedWithResult( - FacetURI::FromCanonicalSpec(kTestAndroidFacetURIAlpha3), - StrategyOnCacheMiss::FETCH_OVER_NETWORK, - GetTestEquivalenceClassAlpha()); - PasswordFormDigest android_form( - GetTestAndroidCredentials(kTestAndroidRealmAlpha3)); - EXPECT_THAT( - GetAffiliatedWebRealms(android_form), - testing::UnorderedElementsAre(kTestWebRealmAlpha1, kTestWebRealmAlpha2)); -} - -TEST_P(AffiliatedMatchHelperTest, GetAffiliatedWebRealmsYieldsOnlyWebsites) { - mock_affiliation_service() - ->ExpectCallToGetAffiliationsAndBrandingAndSucceedWithResult( - FacetURI::FromCanonicalSpec(kTestAndroidFacetURIBeta2), - StrategyOnCacheMiss::FETCH_OVER_NETWORK, - GetTestEquivalenceClassBeta()); - PasswordFormDigest android_form( - GetTestAndroidCredentials(kTestAndroidRealmBeta2)); - // This verifies that |kTestAndroidRealmBeta3| is not returned. - EXPECT_THAT(GetAffiliatedWebRealms(android_form), - testing::UnorderedElementsAre(kTestWebRealmBeta1)); -} - -TEST_P(AffiliatedMatchHelperTest, - GetAffiliatedWebRealmsYieldsEmptyResultsForWebKeyedForms) { - EXPECT_THAT(GetAffiliatedWebRealms( - GetTestObservedWebForm(kTestWebRealmBeta1, nullptr)), - testing::IsEmpty()); -} - // Verifies that InjectAffiliationAndBrandingInformation() injects the realms of // web sites affiliated with the given Android application into the password // forms, as well as branding information corresponding to the application, if
diff --git a/components/password_manager/core/browser/android_affiliation/mock_affiliated_match_helper.cc b/components/password_manager/core/browser/android_affiliation/mock_affiliated_match_helper.cc index d7538847..f7b79e0 100644 --- a/components/password_manager/core/browser/android_affiliation/mock_affiliated_match_helper.cc +++ b/components/password_manager/core/browser/android_affiliation/mock_affiliated_match_helper.cc
@@ -25,13 +25,6 @@ .WillOnce(testing::Return(results_to_return)); } -void MockAffiliatedMatchHelper::ExpectCallToGetAffiliatedWebRealms( - const PasswordFormDigest& expected_android_form, - const std::vector<std::string>& results_to_return) { - EXPECT_CALL(*this, OnGetAffiliatedWebRealmsCalled(expected_android_form)) - .WillOnce(testing::Return(results_to_return)); -} - void MockAffiliatedMatchHelper:: ExpectCallToInjectAffiliationAndBrandingInformation( const std::vector<AffiliationAndBrandingInformation>& @@ -48,14 +41,6 @@ std::move(result_callback).Run(affiliated_android_realms); } -void MockAffiliatedMatchHelper::GetAffiliatedWebRealms( - const PasswordFormDigest& android_form, - AffiliatedRealmsCallback result_callback) { - std::vector<std::string> affiliated_web_realms = - OnGetAffiliatedWebRealmsCalled(android_form); - std::move(result_callback).Run(affiliated_web_realms); -} - void MockAffiliatedMatchHelper::InjectAffiliationAndBrandingInformation( std::vector<std::unique_ptr<PasswordForm>> forms, AndroidAffiliationService::StrategyOnCacheMiss strategy_on_cache_miss,
diff --git a/components/password_manager/core/browser/android_affiliation/mock_affiliated_match_helper.h b/components/password_manager/core/browser/android_affiliation/mock_affiliated_match_helper.h index e395b72..5d4c5e5f 100644 --- a/components/password_manager/core/browser/android_affiliation/mock_affiliated_match_helper.h +++ b/components/password_manager/core/browser/android_affiliation/mock_affiliated_match_helper.h
@@ -39,30 +39,18 @@ const PasswordFormDigest& expected_observed_form, const std::vector<std::string>& results_to_return); - // Expects GetAffiliatedWebRealms() to be called with the - // |expected_android_form|, and will cause the result callback supplied to - // GetAffiliatedWebRealms() to be invoked with |results_to_return|. - void ExpectCallToGetAffiliatedWebRealms( - const PasswordFormDigest& expected_android_form, - const std::vector<std::string>& results_to_return); - void ExpectCallToInjectAffiliationAndBrandingInformation( const std::vector<AffiliationAndBrandingInformation>& results_to_inject); private: MOCK_METHOD1(OnGetAffiliatedAndroidRealmsCalled, std::vector<std::string>(const PasswordFormDigest&)); - MOCK_METHOD1(OnGetAffiliatedWebRealmsCalled, - std::vector<std::string>(const PasswordFormDigest&)); MOCK_METHOD0(OnInjectAffiliationAndBrandingInformationCalled, std::vector<AffiliationAndBrandingInformation>()); void GetAffiliatedAndroidAndWebRealms( const PasswordFormDigest& observed_form, AffiliatedRealmsCallback result_callback) override; - void GetAffiliatedWebRealms( - const PasswordFormDigest& android_form, - AffiliatedRealmsCallback result_callback) override; void InjectAffiliationAndBrandingInformation( std::vector<std::unique_ptr<PasswordForm>> forms,
diff --git a/components/password_manager/core/browser/import/csv_password.cc b/components/password_manager/core/browser/import/csv_password.cc index f8810045..a1b012a 100644 --- a/components/password_manager/core/browser/import/csv_password.cc +++ b/components/password_manager/core/browser/import/csv_password.cc
@@ -106,6 +106,7 @@ form->username_value = Convert(username); form->password_value = Convert(password); form->date_created = base::Time::Now(); + form->date_password_modified = form->date_created; return Status::kOK; }
diff --git a/components/password_manager/core/browser/import/csv_password_unittest.cc b/components/password_manager/core/browser/import/csv_password_unittest.cc index 086a65e..296a2f40 100644 --- a/components/password_manager/core/browser/import/csv_password_unittest.cc +++ b/components/password_manager/core/browser/import/csv_password_unittest.cc
@@ -35,6 +35,7 @@ EXPECT_EQ(u"user", result.username_value); EXPECT_EQ(u"password", result.password_value); EXPECT_EQ(base::Time::Now(), result.date_created); + EXPECT_EQ(base::Time::Now(), result.date_password_modified); } struct TestCase {
diff --git a/components/password_manager/core/browser/ui/saved_passwords_presenter.cc b/components/password_manager/core/browser/ui/saved_passwords_presenter.cc index 7ff7bb338..cad99fb 100644 --- a/components/password_manager/core/browser/ui/saved_passwords_presenter.cc +++ b/components/password_manager/core/browser/ui/saved_passwords_presenter.cc
@@ -100,6 +100,7 @@ return false; found->password_value = std::move(new_password); + found->date_password_modified = base::Time::Now(); found->password_issues->clear(); PasswordStoreInterface& store = form.IsUsingAccountStore() ? *account_store_ : *profile_store_; @@ -147,6 +148,8 @@ PasswordForm new_form = old_form; new_form.username_value = new_username; new_form.password_value = new_password; + if (password_changed) + new_form.date_password_modified = base::Time::Now(); new_form.password_issues->clear(); if (username_changed) {
diff --git a/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc b/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc index 54c7912e..7d2d2230 100644 --- a/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc +++ b/components/password_manager/core/browser/ui/saved_passwords_presenter_unittest.cc
@@ -54,7 +54,8 @@ void RunUntilIdle() { task_env_.RunUntilIdle(); } private: - base::test::SingleThreadTaskEnvironment task_env_; + base::test::SingleThreadTaskEnvironment task_env_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; scoped_refptr<TestPasswordStore> store_ = base::MakeRefCounted<TestPasswordStore>(); SavedPasswordsPresenter presenter_{store_}; @@ -143,6 +144,7 @@ // issues. PasswordForm updated = form; updated.password_value = new_password; + updated.date_password_modified = base::Time::Now(); updated.password_issues->clear(); // Verify that editing a password triggers the right notifications. @@ -239,6 +241,7 @@ // The result of the update should have a new password and no password // issues. updated_password.password_value = new_password; + updated_password.date_password_modified = base::Time::Now(); updated_password.password_issues->clear(); base::HistogramTester histogram_tester; @@ -288,6 +291,7 @@ // password issues. updated_both.username_value = new_username; updated_both.password_value = new_password; + updated_both.date_password_modified = base::Time::Now(); updated_both.password_issues->clear(); base::HistogramTester histogram_tester; @@ -404,10 +408,12 @@ // The result of the update should have a new password and no password_issues. // The same is valid for the duplicate form. updated_form.password_value = new_password; + updated_form.date_password_modified = base::Time::Now(); updated_form.password_issues->clear(); PasswordForm updated_duplicate_form = duplicate_form; updated_duplicate_form.password_value = new_password; + updated_duplicate_form.date_password_modified = base::Time::Now(); updated_duplicate_form.password_issues->clear(); EXPECT_CALL(observer, OnEdited(updated_form)); @@ -486,7 +492,8 @@ void RunUntilIdle() { task_env_.RunUntilIdle(); } private: - base::test::SingleThreadTaskEnvironment task_env_; + base::test::SingleThreadTaskEnvironment task_env_{ + base::test::TaskEnvironment::TimeSource::MOCK_TIME}; scoped_refptr<TestPasswordStore> profile_store_ = base::MakeRefCounted<TestPasswordStore>(IsAccountStore(false)); scoped_refptr<TestPasswordStore> account_store_ = @@ -845,6 +852,7 @@ expected_profile_store_form.username_value = new_username; expected_profile_store_form.password_value = new_password; expected_profile_store_form.in_store = PasswordForm::Store::kProfileStore; + expected_profile_store_form.date_password_modified = base::Time::Now(); expected_profile_store_form.password_issues->clear(); PasswordForm expected_account_store_form = expected_profile_store_form; expected_account_store_form.in_store = PasswordForm::Store::kAccountStore;
diff --git a/components/payments/content/android/payment_app_service_bridge.cc b/components/payments/content/android/payment_app_service_bridge.cc index fdc23b9..a53e47c 100644 --- a/components/payments/content/android/payment_app_service_bridge.cc +++ b/components/payments/content/android/payment_app_service_bridge.cc
@@ -307,7 +307,7 @@ return false; } -ContentPaymentRequestDelegate* +base::WeakPtr<ContentPaymentRequestDelegate> PaymentAppServiceBridge::GetPaymentRequestDelegate() const { // PaymentAppService flow should have short-circuited before this point. NOTREACHED();
diff --git a/components/payments/content/android/payment_app_service_bridge.h b/components/payments/content/android/payment_app_service_bridge.h index 50abe010..9dc22feb 100644 --- a/components/payments/content/android/payment_app_service_bridge.h +++ b/components/payments/content/android/payment_app_service_bridge.h
@@ -80,7 +80,8 @@ bool IsOffTheRecord() const override; const std::vector<autofill::AutofillProfile*>& GetBillingProfiles() override; bool IsRequestedAutofillDataAvailable() override; - ContentPaymentRequestDelegate* GetPaymentRequestDelegate() const override; + base::WeakPtr<ContentPaymentRequestDelegate> GetPaymentRequestDelegate() + const override; void ShowProcessingSpinner() override; base::WeakPtr<PaymentRequestSpec> GetSpec() const override; std::string GetTwaPackageName() const override;
diff --git a/components/payments/content/android_payment_app_factory_unittest.cc b/components/payments/content/android_payment_app_factory_unittest.cc index cfc22b3..1f5ad77 100644 --- a/components/payments/content/android_payment_app_factory_unittest.cc +++ b/components/payments/content/android_payment_app_factory_unittest.cc
@@ -82,7 +82,7 @@ const std::vector<autofill::AutofillProfile*>&()); MOCK_METHOD0(IsRequestedAutofillDataAvailable, bool()); MOCK_CONST_METHOD0(GetPaymentRequestDelegate, - ContentPaymentRequestDelegate*()); + base::WeakPtr<ContentPaymentRequestDelegate>()); MOCK_METHOD1(OnPaymentAppCreated, void(std::unique_ptr<PaymentApp> app)); MOCK_METHOD1(OnPaymentAppCreationError, void(const std::string& error_message));
diff --git a/components/payments/content/autofill_payment_app.cc b/components/payments/content/autofill_payment_app.cc index ea80ca4c..52a64a3 100644 --- a/components/payments/content/autofill_payment_app.cc +++ b/components/payments/content/autofill_payment_app.cc
@@ -34,7 +34,7 @@ const autofill::CreditCard& card, const std::vector<autofill::AutofillProfile*>& billing_profiles, const std::string& app_locale, - PaymentRequestBaseDelegate* payment_request_delegate) + base::WeakPtr<PaymentRequestBaseDelegate> payment_request_delegate) : PaymentApp(autofill::data_util::GetPaymentRequestData(card.network()) .icon_resource_id, PaymentApp::Type::AUTOFILL), @@ -69,14 +69,16 @@ is_waiting_for_billing_address_normalization_ = true; is_waiting_for_card_unmask_ = true; - // Start the normalization of the billing address. - payment_request_delegate_->GetAddressNormalizer()->NormalizeAddressAsync( - billing_address_, /*timeout_seconds=*/5, - base::BindOnce(&AutofillPaymentApp::OnAddressNormalized, - weak_ptr_factory_.GetWeakPtr())); + if (payment_request_delegate_) { + // Start the normalization of the billing address. + payment_request_delegate_->GetAddressNormalizer()->NormalizeAddressAsync( + billing_address_, /*timeout_seconds=*/5, + base::BindOnce(&AutofillPaymentApp::OnAddressNormalized, + weak_ptr_factory_.GetWeakPtr())); - payment_request_delegate_->DoFullCardRequest(credit_card_, - weak_ptr_factory_.GetWeakPtr()); + payment_request_delegate_->DoFullCardRequest( + credit_card_, weak_ptr_factory_.GetWeakPtr()); + } } bool AutofillPaymentApp::IsCompleteForPayment() const { @@ -116,9 +118,11 @@ } void AutofillPaymentApp::RecordUse() { - // Record the use of the credit card. - payment_request_delegate_->GetPersonalDataManager()->RecordUseOf( - &credit_card_); + if (payment_request_delegate_) { + // Record the use of the credit card. + payment_request_delegate_->GetPersonalDataManager()->RecordUseOf( + &credit_card_); + } } bool AutofillPaymentApp::NeedsInstallation() const {
diff --git a/components/payments/content/autofill_payment_app.h b/components/payments/content/autofill_payment_app.h index a91120c..7b0f5e2 100644 --- a/components/payments/content/autofill_payment_app.h +++ b/components/payments/content/autofill_payment_app.h
@@ -33,7 +33,7 @@ const autofill::CreditCard& card, const std::vector<autofill::AutofillProfile*>& billing_profiles, const std::string& app_locale, - PaymentRequestBaseDelegate* payment_request_delegate); + base::WeakPtr<PaymentRequestBaseDelegate> payment_request_delegate); ~AutofillPaymentApp() override; // PaymentApp: @@ -97,7 +97,7 @@ const std::string app_locale_; base::WeakPtr<Delegate> delegate_; - PaymentRequestBaseDelegate* payment_request_delegate_; + base::WeakPtr<PaymentRequestBaseDelegate> payment_request_delegate_; autofill::AutofillProfile billing_address_; std::u16string cvc_;
diff --git a/components/payments/content/autofill_payment_app_unittest.cc b/components/payments/content/autofill_payment_app_unittest.cc index c5a2bd73..9663bb1 100644 --- a/components/payments/content/autofill_payment_app_unittest.cc +++ b/components/payments/content/autofill_payment_app_unittest.cc
@@ -322,7 +322,8 @@ autofill::CreditCard& card = local_credit_card(); card.SetNumber(u""); - AutofillPaymentApp app("visa", card, billing_profiles(), "en-US", &delegate); + AutofillPaymentApp app("visa", card, billing_profiles(), "en-US", + delegate.GetWeakPtr()); FakePaymentAppDelegate app_delegate; @@ -352,7 +353,8 @@ autofill::CreditCard& card = local_credit_card(); card.SetNumber(u""); - AutofillPaymentApp app("visa", card, billing_profiles(), "en-US", &delegate); + AutofillPaymentApp app("visa", card, billing_profiles(), "en-US", + delegate.GetWeakPtr()); FakePaymentAppDelegate app_delegate;
diff --git a/components/payments/content/payment_app_factory.h b/components/payments/content/payment_app_factory.h index fe340a0..f1c571f 100644 --- a/components/payments/content/payment_app_factory.h +++ b/components/payments/content/payment_app_factory.h
@@ -86,8 +86,8 @@ virtual const std::vector<autofill::AutofillProfile*>& GetBillingProfiles() = 0; virtual bool IsRequestedAutofillDataAvailable() = 0; - virtual ContentPaymentRequestDelegate* GetPaymentRequestDelegate() - const = 0; + virtual base::WeakPtr<ContentPaymentRequestDelegate> + GetPaymentRequestDelegate() const = 0; // Called when an app is created. virtual void OnPaymentAppCreated(std::unique_ptr<PaymentApp> app) = 0;
diff --git a/components/payments/content/payment_credential.cc b/components/payments/content/payment_credential.cc index edf253f..ff2e7f3a 100644 --- a/components/payments/content/payment_credential.cc +++ b/components/payments/content/payment_credential.cc
@@ -96,9 +96,14 @@ const std::vector<uint8_t>& credential_id, const std::string& rp_id, StorePaymentCredentialAndHideUserPromptCallback callback) { - if (state_ != State::kMakingCredential || !IsCurrentStateValid() || - !instrument || instrument->display_name.empty() || - credential_id.empty() || rp_id.empty()) { + // If SPCV3 flag is enabled, state will be kIdle and display_name is optional. + bool is_spcv3_enabled = + base::FeatureList::IsEnabled(features::kSecurePaymentConfirmationAPIV3); + if ((is_spcv3_enabled && state_ != State::kIdle) || + (!is_spcv3_enabled && (state_ != State::kMakingCredential || + instrument->display_name.empty())) || + !IsCurrentStateValid() || !instrument || credential_id.empty() || + rp_id.empty()) { Reset(); std::move(callback).Run( mojom::PaymentCredentialStorageStatus::FAILED_TO_STORE_INSTRUMENT); @@ -119,7 +124,10 @@ } void PaymentCredential::HideUserPrompt(HideUserPromptCallback callback) { - if (state_ == State::kMakingCredential) { + bool is_spcv3_enabled = + base::FeatureList::IsEnabled(features::kSecurePaymentConfirmationAPIV3); + if ((is_spcv3_enabled && state_ == State::kIdle) || + (!is_spcv3_enabled && state_ == State::kMakingCredential)) { RecordFirstSystemPromptResult( SecurePaymentConfirmationEnrollSystemPromptResult::kCanceled); } else { @@ -212,9 +220,11 @@ case State::kStoringCredential: return !prompt_callback_ && storage_callback_ && - data_service_request_handle_ && ui_controller_ && - ui_controller_token_ && !pending_icon_download_request_id_ && - encoded_icon_.empty(); + data_service_request_handle_ && + (base::FeatureList::IsEnabled( + features::kSecurePaymentConfirmationAPIV3) || + (ui_controller_ && ui_controller_token_)) && + !pending_icon_download_request_id_ && encoded_icon_.empty(); } }
diff --git a/components/payments/content/payment_method_manifest_table.cc b/components/payments/content/payment_method_manifest_table.cc index 20c18bb..bce36c9 100644 --- a/components/payments/content/payment_method_manifest_table.cc +++ b/components/payments/content/payment_method_manifest_table.cc
@@ -7,10 +7,12 @@ #include <time.h> #include <string> +#include "base/feature_list.h" #include "base/notreached.h" #include "base/time/time.h" #include "components/payments/core/secure_payment_confirmation_instrument.h" #include "components/webdata/common/web_database.h" +#include "content/public/common/content_features.h" #include "sql/statement.h" #include "sql/transaction.h" @@ -161,7 +163,8 @@ bool PaymentMethodManifestTable::AddSecurePaymentConfirmationInstrument( const SecurePaymentConfirmationInstrument& instrument) { - if (!instrument.IsValid()) + if (!instrument.IsValid(base::FeatureList::IsEnabled( + features::kSecurePaymentConfirmationAPIV3))) return false; sql::Transaction transaction(db_); @@ -244,7 +247,8 @@ if (!s.ColumnBlobAsVector(index++, &instrument->icon)) continue; - if (!instrument->IsValid()) + if (!instrument->IsValid(base::FeatureList::IsEnabled( + features::kSecurePaymentConfirmationAPIV3))) continue; instruments.push_back(std::move(instrument));
diff --git a/components/payments/content/payment_method_manifest_table_unittest.cc b/components/payments/content/payment_method_manifest_table_unittest.cc index 1239d84..11232c8 100644 --- a/components/payments/content/payment_method_manifest_table_unittest.cc +++ b/components/payments/content/payment_method_manifest_table_unittest.cc
@@ -60,7 +60,7 @@ instruments) { ASSERT_EQ(1U, instruments.size()); ASSERT_NE(nullptr, instruments.back()); - ASSERT_TRUE(instruments.back()->IsValid()); + ASSERT_TRUE(instruments.back()->IsValid(/*is_spcv3_enabled=*/false)); EXPECT_EQ(credential_id, instruments.back()->credential_id); EXPECT_EQ(relying_party_id, instruments.back()->relying_party_id); EXPECT_EQ(base::ASCIIToUTF16(label), instruments.back()->label); @@ -312,7 +312,7 @@ ASSERT_EQ(2U, instruments.size()); ASSERT_NE(nullptr, instruments.front()); - ASSERT_TRUE(instruments.front()->IsValid()); + ASSERT_TRUE(instruments.front()->IsValid(/*is_spcv3_enabled=*/false)); std::vector<uint8_t> expected_credential_id = {0, 1, 2, 3}; EXPECT_EQ(expected_credential_id, instruments.front()->credential_id); EXPECT_EQ("relying-party.example", instruments.front()->relying_party_id); @@ -321,7 +321,7 @@ EXPECT_EQ(expected_icon, instruments.front()->icon); ASSERT_NE(nullptr, instruments.back()); - ASSERT_TRUE(instruments.back()->IsValid()); + ASSERT_TRUE(instruments.back()->IsValid(/*is_spcv3_enabled=*/false)); expected_credential_id = {4, 5, 6, 7}; EXPECT_EQ(expected_credential_id, instruments.back()->credential_id); EXPECT_EQ("relying-party.example", instruments.back()->relying_party_id);
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc index bbb4aca..352ef5e99 100644 --- a/components/payments/content/payment_request.cc +++ b/components/payments/content/payment_request.cc
@@ -209,7 +209,7 @@ initiator_frame, top_level_origin_, frame_origin_, frame_security_origin_, spec(), /*delegate=*/weak_ptr_factory_.GetWeakPtr(), delegate_->GetApplicationLocale(), delegate_->GetPersonalDataManager(), - delegate_.get(), &journey_logger_); + delegate_->GetContentWeakPtr(), &journey_logger_); journey_logger_.SetRequestedInformation( spec_->request_shipping(), spec_->request_payer_email(), @@ -291,7 +291,7 @@ journey_logger_.SetTriggerTime(); // A tab can display only one PaymentRequest UI at a time. - display_handle_ = display_manager_->TryShow(delegate_.get()); + display_handle_ = display_manager_->TryShow(delegate_->GetContentWeakPtr()); if (!display_handle_) { log_.Error(errors::kAnotherUiShowing); DCHECK(!has_recorded_completion_);
diff --git a/components/payments/content/payment_request_display_manager.cc b/components/payments/content/payment_request_display_manager.cc index 97f8c69..e7b4749 100644 --- a/components/payments/content/payment_request_display_manager.cc +++ b/components/payments/content/payment_request_display_manager.cc
@@ -13,7 +13,7 @@ PaymentRequestDisplayManager::DisplayHandle::DisplayHandle( PaymentRequestDisplayManager* display_manager, - ContentPaymentRequestDelegate* delegate) + base::WeakPtr<ContentPaymentRequestDelegate> delegate) : display_manager_(display_manager), delegate_(delegate) { display_manager_->set_current_handle(this); } @@ -25,21 +25,21 @@ void PaymentRequestDisplayManager::DisplayHandle::Show( base::WeakPtr<PaymentRequest> request) { DCHECK(request); - DCHECK(delegate_); was_shown_ = true; - delegate_->ShowDialog(request); + if (delegate_) + delegate_->ShowDialog(request); } void PaymentRequestDisplayManager::DisplayHandle::Retry() { - DCHECK(delegate_); - delegate_->RetryDialog(); + if (delegate_) + delegate_->RetryDialog(); } void PaymentRequestDisplayManager::DisplayHandle::DisplayPaymentHandlerWindow( const GURL& url, PaymentHandlerOpenWindowCallback callback) { - DCHECK(delegate_); - delegate_->EmbedPaymentHandlerWindow(url, std::move(callback)); + if (delegate_) + delegate_->EmbedPaymentHandlerWindow(url, std::move(callback)); } PaymentRequestDisplayManager::PaymentRequestDisplayManager() @@ -48,9 +48,10 @@ PaymentRequestDisplayManager::~PaymentRequestDisplayManager() {} std::unique_ptr<PaymentRequestDisplayManager::DisplayHandle> -PaymentRequestDisplayManager::TryShow(ContentPaymentRequestDelegate* delegate) { +PaymentRequestDisplayManager::TryShow( + base::WeakPtr<ContentPaymentRequestDelegate> delegate) { std::unique_ptr<PaymentRequestDisplayManager::DisplayHandle> handle; - if (!current_handle_) { + if (!current_handle_ && delegate) { handle = std::make_unique<PaymentRequestDisplayManager::DisplayHandle>( this, delegate); }
diff --git a/components/payments/content/payment_request_display_manager.h b/components/payments/content/payment_request_display_manager.h index 5225810..6951e7c 100644 --- a/components/payments/content/payment_request_display_manager.h +++ b/components/payments/content/payment_request_display_manager.h
@@ -33,7 +33,7 @@ class DisplayHandle { public: DisplayHandle(PaymentRequestDisplayManager* display_manager, - ContentPaymentRequestDelegate* delegate); + base::WeakPtr<ContentPaymentRequestDelegate> delegate); ~DisplayHandle(); void Show(base::WeakPtr<PaymentRequest> request); void Retry(); @@ -48,7 +48,7 @@ private: PaymentRequestDisplayManager* display_manager_; - ContentPaymentRequestDelegate* delegate_; + base::WeakPtr<ContentPaymentRequestDelegate> delegate_; bool was_shown_ = false; DISALLOW_COPY_AND_ASSIGN(DisplayHandle); }; @@ -62,7 +62,7 @@ // called with true if the window is finished opening successfully, false if // opening it failed. std::unique_ptr<DisplayHandle> TryShow( - ContentPaymentRequestDelegate* delegate); + base::WeakPtr<ContentPaymentRequestDelegate> delegate); void ShowPaymentHandlerWindow(const GURL& url, PaymentHandlerOpenWindowCallback callback);
diff --git a/components/payments/content/payment_request_state.cc b/components/payments/content/payment_request_state.cc index 89f463c9..a46c785 100644 --- a/components/payments/content/payment_request_state.cc +++ b/components/payments/content/payment_request_state.cc
@@ -67,7 +67,7 @@ base::WeakPtr<Delegate> delegate, const std::string& app_locale, autofill::PersonalDataManager* personal_data_manager, - ContentPaymentRequestDelegate* payment_request_delegate, + base::WeakPtr<ContentPaymentRequestDelegate> payment_request_delegate, JourneyLogger* journey_logger) : frame_routing_id_(content::GlobalRenderFrameHostId( initiator_render_frame_host->GetProcess()->GetID(), @@ -102,8 +102,8 @@ : nullptr; } -ContentPaymentRequestDelegate* PaymentRequestState::GetPaymentRequestDelegate() - const { +base::WeakPtr<ContentPaymentRequestDelegate> +PaymentRequestState::GetPaymentRequestDelegate() const { return payment_request_delegate_; } @@ -376,7 +376,9 @@ } std::string PaymentRequestState::GetAuthenticatedEmail() const { - return payment_request_delegate_->GetAuthenticatedEmail(); + return payment_request_delegate_ + ? payment_request_delegate_->GetAuthenticatedEmail() + : std::string(); } void PaymentRequestState::AddObserver(Observer* observer) { @@ -517,11 +519,13 @@ // merchant. is_waiting_for_merchant_validation_ = true; - // Start the normalization of the shipping address. - payment_request_delegate_->GetAddressNormalizer()->NormalizeAddressAsync( - *selected_shipping_profile_, /*timeout_seconds=*/2, - base::BindOnce(&PaymentRequestState::OnAddressNormalized, - weak_ptr_factory_.GetWeakPtr())); + if (payment_request_delegate_) { + // Start the normalization of the shipping address. + payment_request_delegate_->GetAddressNormalizer()->NormalizeAddressAsync( + *selected_shipping_profile_, /*timeout_seconds=*/2, + base::BindOnce(&PaymentRequestState::OnAddressNormalized, + weak_ptr_factory_.GetWeakPtr())); + } } void PaymentRequestState::SetSelectedContactProfile( @@ -554,7 +558,9 @@ } autofill::RegionDataLoader* PaymentRequestState::GetRegionDataLoader() { - return payment_request_delegate_->GetRegionDataLoader(); + return payment_request_delegate_ + ? payment_request_delegate_->GetRegionDataLoader() + : nullptr; } bool PaymentRequestState::IsPaymentAppInvoked() const { @@ -562,7 +568,9 @@ } autofill::AddressNormalizer* PaymentRequestState::GetAddressNormalizer() { - return payment_request_delegate_->GetAddressNormalizer(); + return payment_request_delegate_ + ? payment_request_delegate_->GetAddressNormalizer() + : nullptr; } bool PaymentRequestState::IsInitialized() const { @@ -758,7 +766,9 @@ } bool PaymentRequestState::IsInTwa() const { - return !payment_request_delegate_->GetTwaPackageName().empty(); + return payment_request_delegate_ + ? !payment_request_delegate_->GetTwaPackageName().empty() + : false; } bool PaymentRequestState::GetCanMakePaymentValue() const {
diff --git a/components/payments/content/payment_request_state.h b/components/payments/content/payment_request_state.h index 13a31514..e477f155 100644 --- a/components/payments/content/payment_request_state.h +++ b/components/payments/content/payment_request_state.h
@@ -98,21 +98,23 @@ const std::string& error_message)>; // The `spec` parameter should not be null. - PaymentRequestState(content::RenderFrameHost* initiator_render_frame_host, - const GURL& top_level_origin, - const GURL& frame_origin, - const url::Origin& frame_security_origin, - base::WeakPtr<PaymentRequestSpec> spec, - base::WeakPtr<Delegate> delegate, - const std::string& app_locale, - autofill::PersonalDataManager* personal_data_manager, - ContentPaymentRequestDelegate* payment_request_delegate, - JourneyLogger* journey_logger); + PaymentRequestState( + content::RenderFrameHost* initiator_render_frame_host, + const GURL& top_level_origin, + const GURL& frame_origin, + const url::Origin& frame_security_origin, + base::WeakPtr<PaymentRequestSpec> spec, + base::WeakPtr<Delegate> delegate, + const std::string& app_locale, + autofill::PersonalDataManager* personal_data_manager, + base::WeakPtr<ContentPaymentRequestDelegate> payment_request_delegate, + JourneyLogger* journey_logger); ~PaymentRequestState() override; // PaymentAppFactory::Delegate content::WebContents* GetWebContents() override; - ContentPaymentRequestDelegate* GetPaymentRequestDelegate() const override; + base::WeakPtr<ContentPaymentRequestDelegate> GetPaymentRequestDelegate() + const override; void ShowProcessingSpinner() override; base::WeakPtr<PaymentRequestSpec> GetSpec() const override; std::string GetTwaPackageName() const override; @@ -399,7 +401,7 @@ // Credit cards are directly owned by the apps in this list. std::vector<std::unique_ptr<PaymentApp>> available_apps_; - ContentPaymentRequestDelegate* payment_request_delegate_; + base::WeakPtr<ContentPaymentRequestDelegate> payment_request_delegate_; std::unique_ptr<PaymentResponseHelper> response_helper_;
diff --git a/components/payments/content/payment_request_state_unittest.cc b/components/payments/content/payment_request_state_unittest.cc index 66fb43b3..96d531f 100644 --- a/components/payments/content/payment_request_state_unittest.cc +++ b/components/payments/content/payment_request_state_unittest.cc
@@ -94,7 +94,7 @@ GURL("https://example.com/pay"), url::Origin::Create(GURL("https://example.com")), spec_->AsWeakPtr(), weak_ptr_factory_.GetWeakPtr(), "en-US", &test_personal_data_manager_, - &test_payment_request_delegate_, &journey_logger_); + test_payment_request_delegate_.GetContentWeakPtr(), &journey_logger_); state_->AddObserver(this); }
diff --git a/components/payments/content/payment_response_helper.cc b/components/payments/content/payment_response_helper.cc index 5687173..b243ae9 100644 --- a/components/payments/content/payment_response_helper.cc +++ b/components/payments/content/payment_response_helper.cc
@@ -26,7 +26,7 @@ const std::string& app_locale, base::WeakPtr<PaymentRequestSpec> spec, base::WeakPtr<PaymentApp> selected_app, - PaymentRequestDelegate* payment_request_delegate, + base::WeakPtr<PaymentRequestDelegate> payment_request_delegate, autofill::AutofillProfile* selected_shipping_profile, autofill::AutofillProfile* selected_contact_profile, base::WeakPtr<Delegate> delegate) @@ -50,11 +50,13 @@ is_waiting_for_shipping_address_normalization_ = true; - payment_request_delegate_->GetAddressNormalizer()->NormalizeAddressAsync( - *selected_shipping_profile, - /*timeout_seconds=*/5, - base::BindOnce(&PaymentResponseHelper::OnAddressNormalized, - weak_ptr_factory_.GetWeakPtr())); + if (payment_request_delegate_) { + payment_request_delegate_->GetAddressNormalizer()->NormalizeAddressAsync( + *selected_shipping_profile, + /*timeout_seconds=*/5, + base::BindOnce(&PaymentResponseHelper::OnAddressNormalized, + weak_ptr_factory_.GetWeakPtr())); + } } // Start to get the instrument details. Will call back into
diff --git a/components/payments/content/payment_response_helper.h b/components/payments/content/payment_response_helper.h index 6629ceb..d4273d0 100644 --- a/components/payments/content/payment_response_helper.h +++ b/components/payments/content/payment_response_helper.h
@@ -35,13 +35,14 @@ }; // The spec, selected_app and delegate cannot be null. - PaymentResponseHelper(const std::string& app_locale, - base::WeakPtr<PaymentRequestSpec> spec, - base::WeakPtr<PaymentApp> selected_app, - PaymentRequestDelegate* payment_request_delegate, - autofill::AutofillProfile* selected_shipping_profile, - autofill::AutofillProfile* selected_contact_profile, - base::WeakPtr<Delegate> delegate); + PaymentResponseHelper( + const std::string& app_locale, + base::WeakPtr<PaymentRequestSpec> spec, + base::WeakPtr<PaymentApp> selected_app, + base::WeakPtr<PaymentRequestDelegate> payment_request_delegate, + autofill::AutofillProfile* selected_shipping_profile, + autofill::AutofillProfile* selected_contact_profile, + base::WeakPtr<Delegate> delegate); ~PaymentResponseHelper() override; // PaymentApp::Delegate @@ -68,8 +69,7 @@ base::WeakPtr<PaymentRequestSpec> spec_; base::WeakPtr<Delegate> delegate_; base::WeakPtr<PaymentApp> selected_app_; - // Not owned, cannot be null. - PaymentRequestDelegate* payment_request_delegate_; + base::WeakPtr<PaymentRequestDelegate> payment_request_delegate_; // Not owned, can be null (dependent on the spec). autofill::AutofillProfile* selected_contact_profile_;
diff --git a/components/payments/content/payment_response_helper_unittest.cc b/components/payments/content/payment_response_helper_unittest.cc index 5fe19f3..a70abc2 100644 --- a/components/payments/content/payment_response_helper_unittest.cc +++ b/components/payments/content/payment_response_helper_unittest.cc
@@ -42,7 +42,7 @@ visa_card_.set_use_count(5u); autofill_app_ = std::make_unique<AutofillPaymentApp>( "visa", visa_card_, billing_addresses_, "en-US", - &test_payment_request_delegate_); + test_payment_request_delegate_.GetWeakPtr()); } ~PaymentResponseHelperTest() override {} @@ -96,8 +96,8 @@ autofill::AutofillProfile* test_address() { return &address_; } const autofill::CreditCard& test_credit_card() { return visa_card_; } base::WeakPtr<PaymentApp> test_app() { return autofill_app_->AsWeakPtr(); } - PaymentRequestDelegate* test_payment_request_delegate() { - return &test_payment_request_delegate_; + base::WeakPtr<PaymentRequestDelegate> test_payment_request_delegate() { + return test_payment_request_delegate_.GetWeakPtr(); } base::WeakPtr<PaymentResponseHelperTest> GetWeakPtr() {
diff --git a/components/payments/core/secure_payment_confirmation_instrument.cc b/components/payments/core/secure_payment_confirmation_instrument.cc index 0fa4142..f8e45cd 100644 --- a/components/payments/core/secure_payment_confirmation_instrument.cc +++ b/components/payments/core/secure_payment_confirmation_instrument.cc
@@ -32,9 +32,9 @@ SecurePaymentConfirmationInstrument::~SecurePaymentConfirmationInstrument() = default; -bool SecurePaymentConfirmationInstrument::IsValid() const { +bool SecurePaymentConfirmationInstrument::IsValid(bool is_spcv3_enabled) const { return !credential_id.empty() && !relying_party_id.empty() && - !label.empty() && !icon.empty(); + (is_spcv3_enabled || (!label.empty() && !icon.empty())); } } // namespace payments
diff --git a/components/payments/core/secure_payment_confirmation_instrument.h b/components/payments/core/secure_payment_confirmation_instrument.h index 624e63d05..5c1e55a 100644 --- a/components/payments/core/secure_payment_confirmation_instrument.h +++ b/components/payments/core/secure_payment_confirmation_instrument.h
@@ -37,7 +37,7 @@ const SecurePaymentConfirmationInstrument& other) = delete; // Checks instrument validity. - bool IsValid() const; + bool IsValid(bool is_spcv3_enabled) const; std::vector<uint8_t> credential_id; std::string relying_party_id; @@ -47,4 +47,4 @@ } // namespace payments -#endif // COMPONENTS_PAYMENTS_CORE_SECURE_PAYMENT_CONFIRMATION_INSTRUMENT_H_ \ No newline at end of file +#endif // COMPONENTS_PAYMENTS_CORE_SECURE_PAYMENT_CONFIRMATION_INSTRUMENT_H_
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 267a88d..7fee0b4 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -1183,6 +1183,7 @@ 'AssistantOnboardingMode', 'VoiceInteractionContextEnabled', 'VoiceInteractionHotwordEnabled', + 'AssistantVoiceMatchEnabledDuringOobe', 'VoiceInteractionQuickAnswersEnabled', ] }, @@ -21547,6 +21548,35 @@ Leaving the policy unset lets users decide to turn this feature on or off.''', }, { + 'name': 'AssistantVoiceMatchEnabledDuringOobe', + 'owners': ['raleksandrov@google.com', 'cros-oac@google.com'], + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome_os:93-'], + 'tags' : [], + 'features': { + 'dynamic_refresh': True, + 'per_profile': False, + }, + 'items': [ + { + 'value': True, + 'caption': 'Show Google Assistant voice match flow during initial setup', + }, + { + 'value': False, + 'caption': 'Do not show Google Assistant voice match flow during initial setup', + }, + ], + 'example_value': True, + 'default': True, + 'id': 885, + 'caption': '''Enable Google Assistant voice match flow''', + 'desc': '''Setting the policy to Enabled lets show Google Assistant voice match flow during initial setup. Setting the policy to Disabled keeps Google Assistant from showing voice match flow during initial setup. + + Leaving the policy unset means it is Enabled.''', + }, + { 'name': 'VoiceInteractionQuickAnswersEnabled', 'owners': ['llin@google.com'], 'type': 'main', @@ -27798,6 +27828,6 @@ 'placeholders': [], 'deleted_policy_ids': [114, 115, 204, 205, 206, 412, 476, 544, 546, 562, 569, 578, 583, 585, 586, 587, 588, 589, 590, 591, 600, 668, 669], 'deleted_atomic_policy_group_ids': [19], - 'highest_id_currently_used': 884, + 'highest_id_currently_used': 885, 'highest_atomic_group_id_currently_used': 41 }
diff --git a/components/safe_browsing/content/resources/push_file_type_proto.py b/components/safe_browsing/content/resources/push_file_type_proto.py index 9769b4e..8b07d1c 100755 --- a/components/safe_browsing/content/resources/push_file_type_proto.py +++ b/components/safe_browsing/content/resources/push_file_type_proto.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2016 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -40,10 +40,10 @@ gn_command = ['ninja', '-C', opts.dir, RESOURCE_SUBDIR + ':make_all_file_types_protobuf'] - print "Running the following" - print " " + (' '.join(gn_command)) + print("Running the following") + print(" " + (' '.join(gn_command))) if subprocess.call(gn_command): - print "Ninja failed." + print("Ninja failed.") return 1 os.chdir(all_dir) @@ -60,19 +60,19 @@ vers_dir = dirs[0] command = ['gsutil', 'cp', '-Rn', vers_dir, DEST_BUCKET] - print '\nGoing to run the following command' - print ' ', ' '.join(command) - print '\nIn directory' - print ' ', all_dir - print '\nWhich should push the following files' + print('\nGoing to run the following command') + print(' ', ' '.join(command)) + print('\nIn directory') + print(' ', all_dir) + print('\nWhich should push the following files') expected_files = [os.path.join(dp, f) for dp, dn, fn in os.walk(vers_dir) for f in fn] for f in expected_files: - print ' ', f + print(' ', f) - shall = raw_input('\nAre you sure (y/N) ').lower() == 'y' + shall = input('\nAre you sure (y/N) ').lower() == 'y' if not shall: - print 'aborting' + print('aborting') return 1 return subprocess.call(command)
diff --git a/components/safe_browsing/core/browser/password_protection/password_protection_service_base.cc b/components/safe_browsing/core/browser/password_protection/password_protection_service_base.cc index adb2984..4951773f 100644 --- a/components/safe_browsing/core/browser/password_protection/password_protection_service_base.cc +++ b/components/safe_browsing/core/browser/password_protection/password_protection_service_base.cc
@@ -380,10 +380,16 @@ if (password_type.account_type() == ReusedPasswordAccountType::SAVED_PASSWORD) return true; -// Currently password reuse warnings are only supported for saved passwords on -// Android. +// TODO(rsamp) Add test coverage for these changes below in the +// VerifyShouldShowModalWarning tests. + +// Currently password reuse warnings are only supported for saved passwords +// and GAIA passwords on Android. #if defined(OS_ANDROID) - return false; + return base::FeatureList::IsEnabled( + safe_browsing::kPasswordProtectionForSignedInUsers) && + password_type.account_type() == ReusedPasswordAccountType::GMAIL && + password_type.is_account_syncing(); #else if (password_type.account_type() == ReusedPasswordAccountType::NON_GAIA_ENTERPRISE)
diff --git a/components/segmentation_platform/internal/database/mock_signal_database.h b/components/segmentation_platform/internal/database/mock_signal_database.h index 4fede7e..31e31919 100644 --- a/components/segmentation_platform/internal/database/mock_signal_database.h +++ b/components/segmentation_platform/internal/database/mock_signal_database.h
@@ -26,7 +26,6 @@ (proto::SignalType, uint64_t, absl::optional<int32_t>, - base::Time, SignalDatabase::SuccessCallback), (override)); MOCK_METHOD(void,
diff --git a/components/segmentation_platform/internal/database/signal_database.h b/components/segmentation_platform/internal/database/signal_database.h index 56c22768..9cfd080 100644 --- a/components/segmentation_platform/internal/database/signal_database.h +++ b/components/segmentation_platform/internal/database/signal_database.h
@@ -37,7 +37,6 @@ virtual void WriteSample(proto::SignalType signal_type, uint64_t name_hash, absl::optional<int32_t> value, - base::Time timestamp, SuccessCallback callback) = 0; // Called to get signals collected between any two timestamps. The samples are
diff --git a/components/segmentation_platform/internal/database/signal_database_impl.cc b/components/segmentation_platform/internal/database/signal_database_impl.cc index 8301db11..24e8c72 100644 --- a/components/segmentation_platform/internal/database/signal_database_impl.cc +++ b/components/segmentation_platform/internal/database/signal_database_impl.cc
@@ -13,6 +13,7 @@ #include "base/bind.h" #include "base/memory/weak_ptr.h" +#include "base/time/clock.h" #include "base/time/time.h" #include "base/trace_event/typed_macros.h" #include "components/leveldb_proto/public/proto_database.h" @@ -46,8 +47,9 @@ } // namespace -SignalDatabaseImpl::SignalDatabaseImpl(std::unique_ptr<SignalProtoDb> database) - : database_(std::move(database)) {} +SignalDatabaseImpl::SignalDatabaseImpl(std::unique_ptr<SignalProtoDb> database, + base::Clock* clock) + : database_(std::move(database)), clock_(clock) {} SignalDatabaseImpl::~SignalDatabaseImpl() = default; @@ -61,13 +63,18 @@ void SignalDatabaseImpl::WriteSample(proto::SignalType signal_type, uint64_t name_hash, absl::optional<int32_t> value, - base::Time timestamp, SuccessCallback callback) { DCHECK(initialized_); + base::Time timestamp = clock_->Now(); SignalKey key(metadata_utils::SignalTypeToSignalKind(signal_type), name_hash, timestamp, timestamp); proto::SignalData signal_data; + // If there is another sample with the same signal key, collate both into a + // single DB entry. + if (recently_added_signals_.find(key) != recently_added_signals_.end()) + signal_data = recently_added_signals_[key]; + proto::Sample* sample = signal_data.add_samples(); if (value.has_value()) sample->set_value(value.value()); @@ -77,6 +84,8 @@ base::TimeDelta midnight_delta = timestamp - timestamp.UTCMidnight(); sample->set_time_sec_delta(midnight_delta.InSeconds()); + recently_added_signals_[key] = signal_data; + // Write as a new db entry. auto entries_to_save = std::make_unique< std::vector<std::pair<std::string, proto::SignalData>>>(); @@ -85,6 +94,7 @@ std::make_pair(key.ToBinary(), std::move(signal_data))); database_->UpdateEntries(std::move(entries_to_save), std::move(keys_to_delete), std::move(callback)); + CleanupStaleCachedEntries(timestamp); } void SignalDatabaseImpl::GetSamples(proto::SignalType signal_type, @@ -246,4 +256,16 @@ std::move(callback).Run(status == leveldb_proto::Enums::InitStatus::kOK); } +void SignalDatabaseImpl::CleanupStaleCachedEntries( + base::Time current_timestamp) { + base::Time prev_second = current_timestamp - base::TimeDelta::FromSeconds(1); + std::vector<SignalKey> keys_to_delete; + for (const auto& entry : recently_added_signals_) { + if (entry.first.range_end() < prev_second) + keys_to_delete.emplace_back(entry.first); + } + for (const auto& cache_key : keys_to_delete) + recently_added_signals_.erase(cache_key); +} + } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/database/signal_database_impl.h b/components/segmentation_platform/internal/database/signal_database_impl.h index 93736dbe..7645605e9 100644 --- a/components/segmentation_platform/internal/database/signal_database_impl.h +++ b/components/segmentation_platform/internal/database/signal_database_impl.h
@@ -19,6 +19,10 @@ #include "components/segmentation_platform/internal/database/signal_key.h" #include "third_party/abseil-cpp/absl/types/optional.h" +namespace base { +class Clock; +} // namespace base + namespace segmentation_platform { namespace proto { class SignalData; @@ -30,7 +34,8 @@ public: using SignalProtoDb = leveldb_proto::ProtoDatabase<proto::SignalData>; - explicit SignalDatabaseImpl(std::unique_ptr<SignalProtoDb> database); + SignalDatabaseImpl(std::unique_ptr<SignalProtoDb> database, + base::Clock* clock); ~SignalDatabaseImpl() override; // Disallow copy/assign. @@ -42,7 +47,6 @@ void WriteSample(proto::SignalType signal_type, uint64_t name_hash, absl::optional<int32_t> value, - base::Time timestamp, SuccessCallback callback) override; void GetSamples(proto::SignalType signal_type, uint64_t name_hash, @@ -80,12 +84,26 @@ bool success, std::unique_ptr<std::map<std::string, proto::SignalData>> entries); + // Cleans up entries from |recently_added_signals_| cache that are more than 1 + // second old. + void CleanupStaleCachedEntries(base::Time current_timestamp); + // The backing LevelDB proto database. std::unique_ptr<SignalProtoDb> database_; + // Used for getting current time. + base::Clock* clock_; + // Whether or not initialization has been completed. bool initialized_{false}; + // A cache of recently added signals. Used for avoiding collisions between two + // signals if they end up generating the same signal key, which can happen if + // the two WriteSample() calls are less than 1 second apart. In that case, the + // samples will be appended and rewritten to the database. Any entries older + // than 1 second are cleaned up on the subsequent invocation to WriteSample(). + std::map<SignalKey, proto::SignalData> recently_added_signals_; + base::WeakPtrFactory<SignalDatabaseImpl> weak_ptr_factory_{this}; };
diff --git a/components/segmentation_platform/internal/database/signal_database_impl_unittest.cc b/components/segmentation_platform/internal/database/signal_database_impl_unittest.cc index 20aa6d8d..0d5f5d1f 100644 --- a/components/segmentation_platform/internal/database/signal_database_impl_unittest.cc +++ b/components/segmentation_platform/internal/database/signal_database_impl_unittest.cc
@@ -49,7 +49,8 @@ auto db = std::make_unique<leveldb_proto::test::FakeDB<proto::SignalData>>( &db_entries_); db_ = db.get(); - signal_db_ = std::make_unique<SignalDatabaseImpl>(std::move(db)); + signal_db_ = + std::make_unique<SignalDatabaseImpl>(std::move(db), &test_clock_); signal_db_->Initialize(base::DoNothing()); db_->InitStatusCallback(leveldb_proto::Enums::InitStatus::kOK); @@ -90,8 +91,8 @@ // Write a sample. int32_t value = 10; base::Time timestamp = now - base::TimeDelta::FromHours(1); - signal_db_->WriteSample(signal_type, name_hash, value, timestamp, - base::DoNothing()); + test_clock_.SetNow(timestamp); + signal_db_->WriteSample(signal_type, name_hash, value, base::DoNothing()); db_->UpdateCallback(true); // Read back the sample and verify. @@ -101,6 +102,20 @@ db_->LoadCallback(true); CheckVectorsEqual({{timestamp, value}}, get_samples_result_); EXPECT_EQ(1u, db_entries_.size()); + + // Write another sample right away. Both the values should be persisted + // correctly without being overwritten. + int32_t value2 = 20; + signal_db_->WriteSample(signal_type, name_hash, value2, base::DoNothing()); + db_->UpdateCallback(true); + + signal_db_->GetSamples(signal_type, name_hash, now.UTCMidnight(), now, + base::BindOnce(&SignalDatabaseImplTest::OnGetSamples, + base::Unretained(this))); + db_->LoadCallback(true); + CheckVectorsEqual({{timestamp, value}, {timestamp, value2}}, + get_samples_result_); + EXPECT_EQ(1u, db_entries_.size()); } TEST_F(SignalDatabaseImplTest, DeleteSamples) { @@ -113,12 +128,14 @@ base::Time timestamp3 = timestamp2 + base::TimeDelta::FromHours(1); // Write two samples, at timestamp1 and timestamp3. - signal_db_->WriteSample(signal_type, name_hash, absl::nullopt, timestamp1, + test_clock_.SetNow(timestamp1); + signal_db_->WriteSample(signal_type, name_hash, absl::nullopt, base::DoNothing()); db_->UpdateCallback(true); EXPECT_EQ(1u, db_entries_.size()); - signal_db_->WriteSample(signal_type, name_hash, absl::nullopt, timestamp3, + test_clock_.SetNow(timestamp3); + signal_db_->WriteSample(signal_type, name_hash, absl::nullopt, base::DoNothing()); db_->UpdateCallback(true); EXPECT_EQ(2u, db_entries_.size()); @@ -164,16 +181,19 @@ base::Time timestamp_day1_2 = day1 + base::TimeDelta::FromHours(2); base::Time timestamp_day2_1 = day2 + base::TimeDelta::FromHours(2); + test_clock_.SetNow(timestamp_day1_1); signal_db_->WriteSample(signal_type, name_hash, absl::nullopt, - timestamp_day1_1, base::DoNothing()); + base::DoNothing()); db_->UpdateCallback(true); + test_clock_.SetNow(timestamp_day1_2); signal_db_->WriteSample(signal_type, name_hash, absl::nullopt, - timestamp_day1_2, base::DoNothing()); + base::DoNothing()); db_->UpdateCallback(true); + test_clock_.SetNow(timestamp_day2_1); signal_db_->WriteSample(signal_type, name_hash, absl::nullopt, - timestamp_day2_1, base::DoNothing()); + base::DoNothing()); db_->UpdateCallback(true); EXPECT_EQ(3u, db_entries_.size());
diff --git a/components/segmentation_platform/internal/database/signal_key.cc b/components/segmentation_platform/internal/database/signal_key.cc index 1f9de01..b7dfe0f 100644 --- a/components/segmentation_platform/internal/database/signal_key.cc +++ b/components/segmentation_platform/internal/database/signal_key.cc
@@ -101,6 +101,16 @@ return buffer.str(); } +bool SignalKey::operator<(const SignalKey& other) const { + if (kind_ != other.kind_) + return kind_ < other.kind_; + if (name_hash_ != other.name_hash_) + return name_hash_ < other.name_hash_; + if (range_end_ < other.range_end_) + return range_end_ < other.range_end_; + return range_start_ < other.range_start_; +} + std::ostream& operator<<(std::ostream& os, const SignalKey& key) { return os << "{kind=" << key.kind() << ", name_hash=" << key.name_hash() << ", range_start=" << key.range_start()
diff --git a/components/segmentation_platform/internal/database/signal_key.h b/components/segmentation_platform/internal/database/signal_key.h index 930a6073..72cda4a 100644 --- a/components/segmentation_platform/internal/database/signal_key.h +++ b/components/segmentation_platform/internal/database/signal_key.h
@@ -75,6 +75,9 @@ // Returns a human readable representation of the SignalKey. std::string ToDebugString() const; + // Allow SignalKey to be a key in STL containers. + bool operator<(const SignalKey& other) const; + private: // The type of record this key refers to. Kind kind_;
diff --git a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc index bdbd026..7567943e 100644 --- a/components/segmentation_platform/internal/segmentation_platform_service_impl.cc +++ b/components/segmentation_platform/internal/segmentation_platform_service_impl.cc
@@ -92,7 +92,8 @@ // Construct databases. segment_info_database_ = std::make_unique<SegmentInfoDatabase>(std::move(segment_db)); - signal_database_ = std::make_unique<SignalDatabaseImpl>(std::move(signal_db)); + signal_database_ = + std::make_unique<SignalDatabaseImpl>(std::move(signal_db), clock); signal_storage_config_ = std::make_unique<SignalStorageConfig>( std::move(signal_storage_config_db), clock); segmentation_result_prefs_ = @@ -100,9 +101,9 @@ // Construct signal processors. user_action_signal_handler_ = - std::make_unique<UserActionSignalHandler>(signal_database_.get(), clock); + std::make_unique<UserActionSignalHandler>(signal_database_.get()); histogram_signal_handler_ = - std::make_unique<HistogramSignalHandler>(signal_database_.get(), clock); + std::make_unique<HistogramSignalHandler>(signal_database_.get()); signal_filter_processor_ = std::make_unique<SignalFilterProcessor>( segment_info_database_.get(), user_action_signal_handler_.get(), histogram_signal_handler_.get());
diff --git a/components/segmentation_platform/internal/signals/histogram_signal_handler.cc b/components/segmentation_platform/internal/signals/histogram_signal_handler.cc index 41d0b026..f5d570f 100644 --- a/components/segmentation_platform/internal/signals/histogram_signal_handler.cc +++ b/components/segmentation_platform/internal/signals/histogram_signal_handler.cc
@@ -5,14 +5,12 @@ #include "components/segmentation_platform/internal/signals/histogram_signal_handler.h" #include "base/metrics/metrics_hashes.h" -#include "base/time/clock.h" #include "components/segmentation_platform/internal/database/signal_database.h" namespace segmentation_platform { -HistogramSignalHandler::HistogramSignalHandler(SignalDatabase* signal_database, - base::Clock* clock) - : db_(signal_database), clock_(clock), metrics_enabled_(false) {} +HistogramSignalHandler::HistogramSignalHandler(SignalDatabase* signal_database) + : db_(signal_database), metrics_enabled_(false) {} HistogramSignalHandler::~HistogramSignalHandler() = default; @@ -46,8 +44,7 @@ if (!metrics_enabled_) return; - db_->WriteSample(signal_type, name_hash, sample, clock_->Now(), - base::DoNothing()); + db_->WriteSample(signal_type, name_hash, sample, base::DoNothing()); } } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/signals/histogram_signal_handler.h b/components/segmentation_platform/internal/signals/histogram_signal_handler.h index 1527f829..aaf65bd 100644 --- a/components/segmentation_platform/internal/signals/histogram_signal_handler.h +++ b/components/segmentation_platform/internal/signals/histogram_signal_handler.h
@@ -17,10 +17,6 @@ #include "base/metrics/statistics_recorder.h" #include "components/segmentation_platform/internal/proto/types.pb.h" -namespace base { -class Clock; -} // namespace base - namespace segmentation_platform { class SignalDatabase; @@ -29,7 +25,7 @@ // persisting them to the internal database for future processing. class HistogramSignalHandler { public: - HistogramSignalHandler(SignalDatabase* signal_database, base::Clock* clock); + explicit HistogramSignalHandler(SignalDatabase* signal_database); virtual ~HistogramSignalHandler(); // Disallow copy/assign. @@ -53,9 +49,6 @@ // The database storing relevant histogram samples. SignalDatabase* db_; - // Used for getting current time. - base::Clock* clock_; - // Whether or not the segmentation platform should record metrics events. bool metrics_enabled_;
diff --git a/components/segmentation_platform/internal/signals/histogram_signal_handler_unittest.cc b/components/segmentation_platform/internal/signals/histogram_signal_handler_unittest.cc index 76dc469..28a06f6 100644 --- a/components/segmentation_platform/internal/signals/histogram_signal_handler_unittest.cc +++ b/components/segmentation_platform/internal/signals/histogram_signal_handler_unittest.cc
@@ -6,7 +6,6 @@ #include "base/metrics/histogram_macros.h" #include "base/metrics/metrics_hashes.h" -#include "base/test/simple_test_clock.h" #include "base/test/task_environment.h" #include "components/segmentation_platform/internal/database/mock_signal_database.h" #include "components/segmentation_platform/internal/proto/types.pb.h" @@ -32,9 +31,8 @@ void SetUp() override { signal_database_ = std::make_unique<MockSignalDatabase>(); - histogram_signal_handler_ = std::make_unique<HistogramSignalHandler>( - signal_database_.get(), &test_clock_); - test_clock_.SetNow(base::Time::UnixEpoch() + base::TimeDelta::FromHours(8)); + histogram_signal_handler_ = + std::make_unique<HistogramSignalHandler>(signal_database_.get()); } void SetupHistograms() { @@ -45,7 +43,6 @@ } base::test::TaskEnvironment task_environment_; - base::SimpleTestClock test_clock_; std::unique_ptr<MockSignalDatabase> signal_database_; std::unique_ptr<HistogramSignalHandler> histogram_signal_handler_; }; @@ -57,16 +54,15 @@ // Record a registered histogram sample. It should be recorded. EXPECT_CALL(*signal_database_, WriteSample(proto::SignalType::HISTOGRAM_ENUM, - kExpectedHash, Eq(1), _, _)); + kExpectedHash, Eq(1), _)); UMA_HISTOGRAM_BOOLEAN(kExpectedHistogram, true); task_environment_.RunUntilIdle(); // Record an unrelated histogram sample. It should be ignored. std::string kUnrelatedHistogram = "unrelated_histogram"; - EXPECT_CALL( - *signal_database_, - WriteSample(_, base::HashMetricName(kUnrelatedHistogram), _, _, _)) + EXPECT_CALL(*signal_database_, + WriteSample(_, base::HashMetricName(kUnrelatedHistogram), _, _)) .Times(0); UMA_HISTOGRAM_BOOLEAN(kUnrelatedHistogram, true); task_environment_.RunUntilIdle(); @@ -77,7 +73,7 @@ // Metrics is disabled on startup. EXPECT_CALL(*signal_database_, WriteSample(proto::SignalType::HISTOGRAM_ENUM, - kExpectedHash, Eq(1), _, _)) + kExpectedHash, Eq(1), _)) .Times(0); UMA_HISTOGRAM_BOOLEAN(kExpectedHistogram, true); @@ -86,7 +82,7 @@ // Enable metrics. histogram_signal_handler_->EnableMetrics(true); EXPECT_CALL(*signal_database_, WriteSample(proto::SignalType::HISTOGRAM_ENUM, - kExpectedHash, Eq(1), _, _)) + kExpectedHash, Eq(1), _)) .Times(1); UMA_HISTOGRAM_BOOLEAN(kExpectedHistogram, true); task_environment_.RunUntilIdle(); @@ -94,7 +90,7 @@ // Disable metrics again. histogram_signal_handler_->EnableMetrics(false); EXPECT_CALL(*signal_database_, WriteSample(proto::SignalType::HISTOGRAM_ENUM, - kExpectedHash, Eq(1), _, _)) + kExpectedHash, Eq(1), _)) .Times(0); UMA_HISTOGRAM_BOOLEAN(kExpectedHistogram, true); task_environment_.RunUntilIdle(); @@ -102,7 +98,7 @@ // Enable metrics again. histogram_signal_handler_->EnableMetrics(true); EXPECT_CALL(*signal_database_, WriteSample(proto::SignalType::HISTOGRAM_ENUM, - kExpectedHash, Eq(1), _, _)) + kExpectedHash, Eq(1), _)) .Times(1); UMA_HISTOGRAM_BOOLEAN(kExpectedHistogram, true); task_environment_.RunUntilIdle();
diff --git a/components/segmentation_platform/internal/signals/signal_filter_processor_unittest.cc b/components/segmentation_platform/internal/signals/signal_filter_processor_unittest.cc index fe3f98b..cf6a832 100644 --- a/components/segmentation_platform/internal/signals/signal_filter_processor_unittest.cc +++ b/components/segmentation_platform/internal/signals/signal_filter_processor_unittest.cc
@@ -24,14 +24,14 @@ class MockUserActionSignalHandler : public UserActionSignalHandler { public: - MockUserActionSignalHandler() : UserActionSignalHandler(nullptr, nullptr) {} + MockUserActionSignalHandler() : UserActionSignalHandler(nullptr) {} MOCK_METHOD(void, SetRelevantUserActions, (std::set<uint64_t>)); MOCK_METHOD(void, EnableMetrics, (bool)); }; class MockHistogramSignalHandler : public HistogramSignalHandler { public: - MockHistogramSignalHandler() : HistogramSignalHandler(nullptr, nullptr) {} + MockHistogramSignalHandler() : HistogramSignalHandler(nullptr) {} using HistogramAndSignalTypeSet = const std::set<std::pair<std::string, proto::SignalType>>&; MOCK_METHOD(void, SetRelevantHistograms, (HistogramAndSignalTypeSet));
diff --git a/components/segmentation_platform/internal/signals/user_action_signal_handler.cc b/components/segmentation_platform/internal/signals/user_action_signal_handler.cc index 522f5a73..af8195f 100644 --- a/components/segmentation_platform/internal/signals/user_action_signal_handler.cc +++ b/components/segmentation_platform/internal/signals/user_action_signal_handler.cc
@@ -6,16 +6,14 @@ #include "base/callback_helpers.h" #include "base/metrics/metrics_hashes.h" -#include "base/time/clock.h" #include "components/segmentation_platform/internal/database/signal_database.h" #include "components/segmentation_platform/internal/proto/types.pb.h" namespace segmentation_platform { UserActionSignalHandler::UserActionSignalHandler( - SignalDatabase* signal_database, - base::Clock* clock) - : db_(signal_database), clock_(clock), metrics_enabled_(false) { + SignalDatabase* signal_database) + : db_(signal_database), metrics_enabled_(false) { action_callback_ = base::BindRepeating(&UserActionSignalHandler::OnUserAction, weak_ptr_factory_.GetWeakPtr()); } @@ -53,7 +51,7 @@ return; db_->WriteSample(proto::SignalType::USER_ACTION, user_action_hash, - absl::nullopt, clock_->Now(), base::DoNothing()); + absl::nullopt, base::DoNothing()); } } // namespace segmentation_platform
diff --git a/components/segmentation_platform/internal/signals/user_action_signal_handler.h b/components/segmentation_platform/internal/signals/user_action_signal_handler.h index f02fa09e..7fa5eb0 100644 --- a/components/segmentation_platform/internal/signals/user_action_signal_handler.h +++ b/components/segmentation_platform/internal/signals/user_action_signal_handler.h
@@ -11,10 +11,6 @@ #include "base/metrics/user_metrics.h" #include "base/time/time.h" -namespace base { -class Clock; -} // namespace base - namespace segmentation_platform { class SignalDatabase; @@ -23,8 +19,7 @@ // internal database for future processing. class UserActionSignalHandler { public: - explicit UserActionSignalHandler(SignalDatabase* signal_database, - base::Clock* clock); + explicit UserActionSignalHandler(SignalDatabase* signal_database); virtual ~UserActionSignalHandler(); // Disallow copy/assign. @@ -46,9 +41,6 @@ // The database storing relevant user actions. SignalDatabase* db_; - // Used for getting current time. - base::Clock* clock_; - // The callback registered with user metrics module that gets invoked for // every user action. base::ActionCallback action_callback_;
diff --git a/components/segmentation_platform/internal/signals/user_action_signal_handler_unittest.cc b/components/segmentation_platform/internal/signals/user_action_signal_handler_unittest.cc index 8172017..e2decdb 100644 --- a/components/segmentation_platform/internal/signals/user_action_signal_handler_unittest.cc +++ b/components/segmentation_platform/internal/signals/user_action_signal_handler_unittest.cc
@@ -5,7 +5,6 @@ #include "components/segmentation_platform/internal/signals/user_action_signal_handler.h" #include "base/metrics/metrics_hashes.h" -#include "base/test/simple_test_clock.h" #include "base/test/task_environment.h" #include "components/segmentation_platform/internal/database/mock_signal_database.h" #include "components/segmentation_platform/internal/proto/types.pb.h" @@ -32,9 +31,8 @@ base::SetRecordActionTaskRunner( task_environment_.GetMainThreadTaskRunner()); signal_database_ = std::make_unique<MockSignalDatabase>(); - user_action_signal_handler_ = std::make_unique<UserActionSignalHandler>( - signal_database_.get(), &test_clock_); - test_clock_.SetNow(base::Time::UnixEpoch() + base::TimeDelta::FromHours(8)); + user_action_signal_handler_ = + std::make_unique<UserActionSignalHandler>(signal_database_.get()); } void SetupUserActions() { @@ -44,7 +42,6 @@ } base::test::TaskEnvironment task_environment_; - base::SimpleTestClock test_clock_; std::unique_ptr<MockSignalDatabase> signal_database_; std::unique_ptr<UserActionSignalHandler> user_action_signal_handler_; }; @@ -57,7 +54,7 @@ // Fire a registered user action. It should be recorded. EXPECT_CALL(*signal_database_, WriteSample(proto::SignalType::USER_ACTION, kExpectedHash, - Eq(absl::nullopt), test_clock_.Now(), _)); + Eq(absl::nullopt), _)); base::RecordComputedActionAt(kExpectedUserAction, base::TimeTicks::Now()); // Fire an unrelated user action. It should be ignored. @@ -65,7 +62,7 @@ EXPECT_CALL(*signal_database_, WriteSample(proto::SignalType::USER_ACTION, base::HashMetricName(kUnrelatedUserAction), - Eq(absl::nullopt), test_clock_.Now(), _)) + Eq(absl::nullopt), _)) .Times(0); base::RecordComputedActionAt(kUnrelatedUserAction, base::TimeTicks::Now()); } @@ -78,7 +75,7 @@ EXPECT_CALL(*signal_database_, WriteSample(proto::SignalType::USER_ACTION, base::HashMetricName(kExpectedUserAction), - Eq(absl::nullopt), _, _)) + Eq(absl::nullopt), _)) .Times(0); base::RecordComputedActionAt(kExpectedUserAction, time); @@ -87,7 +84,7 @@ EXPECT_CALL(*signal_database_, WriteSample(proto::SignalType::USER_ACTION, base::HashMetricName(kExpectedUserAction), - Eq(absl::nullopt), _, _)) + Eq(absl::nullopt), _)) .Times(1); base::RecordComputedActionAt(kExpectedUserAction, time); @@ -96,7 +93,7 @@ EXPECT_CALL(*signal_database_, WriteSample(proto::SignalType::USER_ACTION, base::HashMetricName(kExpectedUserAction), - Eq(absl::nullopt), _, _)) + Eq(absl::nullopt), _)) .Times(0); base::RecordComputedActionAt(kExpectedUserAction, time); @@ -105,7 +102,7 @@ EXPECT_CALL(*signal_database_, WriteSample(proto::SignalType::USER_ACTION, base::HashMetricName(kExpectedUserAction), - Eq(absl::nullopt), _, _)) + Eq(absl::nullopt), _)) .Times(1); base::RecordComputedActionAt(kExpectedUserAction, time); }
diff --git a/components/soda/soda_installer.cc b/components/soda/soda_installer.cc index 3e4172e..d4e336b0 100644 --- a/components/soda/soda_installer.cc +++ b/components/soda/soda_installer.cc
@@ -5,6 +5,7 @@ #include "components/soda/soda_installer.h" #if BUILDFLAG(IS_CHROMEOS_ASH) +#include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" #endif // BUILDFLAG(IS_CHROMEOS_ASH) #include "base/containers/contains.h" @@ -29,6 +30,10 @@ // static SodaInstaller* SodaInstaller::GetInstance() { +#if BUILDFLAG(IS_CHROMEOS_ASH) + DCHECK( + base::FeatureList::IsEnabled(ash::features::kOnDeviceSpeechRecognition)); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) return g_instance; } @@ -63,7 +68,12 @@ void SodaInstaller::Init(PrefService* profile_prefs, PrefService* global_prefs) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (!base::FeatureList::IsEnabled( + ash::features::kOnDeviceSpeechRecognition) || +#else // !BUILDFLAG(IS_CHROMEOS_ASH) if (!base::FeatureList::IsEnabled(media::kUseSodaForLiveCaption) || +#endif soda_installer_initialized_) { return; } @@ -144,6 +154,13 @@ language_pack_progress_.clear(); } +void SodaInstaller::NotifySodaDownloadProgressForTesting(int progress) { + soda_binary_installed_ = false; + is_soda_downloading_ = true; + installed_languages_.clear(); + NotifyOnSodaProgress(progress); +} + void SodaInstaller::RegisterRegisteredLanguagePackPref( PrefRegistrySimple* registry) { // TODO: Default to one of the user's languages.
diff --git a/components/soda/soda_installer.h b/components/soda/soda_installer.h index d91e56de..08d106db 100644 --- a/components/soda/soda_installer.h +++ b/components/soda/soda_installer.h
@@ -20,6 +20,9 @@ // Installer of SODA (Speech On-Device API). This is a singleton because there // is only one installation of SODA per device. +// SODA is not supported on some Chrome OS devices. Chrome OS callers should +// check if ash::features::kOnDeviceSpeechRecognition is enabled before +// trying to access the SodaInstaller instance. class COMPONENT_EXPORT(SODA_INSTALLER) SodaInstaller { public: // Observer of the SODA (Speech On-Device API) installation. @@ -114,6 +117,7 @@ void NotifySodaInstalledForTesting(); void NotifySodaErrorForTesting(); void UninstallSodaForTesting(); + void NotifySodaDownloadProgressForTesting(int percentage); protected: // Registers the preference tracking the installed SODA language packs.
diff --git a/components/soda/soda_installer_impl_chromeos_unittest.cc b/components/soda/soda_installer_impl_chromeos_unittest.cc index fbd53efc..25f6a89 100644 --- a/components/soda/soda_installer_impl_chromeos_unittest.cc +++ b/components/soda/soda_installer_impl_chromeos_unittest.cc
@@ -4,7 +4,9 @@ #include "components/soda/soda_installer_impl_chromeos.h" +#include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" +#include "base/test/scoped_feature_list.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dlcservice/fake_dlcservice_client.h" #include "components/live_caption/pref_names.h" @@ -23,6 +25,8 @@ class SodaInstallerImplChromeOSTest : public testing::Test { protected: void SetUp() override { + scoped_feature_list_.InitAndEnableFeature( + ash::features::kOnDeviceSpeechRecognition); soda_installer_impl_ = std::make_unique<SodaInstallerImplChromeOS>(); pref_service_ = std::make_unique<TestingPrefServiceSimple>(); soda_installer_impl_->RegisterLocalStatePrefs(pref_service_->registry()); @@ -85,6 +89,7 @@ std::unique_ptr<TestingPrefServiceSimple> pref_service_; chromeos::FakeDlcserviceClient* fake_dlcservice_client_; content::BrowserTaskEnvironment task_environment_; + base::test::ScopedFeatureList scoped_feature_list_; }; TEST_F(SodaInstallerImplChromeOSTest, IsSodaInstalled) {
diff --git a/components/variations/service/variations_service.cc b/components/variations/service/variations_service.cc index 5d9083f..a447d04 100644 --- a/components/variations/service/variations_service.cc +++ b/components/variations/service/variations_service.cc
@@ -356,7 +356,7 @@ state_manager_(state_manager), policy_pref_service_(local_state), initial_request_completed_(false), - disable_deltas_for_next_request_(false), + delta_error_since_last_success_(false), resource_request_allowed_notifier_(std::move(notifier)), request_count_(0), safe_seed_manager_(local_state), @@ -638,7 +638,7 @@ bool enable_deltas = false; std::string serial_number = field_trial_creator_.seed_store()->GetLatestSerialNumber(); - if (!serial_number.empty() && !disable_deltas_for_next_request_) { + if (!serial_number.empty() && !delta_error_since_last_success_) { // Tell the server that delta-compressed seeds are supported. enable_deltas = true; // Get the seed only if its serial number doesn't match what we have. @@ -680,7 +680,7 @@ UMA_HISTOGRAM_COUNTS_100("Variations.RequestCount", request_count_); ++request_count_; last_request_started_time_ = now; - disable_deltas_for_next_request_ = false; + delta_error_since_last_success_ = false; return true; } @@ -902,7 +902,7 @@ StoreSeed(*response_body, signature, country_code, response_date, is_delta_compressed, is_gzip_compressed); if (!store_success && is_delta_compressed) { - disable_deltas_for_next_request_ = true; + delta_error_since_last_success_ = true; // |request_scheduler_| will be null during unit tests. if (request_scheduler_) request_scheduler_->ScheduleFetchShortly();
diff --git a/components/variations/service/variations_service.h b/components/variations/service/variations_service.h index 66250dc..613d534 100644 --- a/components/variations/service/variations_service.h +++ b/components/variations/service/variations_service.h
@@ -399,10 +399,9 @@ // Tracks whether the initial request to the variations server had completed. bool initial_request_completed_; - // Indicates that the next request to the variations service shouldn't specify - // that it supports delta compression. Set to true when a delta compressed - // response encountered an error. - bool disable_deltas_for_next_request_; + // Tracks whether any errors resolving delta compression were encountered + // since the last time a seed was fetched successfully. + bool delta_error_since_last_success_; // Helper class used to tell this service if it's allowed to make network // resource requests.
diff --git a/components/webapps/browser/installable/installable_manager.cc b/components/webapps/browser/installable/installable_manager.cc index 7f54f397b..996d44c 100644 --- a/components/webapps/browser/installable/installable_manager.cc +++ b/components/webapps/browser/installable/installable_manager.cc
@@ -507,6 +507,9 @@ if (worker_error() == NO_MATCHING_SERVICE_WORKER) worker_ = std::make_unique<ServiceWorkerProperty>(); + // |valid_manifest_| shouldn't be re-used across tasks because its state is + // dependent on current task's |params|. + valid_manifest_ = std::make_unique<ValidManifestProperty>(); task_queue_.Next(); WorkOnTask(); } @@ -574,6 +577,8 @@ CheckEligiblity(); } else if (!manifest_->fetched) { FetchManifest(); + } else if (params.valid_manifest && !valid_manifest_->fetched) { + CheckManifestValid(params.check_webapp_manifest_display); } else if (params.valid_primary_icon && params.prefer_maskable_icon && !IsMaskableIconFetched(IconUsage::kPrimary)) { CheckAndFetchBestIcon(GetIdealPrimaryAdaptiveLauncherIconSizeInPx(), @@ -584,8 +589,6 @@ CheckAndFetchBestIcon(GetIdealPrimaryIconSizeInPx(), GetMinimumPrimaryIconSizeInPx(), IconPurpose::ANY, IconUsage::kPrimary); - } else if (params.valid_manifest && !valid_manifest_->fetched) { - CheckManifestValid(params.check_webapp_manifest_display); } else if (params.fetch_screenshots && !is_screenshots_fetch_complete_) { CheckAndFetchScreenshots(); } else if (params.has_worker && !worker_->fetched) {
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 0885e800..1643740 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1382,8 +1382,6 @@ "renderer_host/dip_util.h", "renderer_host/display_feature.cc", "renderer_host/display_feature.h", - "renderer_host/display_util.cc", - "renderer_host/display_util.h", "renderer_host/embedded_frame_sink_impl.cc", "renderer_host/embedded_frame_sink_impl.h", "renderer_host/embedded_frame_sink_provider_impl.cc",
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index d950f11..1f8847f4 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -842,14 +842,7 @@ RunAriaTest(FILE_PATH_LITERAL("aria-grid-extra-wrap-elems.html")); } -// https://crbug.com/1117594 -#if defined(OS_ANDROID) -#define MAYBE_AccessibilityAriaGridCell DISABLED_AccessibilityAriaGridCell -#else -#define MAYBE_AccessibilityAriaGridCell AccessibilityAriaGridCell -#endif -IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - MAYBE_AccessibilityAriaGridCell) { +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityAriaGridCell) { RunAriaTest(FILE_PATH_LITERAL("aria-gridcell.html")); } @@ -989,14 +982,8 @@ RunAriaTest(FILE_PATH_LITERAL("aria-menuitem.html")); } -#if defined(OS_ANDROID) -#define MAYBE_AccessibilityAriaMenuItemInGroup \ - DISABLED_AccessibilityAriaMenuItemInGroup -#else -#define MAYBE_AccessibilityAriaMenuItemInGroup AccessibilityAriaMenuItemInGroup -#endif IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - MAYBE_AccessibilityAriaMenuItemInGroup) { + AccessibilityAriaMenuItemInGroup) { RunAriaTest(FILE_PATH_LITERAL("aria-menuitem-in-group.html")); } // crbug.com/442278 will stop creating new text elements representing title. @@ -2635,13 +2622,7 @@ RunHtmlTest(FILE_PATH_LITERAL("selection-container.html")); } -// https://crbug.com/1117594 -#if defined(OS_ANDROID) -#define MAYBE_AccessibilitySelect DISABLED_AccessibilitySelect -#else -#define MAYBE_AccessibilitySelect AccessibilitySelect -#endif -IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, MAYBE_AccessibilitySelect) { +IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilitySelect) { RunHtmlTest(FILE_PATH_LITERAL("select.html")); } @@ -2660,16 +2641,8 @@ FILE_PATH_LITERAL("select-follows-focus-aria-selected-false.html")); } -// https://crbug.com/1117594 -#if defined(OS_ANDROID) -#define MAYBE_AccessibilitySelectFollowsFocusMultiselect \ - DISABLED_AccessibilitySelectFollowsFocusMultiselect -#else -#define MAYBE_AccessibilitySelectFollowsFocusMultiselect \ - AccessibilitySelectFollowsFocusMultiselect -#endif IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - MAYBE_AccessibilitySelectFollowsFocusMultiselect) { + AccessibilitySelectFollowsFocusMultiselect) { RunHtmlTest(FILE_PATH_LITERAL("select-follows-focus-multiselect.html")); }
diff --git a/content/browser/background_fetch/background_fetch_job_controller_unittest.cc b/content/browser/background_fetch/background_fetch_job_controller_unittest.cc index f42b363..bc16add 100644 --- a/content/browser/background_fetch/background_fetch_job_controller_unittest.cc +++ b/content/browser/background_fetch/background_fetch_job_controller_unittest.cc
@@ -32,8 +32,10 @@ #include "content/public/test/mock_download_manager.h" #include "content/public/test/test_utils.h" #include "testing/gmock/include/gmock/gmock.h" +#include "third_party/blink/public/common/storage_key/storage_key.h" #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom.h" +#include "url/origin.h" using blink::FetchAPIRequestHeadersMap; using testing::_; @@ -468,10 +470,11 @@ TEST_F(BackgroundFetchJobControllerTest, ServiceWorkerRegistrationDeleted) { BackgroundFetchRegistrationId registration_id; + const GURL kFunnyCatUrl("https://example.com/funny_cat.png"); - auto requests = CreateRegistrationForRequests( - ®istration_id, {{GURL("https://example.com/funny_cat.png"), "GET"}}, - /* auto_complete_requests= */ true); + auto requests = + CreateRegistrationForRequests(®istration_id, {{kFunnyCatUrl, "GET"}}, + /* auto_complete_requests= */ true); EXPECT_EQ(JobCompletionStatus::kRunning, GetCompletionStatus(registration_id)); @@ -481,8 +484,9 @@ AddControllerToSchedulerMap(registration_id.unique_id(), std::move(controller)); - scheduler()->OnRegistrationDeleted(kExampleServiceWorkerRegistrationId, - GURL("https://example.com/funny_cat.png")); + scheduler()->OnRegistrationDeleted( + kExampleServiceWorkerRegistrationId, kFunnyCatUrl, + blink::StorageKey(url::Origin::Create(kFunnyCatUrl))); base::RunLoop().RunUntilIdle();
diff --git a/content/browser/background_fetch/background_fetch_scheduler.cc b/content/browser/background_fetch/background_fetch_scheduler.cc index 9b8af02..5fc1a17 100644 --- a/content/browser/background_fetch/background_fetch_scheduler.cc +++ b/content/browser/background_fetch/background_fetch_scheduler.cc
@@ -490,8 +490,10 @@ AbortFetches(service_worker_registration_id); } -void BackgroundFetchScheduler::OnRegistrationDeleted(int64_t registration_id, - const GURL& pattern) { +void BackgroundFetchScheduler::OnRegistrationDeleted( + int64_t registration_id, + const GURL& pattern, + const blink::StorageKey& key) { DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); AbortFetches(registration_id); }
diff --git a/content/browser/background_fetch/background_fetch_scheduler.h b/content/browser/background_fetch/background_fetch_scheduler.h index f1e27f40..a2a9a37 100644 --- a/content/browser/background_fetch/background_fetch_scheduler.h +++ b/content/browser/background_fetch/background_fetch_scheduler.h
@@ -21,6 +21,10 @@ #include "content/common/content_export.h" #include "third_party/blink/public/mojom/background_fetch/background_fetch.mojom.h" +namespace blink { +class StorageKey; +} // namespace blink + namespace content { class BackgroundFetchDataManager; @@ -83,7 +87,8 @@ // ServiceWorkerContextCoreObserver implementation. void OnRegistrationDeleted(int64_t registration_id, - const GURL& pattern) override; + const GURL& pattern, + const blink::StorageKey& key) override; void OnStorageWiped() override; private:
diff --git a/content/browser/background_fetch/background_fetch_service_unittest.cc b/content/browser/background_fetch/background_fetch_service_unittest.cc index 5a93282..cbf7eea 100644 --- a/content/browser/background_fetch/background_fetch_service_unittest.cc +++ b/content/browser/background_fetch/background_fetch_service_unittest.cc
@@ -359,8 +359,10 @@ blink::mojom::FetchAPIResponsePtr response)); // ServiceWorkerContextCoreObserver implementation. - MOCK_METHOD2(OnRegistrationDeleted, - void(int64_t registration_id, const GURL& pattern)); + MOCK_METHOD3(OnRegistrationDeleted, + void(int64_t registration_id, + const GURL& pattern, + const blink::StorageKey& key)); MOCK_METHOD0(OnStorageWiped, void()); // DevToolsBackgroundServicesContext::EventObserver implementation. @@ -1166,7 +1168,7 @@ { using blink::mojom::BackgroundFetchError; EXPECT_CALL(*this, - OnRegistrationDeleted(service_worker_registration_id, _)); + OnRegistrationDeleted(service_worker_registration_id, _, _)); FetchAndUnregisterServiceWorker(service_worker_registration_id, kExampleDeveloperId, std::move(requests), std::move(options), SkBitmap(), &error,
diff --git a/content/browser/background_sync/background_sync_manager.cc b/content/browser/background_sync/background_sync_manager.cc index 7c03927e..26a2757 100644 --- a/content/browser/background_sync/background_sync_manager.cc +++ b/content/browser/background_sync/background_sync_manager.cc
@@ -557,8 +557,10 @@ op_scheduler_.WrapCallbackToRunNext(std::move(callback)))); } -void BackgroundSyncManager::OnRegistrationDeleted(int64_t sw_registration_id, - const GURL& pattern) { +void BackgroundSyncManager::OnRegistrationDeleted( + int64_t sw_registration_id, + const GURL& pattern, + const blink::StorageKey& key) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Operations already in the queue will either fail when they write to storage
diff --git a/content/browser/background_sync/background_sync_manager.h b/content/browser/background_sync/background_sync_manager.h index b1c98f5..3e72d15 100644 --- a/content/browser/background_sync/background_sync_manager.h +++ b/content/browser/background_sync/background_sync_manager.h
@@ -44,6 +44,7 @@ namespace mojom { enum class PermissionStatus; } // namespace mojom +class StorageKey; } // namespace blink namespace content { @@ -117,7 +118,8 @@ // ServiceWorkerContextCoreObserver overrides. void OnRegistrationDeleted(int64_t sw_registration_id, - const GURL& pattern) override; + const GURL& pattern, + const blink::StorageKey& key) override; void OnStorageWiped() override; BackgroundSyncNetworkObserver* GetNetworkObserverForTesting() {
diff --git a/content/browser/browsing_data/browsing_data_browsertest_utils.cc b/content/browser/browsing_data/browsing_data_browsertest_utils.cc index 99b70930..a4a4332d 100644 --- a/content/browser/browsing_data/browsing_data_browsertest_utils.cc +++ b/content/browser/browsing_data/browsing_data_browsertest_utils.cc
@@ -72,6 +72,7 @@ void ServiceWorkerActivationObserver::OnVersionStateChanged( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status) { if (context_->GetLiveVersion(version_id)->status() == ServiceWorkerVersion::ACTIVATED) {
diff --git a/content/browser/browsing_data/browsing_data_browsertest_utils.h b/content/browser/browsing_data/browsing_data_browsertest_utils.h index aadc11d..88eadac 100644 --- a/content/browser/browsing_data/browsing_data_browsertest_utils.h +++ b/content/browser/browsing_data/browsing_data_browsertest_utils.h
@@ -14,6 +14,10 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/http_response.h" +namespace blink { +class StorageKey; +} // namespace blink + namespace content { class StoragePartition; @@ -37,6 +41,7 @@ // ServiceWorkerContextCoreObserver overrides. void OnVersionStateChanged(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status) override; ServiceWorkerContextWrapper* context_;
diff --git a/content/browser/conversions/conversion_network_sender_impl.cc b/content/browser/conversions/conversion_network_sender_impl.cc index 8014b57..9281ff8 100644 --- a/content/browser/conversions/conversion_network_sender_impl.cc +++ b/content/browser/conversions/conversion_network_sender_impl.cc
@@ -61,10 +61,10 @@ base::Time now = base::Time::Now(); base::TimeDelta time_since_original_report_time = (now - report.report_time) + report.extra_delay; - base::UmaHistogramCustomTimes("Conversions.ExtraReportDelay", + base::UmaHistogramCustomTimes("Conversions.ExtraReportDelay2", time_since_original_report_time, base::TimeDelta::FromSeconds(1), - base::TimeDelta::FromDays(7), /*buckets=*/100); + base::TimeDelta::FromDays(24), /*buckets=*/100); base::TimeDelta time_from_conversion_to_report_send = report.report_time - report.conversion_time;
diff --git a/content/browser/cookie_store/cookie_store_context.cc b/content/browser/cookie_store/cookie_store_context.cc index f0035e7e..ab5547c 100644 --- a/content/browser/cookie_store/cookie_store_context.cc +++ b/content/browser/cookie_store/cookie_store_context.cc
@@ -141,7 +141,7 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(core_sequence_checker_); DCHECK(cookie_store_manager_); - cookie_store_manager_->CreateService(std::move(receiver), origin); + cookie_store_manager_->BindReceiver(std::move(receiver), origin); } } // namespace content
diff --git a/content/browser/cookie_store/cookie_store_manager.cc b/content/browser/cookie_store/cookie_store_manager.cc index 2ef1d95..2a4ff47 100644 --- a/content/browser/cookie_store/cookie_store_manager.cc +++ b/content/browser/cookie_store/cookie_store_manager.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" +#include "base/sequence_checker.h" #include "content/browser/cookie_store/cookie_change_subscriptions.pb.h" #include "content/browser/service_worker/embedded_worker_status.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" @@ -46,7 +47,7 @@ service_worker_context_->RemoveObserver(this); } -void CookieStoreManager::CreateService( +void CookieStoreManager::BindReceiver( mojo::PendingReceiver<blink::mojom::CookieStore> receiver, const url::Origin& origin) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -129,6 +130,7 @@ void CookieStoreManager::DidLoadAllSubscriptions( bool succeeded, base::OnceCallback<void(bool)> load_callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(done_loading_subscriptions_); succeeded_loading_subscriptions_ = succeeded; @@ -400,6 +402,8 @@ const GURL& service_worker_origin, const std::vector<std::unique_ptr<CookieChangeSubscription>>& subscriptions, base::OnceCallback<void(bool)> callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (subscriptions.empty()) { service_worker_context_->ClearRegistrationUserData( service_worker_registration_id, {registration_user_data_key_}, @@ -436,7 +440,8 @@ void CookieStoreManager::OnRegistrationDeleted( int64_t service_worker_registration_id, - const GURL& pattern) { + const GURL& pattern, + const blink::StorageKey& key) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); // Waiting for the on-disk subscriptions to be loaded ensures that the @@ -446,7 +451,7 @@ if (!done_loading_subscriptions_) { subscriptions_loaded_callbacks_.push_back(base::BindOnce( &CookieStoreManager::OnRegistrationDeleted, weak_factory_.GetWeakPtr(), - service_worker_registration_id, pattern)); + service_worker_registration_id, pattern, key)); return; } @@ -460,6 +465,8 @@ void CookieStoreManager::ActivateSubscriptions( base::span<const std::unique_ptr<CookieChangeSubscription>> subscriptions) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (subscriptions.empty()) return; @@ -490,6 +497,8 @@ void CookieStoreManager::DeactivateSubscriptions( base::span<const std::unique_ptr<CookieChangeSubscription>> subscriptions) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (subscriptions.empty()) return; @@ -537,6 +546,8 @@ } void CookieStoreManager::OnCookieChange(const net::CookieChangeInfo& change) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Waiting for on-disk subscriptions to be loaded ensures that changes are // delivered to all service workers that subscribed to them in previous // browser sessions. Without waiting, workers might miss cookie changes. @@ -604,6 +615,8 @@ void CookieStoreManager::DispatchChangeEvent( scoped_refptr<ServiceWorkerRegistration> registration, const net::CookieChangeInfo& change) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + scoped_refptr<ServiceWorkerVersion> active_version = registration->active_version(); if (active_version->running_status() != EmbeddedWorkerStatus::RUNNING) {
diff --git a/content/browser/cookie_store/cookie_store_manager.h b/content/browser/cookie_store/cookie_store_manager.h index a3bedacd..ed365fb 100644 --- a/content/browser/cookie_store/cookie_store_manager.h +++ b/content/browser/cookie_store/cookie_store_manager.h
@@ -12,10 +12,10 @@ #include "base/callback.h" #include "base/containers/linked_list.h" #include "base/containers/span.h" -#include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/sequence_checker.h" +#include "base/thread_annotations.h" #include "content/browser/cookie_store/cookie_change_subscription.h" #include "content/browser/cookie_store/cookie_store_host.h" #include "content/browser/service_worker/service_worker_context_core_observer.h" @@ -27,6 +27,10 @@ class GURL; +namespace blink { +class StorageKey; +} // namespace blink + namespace content { class ServiceWorkerContextWrapper; @@ -50,17 +54,20 @@ // // The in-memory subscription database must be populated with data from disk, // by calling ReadAllSubscriptions(). - CookieStoreManager( + explicit CookieStoreManager( scoped_refptr<ServiceWorkerContextWrapper> service_worker_context); + CookieStoreManager(const CookieStoreManager&) = delete; + CookieStoreManager& operator=(const CookieStoreManager&) = delete; + ~CookieStoreManager() override; // Creates a mojo connection to a service worker. // // This is called when service workers use the Cookie Store API to subscribe // to cookie changes or obtain the list of cookie changes. - void CreateService(mojo::PendingReceiver<blink::mojom::CookieStore> receiver, - const url::Origin& origin); + void BindReceiver(mojo::PendingReceiver<blink::mojom::CookieStore> receiver, + const url::Origin& origin); // Starts loading the on-disk subscription data. // @@ -98,7 +105,8 @@ // ServiceWorkerContextCoreObserver void OnRegistrationDeleted(int64_t service_worker_registration_id, - const GURL& pattern) override; + const GURL& pattern, + const blink::StorageKey& key) override; void OnStorageWiped() override; // ::network::mojom::CookieChangeListener @@ -160,6 +168,13 @@ const net::CookieChangeInfo& change, blink::ServiceWorkerStatusCode start_worker_status); + // Instances of this class are currently bound to the service worker core + // thread, because they call ServiceWorkerContextWrapper methods that are + // restricted to that thread. However, the class implementation itself is + // thread-friendly, so it only checks that methods are called on the same + // sequence. + SEQUENCE_CHECKER(sequence_checker_); + // Used to efficiently implement OnRegistrationDeleted(). // // When a service worker registration is removed from the system, the @@ -170,7 +185,7 @@ // O(1) time. std::unordered_map<int64_t, std::vector<std::unique_ptr<CookieChangeSubscription>>> - subscriptions_by_registration_; + subscriptions_by_registration_ GUARDED_BY_CONTEXT(sequence_checker_); // Used to efficiently implement DispatchCookieChange(). // @@ -187,22 +202,26 @@ // linked lists. However, the current approach is more amenable to future // optimizations, such as partitioning by (eTLD+1, cookie name). std::map<std::string, base::LinkedList<CookieChangeSubscription>> - subscriptions_by_url_key_; + subscriptions_by_url_key_ GUARDED_BY_CONTEXT(sequence_checker_); // Used to look up and modify service worker registration data. - scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_; + const scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_ + GUARDED_BY_CONTEXT(sequence_checker_); // Tracks the open mojo pipes created by CreateService(). // // Each pipe is associated with the CookieStoreHost instance that it is // connected to. When the pipe is closed, the UniqueReceiverSet automatically // deletes the CookieStoreHost. - mojo::UniqueReceiverSet<blink::mojom::CookieStore> receivers_; + mojo::UniqueReceiverSet<blink::mojom::CookieStore> receivers_ + GUARDED_BY_CONTEXT(sequence_checker_); // Used to receive cookie changes from the network service. - mojo::Remote<::network::mojom::CookieManager> cookie_manager_; + mojo::Remote<::network::mojom::CookieManager> cookie_manager_ + GUARDED_BY_CONTEXT(sequence_checker_); mojo::Receiver<::network::mojom::CookieChangeListener> - cookie_change_listener_receiver_{this}; + cookie_change_listener_receiver_ GUARDED_BY_CONTEXT(sequence_checker_){ + this}; // The service worker registration user data key for subscription data. // @@ -217,25 +236,20 @@ // and |succeeded_loading_subscriptions_| is set. If the latter is true, // |subscriptions_by_registration_| and |subscriptions_by_url_key_| will also // be populated. - std::vector<base::OnceClosure> subscriptions_loaded_callbacks_; + std::vector<base::OnceClosure> subscriptions_loaded_callbacks_ + GUARDED_BY_CONTEXT(sequence_checker_); // Set to true once all subscriptions have been loaded. - bool done_loading_subscriptions_ = false; + bool done_loading_subscriptions_ GUARDED_BY_CONTEXT(sequence_checker_) = + false; // Only defined when |done_loading_subscriptions_| is true. - bool succeeded_loading_subscriptions_ = false; - - // Instances of this class are currently bound to the service worker core - // thread, because they call ServiceWorkerContextWrapper methods that are - // restricted to that thread. However, the class implementation itself is - // thread-friendly, so it only checks that methods are called on the same - // sequence. - SEQUENCE_CHECKER(sequence_checker_); + bool succeeded_loading_subscriptions_ GUARDED_BY_CONTEXT(sequence_checker_) = + false; // Supports having the manager destroyed while waiting for disk I/O. - base::WeakPtrFactory<CookieStoreManager> weak_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(CookieStoreManager); + base::WeakPtrFactory<CookieStoreManager> weak_factory_ + GUARDED_BY_CONTEXT(sequence_checker_){this}; }; } // namespace content
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc index 05b86710..1adb2acb 100644 --- a/content/browser/devtools/devtools_url_loader_interceptor.cc +++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -89,11 +89,13 @@ protocol::Maybe<std::string> modified_url, protocol::Maybe<std::string> modified_method, protocol::Maybe<protocol::Binary> modified_post_data, - std::unique_ptr<HeadersVector> modified_headers) + std::unique_ptr<HeadersVector> modified_headers, + protocol::Maybe<bool> intercept_response) : modified_url(std::move(modified_url)), modified_method(std::move(modified_method)), modified_post_data(std::move(modified_post_data)), - modified_headers(std::move(modified_headers)) {} + modified_headers(std::move(modified_headers)), + intercept_response(std::move(intercept_response)) {} DevToolsURLLoaderInterceptor::Modifications::Modifications( absl::optional<net::Error> error_reason, @@ -878,6 +880,20 @@ } waiting_for_resolution_ = false; + if (modifications->intercept_response.isJust()) { + if (modifications->intercept_response.fromJust()) { + if (stage_ == InterceptionStage::REQUEST) + stage_ = InterceptionStage::BOTH; + else + stage_ = InterceptionStage::RESPONSE; + } else { + if (stage_ == InterceptionStage::BOTH) + stage_ = InterceptionStage::REQUEST; + else if (stage_ == InterceptionStage::RESPONSE) + stage_ = InterceptionStage::DONT_INTERCEPT; + } + } + if (state_ == State::kAuthRequired) { if (!modifications->auth_challenge_response) return Response::InvalidParams("authChallengeResponse required.");
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.h b/content/browser/devtools/devtools_url_loader_interceptor.h index df9d8eb..449f8e9 100644 --- a/content/browser/devtools/devtools_url_loader_interceptor.h +++ b/content/browser/devtools/devtools_url_loader_interceptor.h
@@ -97,7 +97,8 @@ Modifications(protocol::Maybe<std::string> modified_url, protocol::Maybe<std::string> modified_method, protocol::Maybe<protocol::Binary> modified_post_data, - std::unique_ptr<HeadersVector> modified_headers); + std::unique_ptr<HeadersVector> modified_headers, + protocol::Maybe<bool> intercept_response); Modifications( absl::optional<net::Error> error_reason, scoped_refptr<net::HttpResponseHeaders> response_headers, @@ -124,6 +125,7 @@ protocol::Maybe<std::string> modified_method; protocol::Maybe<protocol::Binary> modified_post_data; std::unique_ptr<HeadersVector> modified_headers; + protocol::Maybe<bool> intercept_response; // AuthChallengeResponse is mutually exclusive with the above. std::unique_ptr<AuthChallengeResponse> auth_challenge_response; };
diff --git a/content/browser/devtools/network_service_devtools_observer.cc b/content/browser/devtools/network_service_devtools_observer.cc index c7f54a9a..6826f4a 100644 --- a/content/browser/devtools/network_service_devtools_observer.cc +++ b/content/browser/devtools/network_service_devtools_observer.cc
@@ -10,6 +10,7 @@ #include "content/browser/devtools/protocol/network_handler.h" #include "content/browser/devtools/render_frame_devtools_agent_host.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" +#include "services/network/public/mojom/http_raw_headers.mojom.h" namespace content {
diff --git a/content/browser/devtools/protocol/fetch_handler.cc b/content/browser/devtools/protocol/fetch_handler.cc index 35c6cf41..730c916 100644 --- a/content/browser/devtools/protocol/fetch_handler.cc +++ b/content/browser/devtools/protocol/fetch_handler.cc
@@ -253,6 +253,7 @@ Maybe<String> method, Maybe<protocol::Binary> postData, Maybe<Array<Fetch::HeaderEntry>> headers, + Maybe<bool> interceptResponse, std::unique_ptr<ContinueRequestCallback> callback) { if (!interceptor_) { callback->sendFailure(Response::ServerError("Fetch domain is not enabled")); @@ -273,7 +274,7 @@ auto modifications = std::make_unique<DevToolsURLLoaderInterceptor::Modifications>( std::move(url), std::move(method), std::move(postData), - std::move(request_headers)); + std::move(request_headers), std::move(interceptResponse)); interceptor_->ContinueInterceptedRequest(requestId, std::move(modifications), WrapCallback(std::move(callback))); }
diff --git a/content/browser/devtools/protocol/fetch_handler.h b/content/browser/devtools/protocol/fetch_handler.h index fc1ac1bd..ed617a8 100644 --- a/content/browser/devtools/protocol/fetch_handler.h +++ b/content/browser/devtools/protocol/fetch_handler.h
@@ -73,6 +73,7 @@ Maybe<String> method, Maybe<protocol::Binary> postData, Maybe<Array<Fetch::HeaderEntry>> headers, + Maybe<bool> interceptResponse, std::unique_ptr<ContinueRequestCallback> callback) override; void ContinueWithAuth( const String& fetchId,
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 858d441..fa3a62d0 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -78,12 +78,12 @@ #include "net/url_request/referrer_policy.h" #include "services/network/public/cpp/data_element.h" #include "services/network/public/cpp/features.h" -#include "services/network/public/cpp/http_raw_request_response_info.h" #include "services/network/public/cpp/is_potentially_trustworthy.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/url_loader_completion_status.h" #include "services/network/public/mojom/client_security_state.mojom-shared.h" #include "services/network/public/mojom/devtools_observer.mojom.h" +#include "services/network/public/mojom/http_raw_headers.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "third_party/blink/public/common/loader/referrer_utils.h" #include "third_party/blink/public/mojom/navigation/navigation_params.mojom.h" @@ -1713,23 +1713,6 @@ response->SetCacheStorageCacheName(info.cache_storage_cache_name); } - auto* raw_info = info.raw_request_response_info.get(); - if (raw_info) { - if (raw_info->http_status_code) { - response->SetStatus(raw_info->http_status_code); - response->SetStatusText(raw_info->http_status_text); - } - if (raw_info->request_headers.size()) { - response->SetRequestHeaders(GetRawHeaders(raw_info->request_headers)); - } - if (!raw_info->request_headers_text.empty()) { - response->SetRequestHeadersText(raw_info->request_headers_text); - } - if (raw_info->response_headers.size()) - response->SetHeaders(GetRawHeaders(raw_info->response_headers)); - if (!raw_info->response_headers_text.empty()) - response->SetHeadersText(raw_info->response_headers_text); - } response->SetProtocol(GetProtocol(url, info)); response->SetRemoteIPAddress( net::HostPortPair::FromIPEndPoint(info.remote_endpoint).HostForURL());
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc index 9c72632..37c35cf 100644 --- a/content/browser/download/download_browsertest.cc +++ b/content/browser/download/download_browsertest.cc
@@ -55,6 +55,7 @@ #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/public/test/download_test_observer.h" +#include "content/public/test/prerender_test_util.h" #include "content/public/test/slow_download_http_response.h" #include "content/public/test/test_download_http_response.h" #include "content/public/test/test_file_error_injector.h" @@ -1429,6 +1430,28 @@ DISALLOW_COPY_AND_ASSIGN(ParallelDownloadTest); }; +class DownloadPrerenderTest : public DownloadContentTest { + public: + DownloadPrerenderTest() + : prerender_helper_( + base::BindRepeating(&DownloadPrerenderTest::GetWebContents, + base::Unretained(this))) {} + ~DownloadPrerenderTest() override = default; + + void SetUpOnMainThread() override { + prerender_helper_.SetUpOnMainThread(embedded_test_server()); + DownloadContentTest::SetUpOnMainThread(); + ASSERT_TRUE(embedded_test_server()->Started()); + } + + test::PrerenderTestHelper* prerender_helper() { return &prerender_helper_; } + + private: + WebContents* GetWebContents() { return shell()->web_contents(); } + + test::PrerenderTestHelper prerender_helper_; +}; + } // namespace // Flaky. See https://crbug.com/754679. @@ -4916,4 +4939,61 @@ 1u, observer->NumDownloadsSeenInState(download::DownloadItem::COMPLETE)); } +// Verify that downloads not triggered by navigation are discarded when +// initiated from a non-active page. +// Navigation downloads won't reach the DownloadManager. That is tested in +// PrerenderBrowserTest.{DownloadInMainFrame,DownloadInSubframe}. +IN_PROC_BROWSER_TEST_F(DownloadPrerenderTest, DiscardNonNavigationDownload) { + const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html"); + const GURL kPrerenderingUrl = + embedded_test_server()->GetURL("/empty.html?prerendering"); + const GURL kDownloadUrl = + embedded_test_server()->GetURL("/download/download-test.lib"); + + EXPECT_TRUE(NavigateToURL(shell(), kInitialUrl)); + + // Create a prerendered page. + int host_id = prerender_helper()->AddPrerender(kPrerenderingUrl); + auto* render_frame_host = + prerender_helper()->GetPrerenderedMainFrameHost(host_id); + auto* web_contents = shell()->web_contents(); + test::PrerenderHostObserver host_observer(*web_contents, host_id); + + // Do a download without navigation from the prerendered RenderFrameHost. The + // download should not reach the download manager. + auto* download_manager = DownloadManagerForShell(shell()); + MockDownloadManagerObserver dm_observer(download_manager); + EXPECT_CALL(dm_observer, OnDownloadCreated(_, _)).Times(0); + EXPECT_CALL(dm_observer, OnDownloadDropped(_)).Times(0); + + auto params = blink::mojom::DownloadURLParams::New(); + params->url = kDownloadUrl; + static_cast<RenderFrameHostImpl*>(render_frame_host) + ->DownloadURL(std::move(params)); + + // Do a download without navigation, from the download manager. In this + // case, the download will be dropped. + EXPECT_CALL(dm_observer, OnDownloadCreated(_, _)).Times(0); + EXPECT_CALL(dm_observer, OnDownloadDropped(_)).Times(1); + + // Create download parameters with the renderer process information from the + // prerendered page and mark it as rendered-initiated, otherwise the download + // won't be checked. + auto download_parameters = std::make_unique<download::DownloadUrlParameters>( + kDownloadUrl, render_frame_host->GetProcess()->GetID(), + render_frame_host->GetRoutingID(), TRAFFIC_ANNOTATION_FOR_TESTS); + download_parameters->set_content_initiated(true); + download_manager->DownloadUrl(std::move(download_parameters)); + + // No navigations were done, so the prerendered page wasn't activated. + EXPECT_FALSE(host_observer.was_activated()); + + // Verify there were no downloads. + EXPECT_TRUE(EnsureNoPendingDownloads()); + + std::vector<download::DownloadItem*> downloads; + download_manager->GetAllDownloads(&downloads); + EXPECT_TRUE(downloads.empty()); +} + } // namespace content
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index a4895cd..7af05162 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -190,8 +190,8 @@ bool opened, base::Time last_access_time, bool transient, - const std::vector<download::DownloadItem::ReceivedSlice>& received_slices) - override { + const std::vector<download::DownloadItem::ReceivedSlice>& received_slices, + const download::DownloadItemRerouteInfo& reroute_info) override { // For history download only as history don't have auto resumption count // saved. int auto_resume_count = download::DownloadItemImpl::kMaxAutoResumeAttempts; @@ -203,7 +203,7 @@ last_modified, received_bytes, total_bytes, auto_resume_count, hash, state, danger_type, interrupt_reason, false /* paused */, false /* allow_metered */, opened, last_access_time, transient, - received_slices, absl::nullopt /*download_schedule*/, + received_slices, reroute_info, absl::nullopt /*download_schedule*/, nullptr /* download_entry */); } @@ -999,12 +999,14 @@ return nullptr; } + download::DownloadItemRerouteInfo reroute_info; + // TODO(https://crbug.com/1203753) take |reroute_info| as an input arg. auto item = base::WrapUnique(item_factory_->CreatePersistedItem( this, guid, id, current_path, target_path, url_chain, referrer_url, site_url, tab_url, tab_refererr_url, request_initiator, mime_type, original_mime_type, start_time, end_time, etag, last_modified, received_bytes, total_bytes, hash, state, danger_type, interrupt_reason, - opened, last_access_time, transient, received_slices)); + opened, last_access_time, transient, received_slices, reroute_info)); if (in_progress_download) { // If a download is in both history DB and in-progress DB, we should // be able to remove the in-progress entry if the following 2 conditions @@ -1029,10 +1031,10 @@ } #if defined(OS_ANDROID) if (target_path.IsContentUri()) { - base::FilePath display_name = + base::FilePath android_display_name = in_progress_manager_->GetDownloadDisplayName(target_path); - if (!display_name.empty()) - item->SetDisplayName(display_name); + if (!android_display_name.empty()) + item->SetDisplayName(android_display_name); else return nullptr; } @@ -1382,23 +1384,33 @@ auto* rfh = RenderFrameHost::FromID(params->render_process_host_id(), params->render_frame_host_routing_id()); bool content_initiated = params->content_initiated(); - // If it's from the web, we don't trust it, so we push the throttle on. - if (rfh && content_initiated && delegate_) { - WebContents::Getter web_contents_getter = base::BindRepeating( - WebContents::FromFrameTreeNodeId, rfh->GetFrameTreeNodeId()); - const GURL& url = params->url(); - const std::string& method = params->method(); - absl::optional<url::Origin> initiator = params->initiator(); - base::OnceCallback<void(bool /* download allowed */)> - on_can_download_checks_done = base::BindOnce( - &DownloadManagerImpl::BeginResourceDownloadOnChecksComplete, - weak_factory_.GetWeakPtr(), std::move(params), - std::move(blob_url_loader_factory), is_new_download, site_url); - delegate_->CheckDownloadAllowed( - std::move(web_contents_getter), url, method, std::move(initiator), - false /* from_download_cross_origin_redirect */, content_initiated, - std::move(on_can_download_checks_done)); - return; + + if (rfh && content_initiated) { + // Cancel downloads from non-active documents (e.g prerendered, bfcached). + if (rfh->IsInactiveAndDisallowActivation()) { + DropDownload(); + return; + } + + // Push the throttle on the web-initiated downloads before allowing them to + // proceed. + if (delegate_) { + WebContents::Getter web_contents_getter = base::BindRepeating( + WebContents::FromFrameTreeNodeId, rfh->GetFrameTreeNodeId()); + const GURL& url = params->url(); + const std::string& method = params->method(); + absl::optional<url::Origin> initiator = params->initiator(); + base::OnceCallback<void(bool /* download allowed */)> + on_can_download_checks_done = base::BindOnce( + &DownloadManagerImpl::BeginResourceDownloadOnChecksComplete, + weak_factory_.GetWeakPtr(), std::move(params), + std::move(blob_url_loader_factory), is_new_download, site_url); + delegate_->CheckDownloadAllowed( + std::move(web_contents_getter), url, method, std::move(initiator), + false /* from_download_cross_origin_redirect */, content_initiated, + std::move(on_can_download_checks_done)); + return; + } } BeginResourceDownloadOnChecksComplete(
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc index d703c0cd..776a4ad 100644 --- a/content/browser/download/download_manager_impl_unittest.cc +++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -157,8 +157,8 @@ bool opened, base::Time last_access_time, bool transient, - const std::vector<download::DownloadItem::ReceivedSlice>& received_slices) - override; + const std::vector<download::DownloadItem::ReceivedSlice>& received_slices, + const download::DownloadItemRerouteInfo& reroute_info) override; download::DownloadItemImpl* CreateActiveItem( download::DownloadItemImplDelegate* delegate, uint32_t download_id, @@ -237,7 +237,8 @@ bool opened, base::Time last_access_time, bool transient, - const std::vector<download::DownloadItem::ReceivedSlice>& received_slices) { + const std::vector<download::DownloadItem::ReceivedSlice>& received_slices, + const download::DownloadItemRerouteInfo& reroute_info) { DCHECK(items_.find(download_id) == items_.end()); download::MockDownloadItemImpl* result = new StrictMock<download::MockDownloadItemImpl>(&item_delegate_); @@ -782,7 +783,8 @@ download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED, false, false, false, base::Time::Now(), true, std::vector<download::DownloadItem::ReceivedSlice>(), - absl::nullopt /*download_schedule*/, nullptr /* download_entry */); + download::DownloadItemRerouteInfo(), absl::nullopt /*download_schedule*/, + nullptr /* download_entry */); in_progress_manager->AddDownloadItem(std::move(in_progress_item)); SetInProgressDownloadManager(std::move(in_progress_manager)); EXPECT_CALL(GetMockObserver(), OnDownloadCreated(download_manager_.get(), _))
diff --git a/content/browser/interest_group/auction_process_manager.cc b/content/browser/interest_group/auction_process_manager.cc index 537eb3d6..f63761e3 100644 --- a/content/browser/interest_group/auction_process_manager.cc +++ b/content/browser/interest_group/auction_process_manager.cc
@@ -11,7 +11,6 @@ #include "base/memory/weak_ptr.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/timer/timer.h" -#include "content/browser/service_sandbox_type.h" #include "content/public/browser/service_process_host.h" #include "content/services/auction_worklet/public/mojom/auction_worklet_service.mojom.h" #include "mojo/public/cpp/bindings/pending_receiver.h"
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index 78afd60..42f62cc 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -246,7 +246,6 @@ new_request->load_flags = load_flags; new_request->request_body = request_info.common_params->post_data.get(); - new_request->report_raw_headers = request_info.report_raw_headers; new_request->has_user_gesture = request_info.common_params->has_user_gesture; new_request->enable_load_timing = true; new_request->mode = network::mojom::RequestMode::kNavigate;
diff --git a/content/browser/native_io/native_io_host.cc b/content/browser/native_io/native_io_host.cc index 6f5c4304..710cccf 100644 --- a/content/browser/native_io/native_io_host.cc +++ b/content/browser/native_io/native_io_host.cc
@@ -625,8 +625,11 @@ std::move(delete_all_data_callbacks_); delete_all_data_callbacks_.clear(); for (DeleteAllDataCallback& callback : callbacks) { - std::move(callback).Run(error, this); + std::move(callback).Run(error); } + + // May delete `this`. + manager_->DidDeleteHostData(this, base::PassKey<NativeIOHost>()); } } // namespace content
diff --git a/content/browser/native_io/native_io_host.h b/content/browser/native_io/native_io_host.h index 87591b3..88ebc91 100644 --- a/content/browser/native_io/native_io_host.h +++ b/content/browser/native_io/native_io_host.h
@@ -43,8 +43,7 @@ // sequences, if desired. class NativeIOHost : public blink::mojom::NativeIOHost { public: - using DeleteAllDataCallback = - base::OnceCallback<void(base::File::Error result, NativeIOHost* host)>; + using DeleteAllDataCallback = base::OnceCallback<void(base::File::Error)>; // `allow_set_length_ipc` gates NativeIOFileHost::SetLength(), which works // around a sandboxing limitation on macOS < 10.15. This is plumbed as a flag
diff --git a/content/browser/native_io/native_io_manager.cc b/content/browser/native_io/native_io_manager.cc index d5a39d5c..28c6b90 100644 --- a/content/browser/native_io/native_io_manager.cc +++ b/content/browser/native_io/native_io_manager.cc
@@ -172,6 +172,15 @@ MaybeDeleteHost(host); } +void NativeIOManager::DidDeleteHostData(NativeIOHost* host, + base::PassKey<NativeIOHost>) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(host != nullptr); + DCHECK(!host->delete_all_data_in_progress()); + + MaybeDeleteHost(host); +} + void NativeIOManager::MaybeDeleteHost(NativeIOHost* host) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(host != nullptr); @@ -185,19 +194,6 @@ hosts_.erase(host->storage_key()); } -void NativeIOManager::OnDeleteStorageKeyDataCompleted( - storage::mojom::QuotaClient::DeleteStorageKeyDataCallback callback, - base::File::Error result, - NativeIOHost* host) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - MaybeDeleteHost(host); - blink::mojom::QuotaStatusCode quota_result = - result == base::File::FILE_OK ? blink::mojom::QuotaStatusCode::kOk - : blink::mojom::QuotaStatusCode::kUnknown; - std::move(callback).Run(quota_result); -} - void NativeIOManager::DeleteStorageKeyData( const blink::StorageKey& storage_key, storage::mojom::QuotaClient::DeleteStorageKeyDataCallback callback) { @@ -236,14 +232,16 @@ DCHECK(insert_succeeded); } - // base::Unretained is safe here NativeIOHost::DeleteAllData() guarantees that - // the callback will only be called while the NativeIOHost is alive, and this - // NativeIOManager owns the NativeIOHost. So, the unretained NativeIOManager - // will only be referenced if the NativeIOHost is still alive, which implies - // that this NativeIOManager is still alive. - it->second->DeleteAllData( - base::BindOnce(&NativeIOManager::OnDeleteStorageKeyDataCompleted, - base::Unretained(this), std::move(callback))); + // DeleteAllData() will call DidDeleteHostData() asynchronously, which may + // delete this entry from `hosts_`. + it->second->DeleteAllData(base::BindOnce( + [](storage::mojom::QuotaClient::DeleteStorageKeyDataCallback callback, + base::File::Error error) { + std::move(callback).Run((error == base::File::FILE_OK) + ? blink::mojom::QuotaStatusCode::kOk + : blink::mojom::QuotaStatusCode::kUnknown); + }, + std::move(callback))); } void NativeIOManager::GetStorageKeysForType(
diff --git a/content/browser/native_io/native_io_manager.h b/content/browser/native_io/native_io_manager.h index 3b33861..6844d7a3 100644 --- a/content/browser/native_io/native_io_manager.h +++ b/content/browser/native_io/native_io_manager.h
@@ -124,13 +124,10 @@ void OnHostReceiverDisconnect(NativeIOHost* host, base::PassKey<NativeIOHost>); - // Callback function when DeleteStorageKeyData has completed. + // Called when a NativeIOHost finishes processing a data deletion request. // - // `host` must be owned by this manager. - void OnDeleteStorageKeyDataCompleted( - storage::mojom::QuotaClient::DeleteStorageKeyDataCallback callback, - base::File::Error result, - NativeIOHost* host); + // `host` must be owned by this manager. `host` may be deleted. + void DidDeleteHostData(NativeIOHost* host, base::PassKey<NativeIOHost>); storage::QuotaManagerProxy* quota_manager_proxy() const { return quota_manager_proxy_.get();
diff --git a/content/browser/native_io/native_io_manager_unittest.cc b/content/browser/native_io/native_io_manager_unittest.cc index d39407a..041128d6 100644 --- a/content/browser/native_io/native_io_manager_unittest.cc +++ b/content/browser/native_io/native_io_manager_unittest.cc
@@ -744,30 +744,42 @@ } TEST_P(NativeIOManagerTest, DeleteStorageKeyData_ConcurrentDeletion) { - mojo::Remote<blink::mojom::NativeIOFileHost> example_host_remote; - base::File example_file = - example_host_ - ->OpenFile("test_file", - example_host_remote.BindNewPipeAndPassReceiver()) - .file; - EXPECT_TRUE(example_file.IsValid()); - example_file.Close(); - NativeIOFileHostSync example_file_host(example_host_remote.get()); - example_file_host.Close(); + { + mojo::Remote<blink::mojom::NativeIOFileHost> example_host_remote; + base::File example_file = + example_host_ + ->OpenFile("test_file", + example_host_remote.BindNewPipeAndPassReceiver()) + .file; + EXPECT_TRUE(example_file.IsValid()); + example_file.Close(); + NativeIOFileHostSync example_file_host(example_host_remote.get()); + example_file_host.Close(); + } + + // Reset the last mojo connection to the example host, so the host remains + // without connections during deletion. + example_host_ = nullptr; + example_host_remote_.reset(); StorageKey example_storage_key = StorageKey::CreateFromStringForTesting(kExampleStorageKey); + base::RunLoop delete_run_loop; + blink::mojom::QuotaStatusCode delete_status; manager_->DeleteStorageKeyData( example_storage_key, - base::BindLambdaForTesting( - [&](blink::mojom::QuotaStatusCode returned_status) { - EXPECT_EQ(returned_status, blink::mojom::QuotaStatusCode::kOk); - })); + base::BindLambdaForTesting([&](blink::mojom::QuotaStatusCode status) { + delete_run_loop.Quit(); + delete_status = status; + })); EXPECT_EQ(sync_manager_->DeleteStorageKeyData(example_storage_key), blink::mojom::QuotaStatusCode::kOk); + delete_run_loop.Run(); + EXPECT_EQ(delete_status, blink::mojom::QuotaStatusCode::kOk); + EXPECT_TRUE( !base::PathExists(manager_->RootPathForStorageKey(example_storage_key))); }
diff --git a/content/browser/notifications/platform_notification_context_impl.cc b/content/browser/notifications/platform_notification_context_impl.cc index 4e194cb..0a967ad0 100644 --- a/content/browser/notifications/platform_notification_context_impl.cc +++ b/content/browser/notifications/platform_notification_context_impl.cc
@@ -1093,7 +1093,8 @@ void PlatformNotificationContextImpl::OnRegistrationDeleted( int64_t registration_id, - const GURL& pattern) { + const GURL& pattern, + const blink::StorageKey& key) { DCHECK_CURRENTLY_ON(BrowserThread::UI); InitializeDatabase( base::BindOnce(&PlatformNotificationContextImpl::
diff --git a/content/browser/notifications/platform_notification_context_impl.h b/content/browser/notifications/platform_notification_context_impl.h index 9ee758d7..78f9ab68 100644 --- a/content/browser/notifications/platform_notification_context_impl.h +++ b/content/browser/notifications/platform_notification_context_impl.h
@@ -33,6 +33,10 @@ class SequencedTaskRunner; } +namespace blink { +class StorageKey; +} // namespace blink + namespace url { class Origin; } @@ -124,7 +128,8 @@ // ServiceWorkerContextCoreObserver implementation. void OnRegistrationDeleted(int64_t registration_id, - const GURL& pattern) override; + const GURL& pattern, + const blink::StorageKey& key) override; void OnStorageWiped() override; private:
diff --git a/content/browser/push_messaging/push_messaging_context.cc b/content/browser/push_messaging/push_messaging_context.cc index 83527fa..743a81b0 100644 --- a/content/browser/push_messaging/push_messaging_context.cc +++ b/content/browser/push_messaging/push_messaging_context.cc
@@ -27,7 +27,8 @@ } void PushMessagingContext::OnRegistrationDeleted(int64_t registration_id, - const GURL& pattern) { + const GURL& pattern, + const blink::StorageKey& key) { DCHECK_CURRENTLY_ON(BrowserThread::UI); PushMessagingService* push_service = browser_context_->GetPushMessagingService();
diff --git a/content/browser/push_messaging/push_messaging_context.h b/content/browser/push_messaging/push_messaging_context.h index f5e233f..cf73d143 100644 --- a/content/browser/push_messaging/push_messaging_context.h +++ b/content/browser/push_messaging/push_messaging_context.h
@@ -12,6 +12,10 @@ class GURL; +namespace blink { +class StorageKey; +} // namespace blink + namespace content { class BrowserContext; @@ -28,7 +32,8 @@ // ServiceWorkerContextCoreObserver methods void OnRegistrationDeleted(int64_t registration_id, - const GURL& pattern) override; + const GURL& pattern, + const blink::StorageKey& key) override; void OnStorageWiped() override; private:
diff --git a/content/browser/renderer_host/dip_util.cc b/content/browser/renderer_host/dip_util.cc index 425984d1..ca59ae8 100644 --- a/content/browser/renderer_host/dip_util.cc +++ b/content/browser/renderer_host/dip_util.cc
@@ -4,9 +4,9 @@ #include "content/browser/renderer_host/dip_util.h" -#include "content/browser/renderer_host/display_util.h" #include "content/public/browser/render_widget_host_view.h" #include "ui/base/layout.h" +#include "ui/display/display_util.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/point.h" #include "ui/gfx/geometry/point_conversions.h" @@ -21,7 +21,7 @@ if (view) return view->GetDeviceScaleFactor(); display::ScreenInfo screen_info; - DisplayUtil::GetDefaultScreenInfo(&screen_info); + display::DisplayUtil::GetDefaultScreenInfo(&screen_info); return screen_info.device_scale_factor; }
diff --git a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc index 3fbde2c..8268c707 100644 --- a/content/browser/renderer_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/renderer_host/navigation_controller_impl_browsertest.cc
@@ -26,7 +26,6 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" #include "content/browser/child_process_security_policy_impl.h" -#include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/frame_navigation_entry.h" #include "content/browser/renderer_host/frame_tree.h" #include "content/browser/renderer_host/navigation_controller_impl.h" @@ -82,6 +81,7 @@ #include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h" #include "third_party/blink/public/mojom/frame/frame.mojom-test-utils.h" #include "third_party/blink/public/mojom/frame/user_activation_update_types.mojom.h" +#include "ui/display/display_util.h" namespace content { namespace {
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index cb8522e..06b39a29 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -61,7 +61,6 @@ #include "content/browser/renderer_host/data_transfer_util.h" #include "content/browser/renderer_host/dip_util.h" #include "content/browser/renderer_host/display_feature.h" -#include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/frame_token_message_queue.h" #include "content/browser/renderer_host/frame_tree.h" #include "content/browser/renderer_host/input/fling_scheduler.h" @@ -127,6 +126,7 @@ #include "ui/base/ui_base_features.h" #include "ui/base/ui_base_switches.h" #include "ui/display/display_switches.h" +#include "ui/display/display_util.h" #include "ui/display/screen.h" #include "ui/events/blink/web_input_event_traits.h" #include "ui/events/event.h" @@ -1866,7 +1866,7 @@ if (view_) view_->GetScreenInfo(result); else - DisplayUtil::GetDefaultScreenInfo(result); + display::DisplayUtil::GetDefaultScreenInfo(result); if (display::Display::HasForceRasterColorProfile()) { result->display_color_spaces = gfx::DisplayColorSpaces( @@ -2136,7 +2136,7 @@ continue; } display::ScreenInfo screen_info; - DisplayUtil::DisplayToScreenInfo(&screen_info, display); + display::DisplayUtil::DisplayToScreenInfo(&screen_info, display); if (display::Display::HasForceRasterColorProfile()) { screen_info.display_color_spaces = gfx::DisplayColorSpaces( display::Display::GetForcedRasterColorProfile());
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index 5ad6bbf..c73913d4 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -30,7 +30,6 @@ #include "content/browser/renderer_host/agent_scheduling_group_host.h" #include "content/browser/renderer_host/data_transfer_util.h" #include "content/browser/renderer_host/display_feature.h" -#include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/frame_token_message_queue.h" #include "content/browser/renderer_host/input/mock_input_router.h" #include "content/browser/renderer_host/input/touch_emulator.h" @@ -64,6 +63,7 @@ #include "third_party/blink/public/mojom/input/input_handler.mojom-shared.h" #include "third_party/blink/public/mojom/input/touch_event.mojom.h" #include "third_party/blink/public/mojom/page/drag.mojom.h" +#include "ui/display/display_util.h" #include "ui/display/screen.h" #include "ui/events/base_event_utils.h" #include "ui/events/blink/blink_features.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 7981bf6b..8ea447b 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -51,7 +51,6 @@ #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/renderer_host/compositor_impl_android.h" #include "content/browser/renderer_host/delegated_frame_host_client_android.h" -#include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/input/input_router.h" #include "content/browser/renderer_host/input/synthetic_gesture_target_android.h" #include "content/browser/renderer_host/input/touch_selection_controller_client_manager_android.h" @@ -87,6 +86,7 @@ #include "ui/android/window_android_compositor.h" #include "ui/base/layout.h" #include "ui/base/ui_base_types.h" +#include "ui/display/display_util.h" #include "ui/events/android/gesture_event_android.h" #include "ui/events/android/gesture_event_type.h" #include "ui/events/android/motion_event_android.h" @@ -2517,8 +2517,8 @@ RenderWidgetHostViewBase::GetScreenInfo(screen_info); return; } - DisplayUtil::DisplayToScreenInfo(screen_info, - window->GetDisplayWithWindowColorSpace()); + display::DisplayUtil::DisplayToScreenInfo( + screen_info, window->GetDisplayWithWindowColorSpace()); } std::vector<std::unique_ptr<ui::TouchEvent>>
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index 00f5be9c..10dfd88 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -15,7 +15,6 @@ #include "content/browser/compositor/surface_utils.h" #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/browser/renderer_host/delegated_frame_host.h" -#include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/event_with_latency_info.h" #include "content/browser/renderer_host/input/mouse_wheel_phase_handler.h" #include "content/browser/renderer_host/input/synthetic_gesture_target_base.h" @@ -32,6 +31,7 @@ #include "third_party/blink/public/mojom/page/record_content_to_visible_time_request.mojom.h" #include "ui/base/layout.h" #include "ui/base/ui_base_types.h" +#include "ui/display/display_util.h" #include "ui/display/screen.h" #include "ui/events/event.h" #include "ui/events/keycodes/dom/dom_code.h" @@ -629,7 +629,7 @@ } void RenderWidgetHostViewBase::GetScreenInfo(display::ScreenInfo* screen_info) { - DisplayUtil::GetNativeViewScreenInfo(screen_info, GetNativeView()); + display::DisplayUtil::GetNativeViewScreenInfo(screen_info, GetNativeView()); } float RenderWidgetHostViewBase::GetDeviceScaleFactor() {
diff --git a/content/browser/renderer_host/render_widget_host_view_base_unittest.cc b/content/browser/renderer_host/render_widget_host_view_base_unittest.cc index c57fd91..530230ff 100644 --- a/content/browser/renderer_host/render_widget_host_view_base_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_base_unittest.cc
@@ -4,9 +4,9 @@ #include "content/browser/renderer_host/render_widget_host_view_base.h" -#include "content/browser/renderer_host/display_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/display/display.h" +#include "ui/display/display_util.h" namespace content { @@ -30,57 +30,57 @@ display::Display display = CreateDisplay(100, 100, display::Display::ROTATE_0); EXPECT_EQ(display::mojom::ScreenOrientation::kPortraitPrimary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); display = CreateDisplay(200, 200, display::Display::ROTATE_90); EXPECT_EQ(display::mojom::ScreenOrientation::kLandscapePrimary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); display = CreateDisplay(0, 0, display::Display::ROTATE_180); EXPECT_EQ(display::mojom::ScreenOrientation::kPortraitSecondary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); display = CreateDisplay(10000, 10000, display::Display::ROTATE_270); EXPECT_EQ(display::mojom::ScreenOrientation::kLandscapeSecondary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); } // natural width > natural height. { display::Display display = CreateDisplay(1, 0, display::Display::ROTATE_0); EXPECT_EQ(display::mojom::ScreenOrientation::kLandscapePrimary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); display = CreateDisplay(19999, 20000, display::Display::ROTATE_90); EXPECT_EQ(display::mojom::ScreenOrientation::kPortraitSecondary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); display = CreateDisplay(200, 100, display::Display::ROTATE_180); EXPECT_EQ(display::mojom::ScreenOrientation::kLandscapeSecondary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); display = CreateDisplay(1, 10000, display::Display::ROTATE_270); EXPECT_EQ(display::mojom::ScreenOrientation::kPortraitPrimary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); } // natural width < natural height. { display::Display display = CreateDisplay(0, 1, display::Display::ROTATE_0); EXPECT_EQ(display::mojom::ScreenOrientation::kPortraitPrimary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); display = CreateDisplay(20000, 19999, display::Display::ROTATE_90); EXPECT_EQ(display::mojom::ScreenOrientation::kLandscapePrimary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); display = CreateDisplay(100, 200, display::Display::ROTATE_180); EXPECT_EQ(display::mojom::ScreenOrientation::kPortraitSecondary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); display = CreateDisplay(10000, 1, display::Display::ROTATE_270); EXPECT_EQ(display::mojom::ScreenOrientation::kLandscapeSecondary, - DisplayUtil::GetOrientationTypeForMobile(display)); + display::DisplayUtil::GetOrientationTypeForMobile(display)); } } @@ -95,14 +95,14 @@ { display::Display display = CreateDisplay(1, 0, display::Display::ROTATE_0); display::mojom::ScreenOrientation landscape_1 = - DisplayUtil::GetOrientationTypeForDesktop(display); + display::DisplayUtil::GetOrientationTypeForDesktop(display); EXPECT_TRUE( landscape_1 == display::mojom::ScreenOrientation::kLandscapePrimary || landscape_1 == display::mojom::ScreenOrientation::kLandscapeSecondary); display = CreateDisplay(200, 100, display::Display::ROTATE_180); display::mojom::ScreenOrientation landscape_2 = - DisplayUtil::GetOrientationTypeForDesktop(display); + display::DisplayUtil::GetOrientationTypeForDesktop(display); EXPECT_TRUE( landscape_2 == display::mojom::ScreenOrientation::kLandscapePrimary || landscape_2 == display::mojom::ScreenOrientation::kLandscapeSecondary); @@ -111,14 +111,14 @@ display = CreateDisplay(19999, 20000, display::Display::ROTATE_90); display::mojom::ScreenOrientation portrait_1 = - DisplayUtil::GetOrientationTypeForDesktop(display); + display::DisplayUtil::GetOrientationTypeForDesktop(display); EXPECT_TRUE( portrait_1 == display::mojom::ScreenOrientation::kPortraitPrimary || portrait_1 == display::mojom::ScreenOrientation::kPortraitSecondary); display = CreateDisplay(1, 10000, display::Display::ROTATE_270); display::mojom::ScreenOrientation portrait_2 = - DisplayUtil::GetOrientationTypeForDesktop(display); + display::DisplayUtil::GetOrientationTypeForDesktop(display); EXPECT_TRUE( portrait_2 == display::mojom::ScreenOrientation::kPortraitPrimary || portrait_2 == display::mojom::ScreenOrientation::kPortraitSecondary);
diff --git a/content/browser/renderer_host/render_widget_host_view_child_frame.cc b/content/browser/renderer_host/render_widget_host_view_child_frame.cc index 8b3eac2..833fb3b 100644 --- a/content/browser/renderer_host/render_widget_host_view_child_frame.cc +++ b/content/browser/renderer_host/render_widget_host_view_child_frame.cc
@@ -23,7 +23,6 @@ #include "content/browser/gpu/compositor_util.h" #include "content/browser/renderer_host/cross_process_frame_connector.h" #include "content/browser/renderer_host/cursor_manager.h" -#include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/input/synthetic_gesture_target.h" #include "content/browser/renderer_host/input/touch_selection_controller_client_child_frame.h" #include "content/browser/renderer_host/render_view_host_impl.h" @@ -37,6 +36,7 @@ #include "third_party/blink/public/mojom/frame/intrinsic_sizing_info.mojom.h" #include "third_party/blink/public/mojom/frame/viewport_intersection_state.mojom.h" #include "ui/base/ime/mojom/text_input_state.mojom.h" +#include "ui/display/display_util.h" #include "ui/gfx/geometry/dip_util.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/size_f.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index cdbfdb7b..8109cf4 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -31,7 +31,6 @@ #import "content/browser/accessibility/browser_accessibility_mac.h" #include "content/browser/accessibility/browser_accessibility_manager_mac.h" #include "content/browser/renderer_host/cursor_manager.h" -#include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/input/motion_event_web.h" #import "content/browser/renderer_host/input/synthetic_gesture_target_mac.h" #include "content/browser/renderer_host/input/web_input_event_builders_mac.h" @@ -60,6 +59,7 @@ #include "ui/base/mojom/attributed_string.mojom.h" #include "ui/base/ui_base_features.h" #include "ui/display/display.h" +#include "ui/display/display_util.h" #include "ui/display/screen.h" #include "ui/events/cocoa/cocoa_event_utils.h" #include "ui/events/gesture_detection/gesture_provider_config_helper.h" @@ -417,7 +417,7 @@ const display::DisplayList& displays = browser_compositor_->display_list(); DCHECK(displays.IsValidAndHasPrimaryAndCurrentDisplays()); const display::Display& display = displays.GetCurrentDisplay(); - DisplayUtil::DisplayToScreenInfo(screen_info, display); + display::DisplayUtil::DisplayToScreenInfo(screen_info, display); // Recalculate some ScreenInfo properties from the cached screen info, which // may originate from a remote process that hosts the associated NSWindow. // DisplayToScreenInfo derives some properties from the latest display::Screen
diff --git a/content/browser/service_sandbox_type.h b/content/browser/service_sandbox_type.h index c171548..cce460a 100644 --- a/content/browser/service_sandbox_type.h +++ b/content/browser/service_sandbox_type.h
@@ -17,18 +17,6 @@ // This file maps service classes to sandbox types. See // ServiceProcessHost::Launch() for how these templates are consumed. -// auction_worklet::mojom::AuctionWorkletService -namespace auction_worklet { -namespace mojom { -class AuctionWorkletService; -} -} // namespace auction_worklet -template <> -inline sandbox::policy::SandboxType content::GetServiceSandboxType< - auction_worklet::mojom::AuctionWorkletService>() { - return sandbox::policy::SandboxType::kService; -} - // audio::mojom::AudioService namespace audio { namespace mojom {
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index 4e11f7a..c84e16e 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -147,6 +147,7 @@ // ServiceWorkerContextCoreObserver overrides. void OnVersionStateChanged(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status) override { ASSERT_TRUE( BrowserThread::CurrentlyOn(ServiceWorkerContext::GetCoreThreadId()));
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc index d89b490..cc7fdd0 100644 --- a/content/browser/service_worker/service_worker_context_core.cc +++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -663,7 +663,7 @@ // persisted anything to storage yet. observer_list_->Notify( FROM_HERE, &ServiceWorkerContextCoreObserver::OnRegistrationCompleted, - registration->id(), scope); + registration->id(), scope, key); } void ServiceWorkerContextCore::UpdateComplete( @@ -692,7 +692,7 @@ if (status == blink::ServiceWorkerStatusCode::kOk) { observer_list_->Notify( FROM_HERE, &ServiceWorkerContextCoreObserver::OnRegistrationDeleted, - registration_id, scope); + registration_id, scope, key); } } @@ -734,7 +734,7 @@ live_registrations_[registration->id()] = registration; observer_list_->Notify( FROM_HERE, &ServiceWorkerContextCoreObserver::OnNewLiveRegistration, - registration->id(), registration->scope()); + registration->id(), registration->scope(), registration->key()); } void ServiceWorkerContextCore::RemoveLiveRegistration(int64_t id) { @@ -922,7 +922,7 @@ DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); observer_list_->Notify( FROM_HERE, &ServiceWorkerContextCoreObserver::OnRegistrationStored, - registration_id, scope); + registration_id, scope, key); } void ServiceWorkerContextCore::NotifyAllRegistrationsDeletedForStorageKey( @@ -974,9 +974,9 @@ if (registration) registration->OnNoControllees(version); - observer_list_->Notify(FROM_HERE, - &ServiceWorkerContextCoreObserver::OnNoControllees, - version->version_id(), version->scope()); + observer_list_->Notify( + FROM_HERE, &ServiceWorkerContextCoreObserver::OnNoControllees, + version->version_id(), version->scope(), version->key()); } void ServiceWorkerContextCore::OnControlleeNavigationCommitted( @@ -1010,7 +1010,7 @@ FROM_HERE, &ServiceWorkerContextCoreObserver::OnStarted, version->version_id(), version->scope(), version->embedded_worker()->process_id(), version->script_url(), - version->embedded_worker()->token().value()); + version->embedded_worker()->token().value(), version->key()); break; case EmbeddedWorkerStatus::STOPPING: observer_list_->Notify(FROM_HERE, @@ -1025,7 +1025,8 @@ DCHECK_EQ(this, version->context().get()); observer_list_->Notify( FROM_HERE, &ServiceWorkerContextCoreObserver::OnVersionStateChanged, - version->version_id(), version->scope(), version->status()); + version->version_id(), version->scope(), version->key(), + version->status()); } void ServiceWorkerContextCore::OnDevToolsRoutingIdChanged( @@ -1049,7 +1050,7 @@ DCHECK_EQ(this, version->context().get()); observer_list_->Notify( FROM_HERE, &ServiceWorkerContextCoreObserver::OnErrorReported, - version->version_id(), version->scope(), + version->version_id(), version->scope(), version->key(), ServiceWorkerContextObserver::ErrorInfo(error_message, line_number, column_number, source_url)); } @@ -1076,7 +1077,7 @@ observer_list_->Notify( FROM_HERE, &ServiceWorkerContextCoreObserver::OnReportConsoleMessage, - version->version_id(), version->scope(), + version->version_id(), version->scope(), version->key(), ConsoleMessage(source, message_level, message, line_number, source_url)); }
diff --git a/content/browser/service_worker/service_worker_context_core_observer.h b/content/browser/service_worker/service_worker_context_core_observer.h index 1ebabd8..5351139 100644 --- a/content/browser/service_worker/service_worker_context_core_observer.h +++ b/content/browser/service_worker/service_worker_context_core_observer.h
@@ -19,6 +19,10 @@ #include "third_party/blink/public/mojom/service_worker/service_worker_container_type.mojom.h" #include "url/gurl.h" +namespace blink { +class StorageKey; +} // namespace blink + namespace content { enum class EmbeddedWorkerStatus; @@ -28,7 +32,8 @@ class ServiceWorkerContextCoreObserver { public: virtual void OnNewLiveRegistration(int64_t registration_id, - const GURL& scope) {} + const GURL& scope, + const blink::StorageKey& key) {} virtual void OnNewLiveVersion(const ServiceWorkerVersionInfo& version_info) {} virtual void OnLiveVersionDestroyed(int64_t version_id) {} virtual void OnStarting(int64_t version_id) {} @@ -36,7 +41,8 @@ const GURL& scope, int process_id, const GURL& script_url, - const blink::ServiceWorkerToken& token) {} + const blink::ServiceWorkerToken& token, + const blink::StorageKey& key) {} virtual void OnStopping(int64_t version_id) {} virtual void OnStopped(int64_t version_id) {} // Called when the context core is about to be deleted. After this is called, @@ -46,6 +52,7 @@ virtual void OnDeleteAndStartOver() {} virtual void OnVersionStateChanged(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status status) {} virtual void OnVersionDevToolsRoutingIdChanged(int64_t version_id, int process_id, @@ -56,16 +63,20 @@ virtual void OnErrorReported( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ServiceWorkerContextObserver::ErrorInfo& info) {} virtual void OnReportConsoleMessage(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ConsoleMessage& message) {} virtual void OnControlleeAdded(int64_t version_id, const std::string& uuid, const ServiceWorkerClientInfo& info) {} virtual void OnControlleeRemoved(int64_t version_id, const std::string& uuid) {} - virtual void OnNoControllees(int64_t version_id, const GURL& scope) {} + virtual void OnNoControllees(int64_t version_id, + const GURL& scope, + const blink::StorageKey& key) {} virtual void OnControlleeNavigationCommitted( int64_t version_id, const std::string& uuid, @@ -76,14 +87,16 @@ // storage. The implementation cannot assume that the ServiceWorkerContextCore // will find the registration at this point. virtual void OnRegistrationCompleted(int64_t registration_id, - const GURL& scope) {} + const GURL& scope, + const blink::StorageKey& key) {} // Called after a service worker registration is persisted to storage. // // This happens after OnRegistrationCompleted(). The implementation can assume // that ServiceWorkerContextCore will find the registration, and can safely // add user data to the registration. virtual void OnRegistrationStored(int64_t registration_id, - const GURL& scope) {} + const GURL& scope, + const blink::StorageKey& key) {} // Called after a task has been posted to delete a registration from storage. // This is roughly equivalent to the same time that the promise for @@ -91,7 +104,8 @@ // ServiceWorkerRegistration may still exist, and the deletion operator may // not yet have finished. virtual void OnRegistrationDeleted(int64_t registration_id, - const GURL& scope) {} + const GURL& scope, + const blink::StorageKey& key) {} // Called after all registrations for |origin| are deleted from storage. There // may still be live registrations for this origin in the kUninstalling or @@ -99,6 +113,8 @@ // // This is called after OnRegistrationDeleted(). It is called once // ServiceWorkerRegistry gets confirmation that the delete operation finished. + // TODO(crbug.com/1199077): Refactor to use StorageKey once + // ServiceWorkerContextWrapper::registered_origins_ is refactored. virtual void OnAllRegistrationsDeletedForOrigin(const url::Origin& origin) {} // Notified when the storage corruption recovery is completed and all stored
diff --git a/content/browser/service_worker/service_worker_context_core_unittest.cc b/content/browser/service_worker/service_worker_context_core_unittest.cc index c338b1c..1410703 100644 --- a/content/browser/service_worker/service_worker_context_core_unittest.cc +++ b/content/browser/service_worker/service_worker_context_core_unittest.cc
@@ -151,6 +151,7 @@ // ServiceWorkerContextCoreObserver overrides: void OnVersionStateChanged(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status status) override { if (status == ServiceWorkerVersion::ACTIVATED && scope == scope_for_wait_for_activated_ &&
diff --git a/content/browser/service_worker/service_worker_context_unittest.cc b/content/browser/service_worker/service_worker_context_unittest.cc index ee0dba21..6cc19caa 100644 --- a/content/browser/service_worker/service_worker_context_unittest.cc +++ b/content/browser/service_worker/service_worker_context_unittest.cc
@@ -183,7 +183,8 @@ // ServiceWorkerContextCoreObserver overrides. void OnRegistrationCompleted(int64_t registration_id, - const GURL& scope) override { + const GURL& scope, + const blink::StorageKey& key) override { NotificationLog log; log.type = REGISTRATION_COMPLETED; log.scope = scope; @@ -191,7 +192,8 @@ notifications_.push_back(log); } void OnRegistrationStored(int64_t registration_id, - const GURL& scope) override { + const GURL& scope, + const blink::StorageKey& key) override { NotificationLog log; log.type = REGISTRATION_STORED; log.scope = scope; @@ -199,7 +201,8 @@ notifications_.push_back(log); } void OnRegistrationDeleted(int64_t registration_id, - const GURL& scope) override { + const GURL& scope, + const blink::StorageKey& key) override { NotificationLog log; log.type = REGISTRATION_DELETED; log.scope = scope;
diff --git a/content/browser/service_worker/service_worker_context_watcher.cc b/content/browser/service_worker/service_worker_context_watcher.cc index bffbc77b..d09accae 100644 --- a/content/browser/service_worker/service_worker_context_watcher.cc +++ b/content/browser/service_worker/service_worker_context_watcher.cc
@@ -194,13 +194,12 @@ error_callback_.Run(registration_id, version_id, *error_info.get()); } -void ServiceWorkerContextWatcher::OnNewLiveRegistration(int64_t registration_id, - const GURL& scope) { +void ServiceWorkerContextWatcher::OnNewLiveRegistration( + int64_t registration_id, + const GURL& scope, + const blink::StorageKey& key) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // TODO(crbug.com/1199077): Pipe in StorageKey when it's available in this - // function. - SendRegistrationInfo(registration_id, scope, - blink::StorageKey(url::Origin::Create(scope)), + SendRegistrationInfo(registration_id, scope, key, ServiceWorkerRegistrationInfo::IS_NOT_DELETED); } @@ -231,7 +230,8 @@ const GURL& scope, int process_id, const GURL& script_url, - const blink::ServiceWorkerToken& token) { + const blink::ServiceWorkerToken& token, + const blink::StorageKey& key) { OnRunningStateChanged(version_id, EmbeddedWorkerStatus::RUNNING); } @@ -246,6 +246,7 @@ void ServiceWorkerContextWatcher::OnVersionStateChanged( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, content::ServiceWorkerVersion::Status status) { DCHECK_CURRENTLY_ON(BrowserThread::UI); auto it = version_info_map_.find(version_id); @@ -297,6 +298,7 @@ void ServiceWorkerContextWatcher::OnErrorReported( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ServiceWorkerContextObserver::ErrorInfo& info) { DCHECK_CURRENTLY_ON(BrowserThread::UI); int64_t registration_id = blink::mojom::kInvalidServiceWorkerRegistrationId; @@ -314,6 +316,7 @@ void ServiceWorkerContextWatcher::OnReportConsoleMessage( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ConsoleMessage& message) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (message.message_level != blink::mojom::ConsoleMessageLevel::kError) @@ -360,22 +363,21 @@ void ServiceWorkerContextWatcher::OnRegistrationCompleted( int64_t registration_id, - const GURL& scope) { + const GURL& scope, + const blink::StorageKey& key) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // TODO(crbug.com/1199077): Pipe in StorageKey when it's available in this // function. - SendRegistrationInfo(registration_id, scope, - blink::StorageKey(url::Origin::Create(scope)), + SendRegistrationInfo(registration_id, scope, key, ServiceWorkerRegistrationInfo::IS_NOT_DELETED); } -void ServiceWorkerContextWatcher::OnRegistrationDeleted(int64_t registration_id, - const GURL& scope) { +void ServiceWorkerContextWatcher::OnRegistrationDeleted( + int64_t registration_id, + const GURL& scope, + const blink::StorageKey& key) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - // TODO(crbug.com/1199077): Pipe in StorageKey when it's available in this - // function. - SendRegistrationInfo(registration_id, scope, - blink::StorageKey(url::Origin::Create(scope)), + SendRegistrationInfo(registration_id, scope, key, ServiceWorkerRegistrationInfo::IS_DELETED); }
diff --git a/content/browser/service_worker/service_worker_context_watcher.h b/content/browser/service_worker/service_worker_context_watcher.h index 4b797c5..fa5c084 100644 --- a/content/browser/service_worker/service_worker_context_watcher.h +++ b/content/browser/service_worker/service_worker_context_watcher.h
@@ -85,18 +85,21 @@ // ServiceWorkerContextCoreObserver implements void OnNewLiveRegistration(int64_t registration_id, - const GURL& scope) override; + const GURL& scope, + const blink::StorageKey& key) override; void OnNewLiveVersion(const ServiceWorkerVersionInfo& version_info) override; void OnStarting(int64_t version_id) override; void OnStarted(int64_t version_id, const GURL& scope, int process_id, const GURL& script_url, - const blink::ServiceWorkerToken& token) override; + const blink::ServiceWorkerToken& token, + const blink::StorageKey& key) override; void OnStopping(int64_t version_id) override; void OnStopped(int64_t version_id) override; void OnVersionStateChanged(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status status) override; void OnVersionDevToolsRoutingIdChanged(int64_t version_id, int process_id, @@ -107,9 +110,11 @@ void OnErrorReported( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ServiceWorkerContextObserver::ErrorInfo& info) override; void OnReportConsoleMessage(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ConsoleMessage& message) override; void OnControlleeAdded(int64_t version_id, const std::string& uuid, @@ -117,9 +122,11 @@ void OnControlleeRemoved(int64_t version_id, const std::string& uuid) override; void OnRegistrationCompleted(int64_t registration_id, - const GURL& scope) override; + const GURL& scope, + const blink::StorageKey& key) override; void OnRegistrationDeleted(int64_t registration_id, - const GURL& scope) override; + const GURL& scope, + const blink::StorageKey& key) override; void OnRunningStateChanged(int64_t version_id, EmbeddedWorkerStatus running_status);
diff --git a/content/browser/service_worker/service_worker_context_watcher_unittest.cc b/content/browser/service_worker/service_worker_context_watcher_unittest.cc index 6d43fee..0304a72 100644 --- a/content/browser/service_worker/service_worker_context_watcher_unittest.cc +++ b/content/browser/service_worker/service_worker_context_watcher_unittest.cc
@@ -174,8 +174,9 @@ void ReportError(scoped_refptr<ServiceWorkerContextWatcher> watcher, int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ServiceWorkerContextObserver::ErrorInfo& error_info) { - watcher->OnErrorReported(version_id, scope, error_info); + watcher->OnErrorReported(version_id, scope, key, error_info); } private: @@ -357,7 +358,7 @@ EXPECT_EQ(0u, watcher_callback.errors().size()); std::u16string message(u"HELLO"); - ReportError(watcher, version_id, scope, + ReportError(watcher, version_id, scope, key, ServiceWorkerContextObserver::ErrorInfo(message, 0, 0, script)); base::RunLoop().RunUntilIdle(); ASSERT_EQ(1u, watcher_callback.errors().size()); @@ -410,7 +411,7 @@ int callback_count = watcher_callback.callback_count(); std::u16string message(u"HELLO"); - ReportError(watcher, 0 /*version_id*/, scope, + ReportError(watcher, 0 /*version_id*/, scope, key, ServiceWorkerContextObserver::ErrorInfo(message, 0, 0, script)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(callback_count, watcher_callback.callback_count());
diff --git a/content/browser/service_worker/service_worker_context_wrapper.cc b/content/browser/service_worker/service_worker_context_wrapper.cc index 34c2ad6..5c78f51 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.cc +++ b/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -306,15 +306,18 @@ void ServiceWorkerContextWrapper::OnRegistrationCompleted( int64_t registration_id, - const GURL& scope) { + const GURL& scope, + const blink::StorageKey& key) { DCHECK_CURRENTLY_ON(BrowserThread::UI); for (auto& observer : observer_list_) observer.OnRegistrationCompleted(scope); } -void ServiceWorkerContextWrapper::OnRegistrationStored(int64_t registration_id, - const GURL& scope) { +void ServiceWorkerContextWrapper::OnRegistrationStored( + int64_t registration_id, + const GURL& scope, + const blink::StorageKey& key) { DCHECK_CURRENTLY_ON(BrowserThread::UI); registered_origins_.insert(url::Origin::Create(scope)); @@ -332,6 +335,7 @@ void ServiceWorkerContextWrapper::OnErrorReported( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ServiceWorkerContextObserver::ErrorInfo& info) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -342,6 +346,7 @@ void ServiceWorkerContextWrapper::OnReportConsoleMessage( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ConsoleMessage& message) { DCHECK_CURRENTLY_ON(BrowserThread::UI); @@ -368,8 +373,10 @@ observer.OnControlleeRemoved(version_id, client_uuid); } -void ServiceWorkerContextWrapper::OnNoControllees(int64_t version_id, - const GURL& scope) { +void ServiceWorkerContextWrapper::OnNoControllees( + int64_t version_id, + const GURL& scope, + const blink::StorageKey& key) { DCHECK_CURRENTLY_ON(BrowserThread::UI); for (auto& observer : observer_list_) @@ -392,16 +399,15 @@ const GURL& scope, int process_id, const GURL& script_url, - const blink::ServiceWorkerToken& token) { + const blink::ServiceWorkerToken& token, + const blink::StorageKey& key) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // TODO(crbug.com/1199077): Update this when ServiceWorkerContextCoreObserver // implements StorageKey. auto insertion_result = running_service_workers_.insert(std::make_pair( version_id, - ServiceWorkerRunningInfo(script_url, scope, - blink::StorageKey(url::Origin::Create(scope)), - process_id, token))); + ServiceWorkerRunningInfo(script_url, scope, key, process_id, token))); DCHECK(insertion_result.second); const auto& running_info = insertion_result.first->second; @@ -434,6 +440,7 @@ void ServiceWorkerContextWrapper::OnVersionStateChanged( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status status) { DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/content/browser/service_worker/service_worker_context_wrapper.h b/content/browser/service_worker/service_worker_context_wrapper.h index dbf622d..ccd65d1 100644 --- a/content/browser/service_worker/service_worker_context_wrapper.h +++ b/content/browser/service_worker/service_worker_context_wrapper.h
@@ -116,23 +116,29 @@ // ServiceWorkerContextCoreObserver implementation: void OnRegistrationCompleted(int64_t registration_id, - const GURL& scope) override; + const GURL& scope, + const blink::StorageKey& key) override; void OnRegistrationStored(int64_t registration_id, - const GURL& scope) override; + const GURL& scope, + const blink::StorageKey& key) override; void OnAllRegistrationsDeletedForOrigin(const url::Origin& origin) override; void OnErrorReported( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ServiceWorkerContextObserver::ErrorInfo& info) override; void OnReportConsoleMessage(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ConsoleMessage& message) override; void OnControlleeAdded(int64_t version_id, const std::string& uuid, const ServiceWorkerClientInfo& info) override; void OnControlleeRemoved(int64_t version_id, const std::string& uuid) override; - void OnNoControllees(int64_t version_id, const GURL& scope) override; + void OnNoControllees(int64_t version_id, + const GURL& scope, + const blink::StorageKey& key) override; void OnControlleeNavigationCommitted( int64_t version_id, const std::string& uuid, @@ -141,11 +147,13 @@ const GURL& scope, int process_id, const GURL& script_url, - const blink::ServiceWorkerToken& token) override; + const blink::ServiceWorkerToken& token, + const blink::StorageKey& key) override; void OnStopped(int64_t version_id) override; void OnDeleteAndStartOver() override; void OnVersionStateChanged(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status status) override; // ServiceWorkerContext implementation:
diff --git a/content/browser/service_worker/service_worker_context_wrapper_unittest.cc b/content/browser/service_worker/service_worker_context_wrapper_unittest.cc index 81debfa6..09c29fd 100644 --- a/content/browser/service_worker/service_worker_context_wrapper_unittest.cc +++ b/content/browser/service_worker/service_worker_context_wrapper_unittest.cc
@@ -225,7 +225,8 @@ ASSERT_EQ(StoreRegistration(registration), blink::ServiceWorkerStatusCode::kOk); - wrapper_->OnRegistrationCompleted(registration->id(), registration->scope()); + wrapper_->OnRegistrationCompleted(registration->id(), registration->scope(), + registration->key()); base::RunLoop().RunUntilIdle(); // Now test that a registration is recognized.
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc index d6faccd..0d03429 100644 --- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc +++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -93,7 +93,7 @@ const network::ResourceRequest& request) : client_(std::move(client)), url_(request.url), - devtools_enabled_(request.report_raw_headers) { + devtools_enabled_(request.devtools_request_id.has_value()) { if (!devtools_enabled_) return; AddDevToolsCallback(
diff --git a/content/browser/service_worker/service_worker_internals_ui.cc b/content/browser/service_worker/service_worker_internals_ui.cc index a1b86a7..72f6472 100644 --- a/content/browser/service_worker/service_worker_internals_ui.cc +++ b/content/browser/service_worker/service_worker_internals_ui.cc
@@ -266,7 +266,8 @@ const GURL& scope, int process_id, const GURL& script_url, - const blink::ServiceWorkerToken& token) override { + const blink::ServiceWorkerToken& token, + const blink::StorageKey& key) override { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (handler_) { handler_->OnRunningStateChanged(); @@ -286,6 +287,7 @@ } void OnVersionStateChanged(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status) override { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (handler_) { @@ -295,6 +297,7 @@ void OnErrorReported( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ServiceWorkerContextObserver::ErrorInfo& info) override { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!handler_) { @@ -311,6 +314,7 @@ } void OnReportConsoleMessage(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, const ConsoleMessage& message) override { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!handler_) { @@ -326,14 +330,16 @@ version_id, std::move(details)); } void OnRegistrationCompleted(int64_t registration_id, - const GURL& scope) override { + const GURL& scope, + const blink::StorageKey& key) override { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (handler_) { handler_->OnRegistrationEvent("registration-completed", scope); } } void OnRegistrationDeleted(int64_t registration_id, - const GURL& scope) override { + const GURL& scope, + const blink::StorageKey& key) override { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (handler_) { handler_->OnRegistrationEvent("registration-deleted", scope);
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc index 14de8af..72723472 100644 --- a/content/browser/service_worker/service_worker_job_unittest.cc +++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -1436,6 +1436,7 @@ // ServiceWorkerContextCoreObserver overrides void OnVersionStateChanged(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status status) override { StateChangeLogEntry entry; entry.version_id = version_id;
diff --git a/content/browser/service_worker/service_worker_version_browsertest.cc b/content/browser/service_worker/service_worker_version_browsertest.cc index 687270f..9b89de45 100644 --- a/content/browser/service_worker/service_worker_version_browsertest.cc +++ b/content/browser/service_worker/service_worker_version_browsertest.cc
@@ -156,6 +156,7 @@ // ServiceWorkerContextCoreObserver overrides. void OnVersionStateChanged(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status) override { ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI)); const ServiceWorkerVersion* version = context_->GetLiveVersion(version_id);
diff --git a/content/browser/service_worker/test_service_worker_observer.cc b/content/browser/service_worker/test_service_worker_observer.cc index 288ac82..c699556 100644 --- a/content/browser/service_worker/test_service_worker_observer.cc +++ b/content/browser/service_worker/test_service_worker_observer.cc
@@ -52,6 +52,7 @@ void TestServiceWorkerObserver::OnVersionStateChanged( int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status status) { if (version_id == version_id_for_status_change_ && status == status_for_status_change_ && quit_closure_for_status_change_) {
diff --git a/content/browser/service_worker/test_service_worker_observer.h b/content/browser/service_worker/test_service_worker_observer.h index c4de11f9c..09b8b0ca 100644 --- a/content/browser/service_worker/test_service_worker_observer.h +++ b/content/browser/service_worker/test_service_worker_observer.h
@@ -14,6 +14,10 @@ class TestSimpleTaskRunner; } +namespace blink { +class StorageKey; +} // namespace blink + namespace content { class ServiceWorkerContextWrapper; @@ -42,6 +46,7 @@ // ServiceWorkerContextCoreObserver overrides: void OnVersionStateChanged(int64_t version_id, const GURL& scope, + const blink::StorageKey& key, ServiceWorkerVersion::Status status) override; scoped_refptr<ServiceWorkerContextWrapper> wrapper_;
diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc index bb74220..feb08bbc 100644 --- a/content/browser/web_contents/web_contents_view_android.cc +++ b/content/browser/web_contents/web_contents_view_android.cc
@@ -15,7 +15,6 @@ #include "content/browser/android/gesture_listener_manager.h" #include "content/browser/android/select_popup.h" #include "content/browser/android/selection/selection_popup_controller.h" -#include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/render_view_host_factory.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_android.h" @@ -31,6 +30,7 @@ #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/clipboard_constants.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h" +#include "ui/display/display_util.h" #include "ui/display/screen.h" #include "ui/events/android/drag_event_android.h" #include "ui/events/android/gesture_event_android.h"
diff --git a/content/browser/web_contents/web_contents_view_child_frame.cc b/content/browser/web_contents/web_contents_view_child_frame.cc index cd3dac7..70a31ea9 100644 --- a/content/browser/web_contents/web_contents_view_child_frame.cc +++ b/content/browser/web_contents/web_contents_view_child_frame.cc
@@ -5,13 +5,13 @@ #include "content/browser/web_contents/web_contents_view_child_frame.h" #include "build/build_config.h" -#include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/render_frame_proxy_host.h" #include "content/browser/renderer_host/render_widget_host_view_child_frame.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/web_contents_view_delegate.h" #include "third_party/blink/public/mojom/input/focus_type.mojom.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h" +#include "ui/display/display_util.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" @@ -83,7 +83,7 @@ if (auto* view = web_contents_->GetRenderWidgetHostView()) view->GetScreenInfo(&screen_info); else - DisplayUtil::GetDefaultScreenInfo(&screen_info); + display::DisplayUtil::GetDefaultScreenInfo(&screen_info); return RenderWidgetHostViewChildFrame::Create(render_widget_host, screen_info); }
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm index 7f103e64..44c10f5 100644 --- a/content/browser/web_contents/web_contents_view_mac.mm +++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -21,7 +21,6 @@ #import "content/app_shim_remote_cocoa/web_contents_view_cocoa.h" #include "content/browser/download/drag_download_file.h" #include "content/browser/download/drag_download_util.h" -#include "content/browser/renderer_host/display_util.h" #include "content/browser/renderer_host/popup_menu_helper_mac.h" #include "content/browser/renderer_host/render_view_host_factory.h" #include "content/browser/renderer_host/render_view_host_impl.h" @@ -35,6 +34,7 @@ #include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "ui/base/cocoa/cocoa_base_utils.h" #include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h" +#include "ui/display/display_util.h" #include "ui/gfx/mac/coordinate_conversion.h" using blink::DragOperationsMask;
diff --git a/content/browser/web_package/prefetched_signed_exchange_cache.cc b/content/browser/web_package/prefetched_signed_exchange_cache.cc index d863396..10a3afb 100644 --- a/content/browser/web_package/prefetched_signed_exchange_cache.cc +++ b/content/browser/web_package/prefetched_signed_exchange_cache.cc
@@ -197,11 +197,11 @@ DCHECK(request.request_initiator); // Keep the SSLInfo only when the request is for main frame main resource, - // or report_raw_headers is set. Users can inspect the certificate for the + // or devtools_request_id is set. Users can inspect the certificate for the // main frame using the info bubble in Omnibox, and for the subresources in // DevTools' Security panel. if (request.destination != network::mojom::RequestDestination::kDocument && - !request.report_raw_headers) { + !request.devtools_request_id) { response_->ssl_info = absl::nullopt; } UpdateRequestResponseStartTime(response_.get());
diff --git a/content/browser/web_package/signed_exchange_prefetch_handler.cc b/content/browser/web_package/signed_exchange_prefetch_handler.cc index e2ca4db..1a5d51a 100644 --- a/content/browser/web_package/signed_exchange_prefetch_handler.cc +++ b/content/browser/web_package/signed_exchange_prefetch_handler.cc
@@ -49,7 +49,7 @@ auto devtools_proxy = std::make_unique<SignedExchangeDevToolsProxy>( resource_request.url, response_head.Clone(), frame_tree_node_id, absl::nullopt /* devtools_navigation_token */, - resource_request.report_raw_headers); + resource_request.devtools_request_id.has_value()); signed_exchange_loader_ = std::make_unique<SignedExchangeLoader>( resource_request, std::move(response_head), std::move(response_body), loader_client_receiver_.BindNewPipeAndPassRemote(), std::move(endpoints),
diff --git a/content/browser/web_package/signed_exchange_request_handler.cc b/content/browser/web_package/signed_exchange_request_handler.cc index 095a647b..7e4a4ec 100644 --- a/content/browser/web_package/signed_exchange_request_handler.cc +++ b/content/browser/web_package/signed_exchange_request_handler.cc
@@ -109,7 +109,7 @@ network_isolation_key, frame_tree_node_id_); auto devtools_proxy = std::make_unique<SignedExchangeDevToolsProxy>( request.url, response_head->Clone(), frame_tree_node_id_, - devtools_navigation_token_, request.report_raw_headers); + devtools_navigation_token_, request.devtools_request_id.has_value()); signed_exchange_loader_ = std::make_unique<SignedExchangeLoader>( request, std::move(*response_head), std::move(*response_body), std::move(client), url_loader->Unbind(), url_loader_options_,
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java index 64e4f01..b349942d 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java
@@ -566,6 +566,7 @@ @Override public void onShowKeyboardReceiveResult(int resultCode) { + if (!isValid()) return; View containerView = getContainerView(); if (resultCode == InputMethodManager.RESULT_SHOWN) { // If OSK is newly shown, delay the form focus until
diff --git a/content/public/test/DEPS b/content/public/test/DEPS index c269755..17d68a5 100644 --- a/content/public/test/DEPS +++ b/content/public/test/DEPS
@@ -11,7 +11,7 @@ "+content/public", "+components/discardable_memory/service", "+components/download/public/common", - "+components/enterprise/common/proto", + "+components/enterprise/common/download_item_reroute_info.h", "+components/leveldb_proto/public", "+components/services/storage/public", "+components/viz/client",
diff --git a/content/public/test/fake_download_item.h b/content/public/test/fake_download_item.h index e81ee45..550b6a2 100644 --- a/content/public/test/fake_download_item.h +++ b/content/public/test/fake_download_item.h
@@ -15,7 +15,7 @@ #include "components/download/public/common/download_interrupt_reasons.h" #include "components/download/public/common/download_item.h" #include "components/download/public/common/download_source.h" -#include "components/enterprise/common/proto/download_item_reroute_info.pb.h" +#include "components/enterprise/common/download_item_reroute_info.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/base/page_transition_types.h" #include "url/gurl.h"
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc index eb77d14..a12cf36 100644 --- a/content/renderer/service_worker/service_worker_subresource_loader.cc +++ b/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -637,11 +637,9 @@ void ServiceWorkerSubresourceLoader::RecordTimingMetrics(bool handled) { DCHECK(fetch_event_timing_); - // |report_raw_headers| is true when DevTools is attached. Don't record + // |devtools_request_id| is set when DevTools is attached. Don't record // metrics when DevTools is attached to reduce noise. - // TODO(bashi): Relying on |report_raw_header| to detect DevTools existence - // is brittle. Figure out a better way to check DevTools is attached. - if (resource_request_.report_raw_headers) + if (resource_request_.devtools_request_id.has_value()) return; // |fetch_event_timing_| can be recorded in different process. We can get
diff --git a/content/services/auction_worklet/public/mojom/BUILD.gn b/content/services/auction_worklet/public/mojom/BUILD.gn index 7627b86..9eeb9c0 100644 --- a/content/services/auction_worklet/public/mojom/BUILD.gn +++ b/content/services/auction_worklet/public/mojom/BUILD.gn
@@ -13,6 +13,7 @@ ] deps = [ "//mojo/public/mojom/base", + "//sandbox/policy/mojom", "//services/network/public/mojom", "//third_party/blink/public/mojom:mojom_platform", "//url/mojom:url_mojom_gurl",
diff --git a/content/services/auction_worklet/public/mojom/auction_worklet_service.mojom b/content/services/auction_worklet/public/mojom/auction_worklet_service.mojom index c3440ce..e077deb5 100644 --- a/content/services/auction_worklet/public/mojom/auction_worklet_service.mojom +++ b/content/services/auction_worklet/public/mojom/auction_worklet_service.mojom
@@ -7,6 +7,7 @@ import "content/services/auction_worklet/public/mojom/bidder_worklet.mojom"; import "content/services/auction_worklet/public/mojom/seller_worklet.mojom"; import "mojo/public/mojom/base/time.mojom"; +import "sandbox/policy/mojom/sandbox.mojom"; import "services/network/public/mojom/url_loader_factory.mojom"; import "third_party/blink/public/mojom/interest_group/interest_group_types.mojom"; import "url/mojom/origin.mojom"; @@ -20,6 +21,7 @@ // Used by the browser to load and run FLEDGE worklets in a sandboxed utility // process. // See https://github.com/WICG/turtledove/blob/main/FLEDGE.md +[ServiceSandbox=sandbox.mojom.Sandbox.kService] interface AuctionWorkletService { // Loads a FLEDGE bidder worklet, its same-origin realtime bidding signals // URL (if necessary), and invokes its generateBid() method, returning
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index a9b3997..345e561d 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -538,9 +538,11 @@ } } - if (is_win || is_linux || is_chromeos) { + if (is_win) { data_deps += [ "//third_party/crashpad/crashpad/handler:crashpad_handler" ] + } else if (is_linux || is_chromeos) { + data_deps += [ "//components/crash/core/app:chrome_crashpad_handler" ] } if ((is_linux || is_chromeos) && !is_component_build) {
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 31ed6d4..b557efb 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -406,7 +406,7 @@ public_deps = [ ":test_interfaces", "//components/download/public/common:test_support", - "//components/enterprise/common/proto:download_item_reroute_info_proto", + "//components/enterprise/common:download_item_reroute_info", "//components/services/filesystem/public/mojom", "//components/services/storage/public/cpp", "//components/services/storage/public/mojom", @@ -1351,9 +1351,7 @@ defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] - configs += [ - "//build/config:precompiled_headers", - ] + configs += [ "//build/config:precompiled_headers" ] public_deps = [ ":test_interfaces",
diff --git a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-android.txt b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-android.txt index 07195b46..454f722e0 100644 --- a/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-android.txt +++ b/content/test/data/accessibility/aria/aria-menuitem-in-group-expected-android.txt
@@ -1,3 +1,3 @@ android.webkit.WebView focusable focused scrollable ++android.view.View -++++android.view.MenuItem role_description='menu item' clickable focusable name='Menu button' \ No newline at end of file +++++android.view.MenuItem role_description='menu item' clickable focusable name='Menu item' \ No newline at end of file
diff --git a/content/test/data/accessibility/html/select-expected-android.txt b/content/test/data/accessibility/html/select-expected-android.txt index 4b9a347..a0affc17 100644 --- a/content/test/data/accessibility/html/select-expected-android.txt +++ b/content/test/data/accessibility/html/select-expected-android.txt
@@ -1,11 +1,11 @@ android.webkit.WebView focusable focused scrollable ++android.view.View -++++android.widget.Spinner role_description='pop up button' clickable focusable name='Placeholder option' -++++android.widget.Spinner role_description='pop up button' clickable focusable name='Option 2' -++++android.widget.Spinner role_description='pop up button' clickable focusable name='Option 1' -++++android.widget.Spinner role_description='pop up button' clickable focusable multiselectable name='0 selected' state_description='multiselectable, none selected.' -++++android.widget.Spinner role_description='pop up button' clickable focusable -++++++android.view.View clickable invisible +++++android.view.View role_description='menu pop up button' clickable collapsed focusable name='Placeholder option' +++++android.view.View role_description='menu pop up button' clickable collapsed focusable name='Option 2' +++++android.view.View role_description='menu pop up button' clickable collapsed focusable name='Option 1' +++++android.view.View role_description='menu pop up button' clickable collapsed focusable multiselectable name='0 selected' +++++android.view.View role_description='menu pop up button' clickable collapsed focusable +++++++android.view.View invisible ++++++++android.view.View clickable focusable invisible name='Option 1' ++++++++android.view.View clickable focusable invisible name='Option 2' item_index=1 row_index=1 ++++++++android.view.View clickable focusable invisible name='Option 3' item_index=2 row_index=2 \ No newline at end of file
diff --git a/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py b/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py index 1186c5a..5d67413 100644 --- a/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py +++ b/content/test/gpu/gpu_tests/skia_gold_integration_test_base.py
@@ -411,7 +411,10 @@ 'Given unhandled SkiaGoldSession StatusCode %s with error %s', status, error) if self._ShouldReportGoldFailure(page): - raise Exception('goldctl command failed, see above for details') + raise Exception( + 'goldctl command returned non-zero exit code, see above for details. ' + 'This probably just means that the test produced an image that has ' + 'not been triaged as positive.') def _ShouldReportGoldFailure(self, page): """Determines if a Gold failure should actually be surfaced.
diff --git a/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt index 39245d19..6dbc078 100644 --- a/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt
@@ -93,6 +93,10 @@ # Flakily hits a DCHECK during shared image creation. crbug.com/1188437 [ linux intel display-server-wayland ] GpuProcess_webgl [ RetryOnFailure ] +# Test timeout +crbug.com/1183940 [ android-nexus-5 ] GpuProcess_visibility [ Failure ] +crbug.com/1183940 [ android-nexus-6 ] GpuProcess_visibility [ Failure ] + ####################################################################### # Automated Entries After This Point - Do Not Manually Add Below Here # #######################################################################
diff --git a/device/gamepad/gamepad_device_linux.cc b/device/gamepad/gamepad_device_linux.cc index 4a28e10..6798042 100644 --- a/device/gamepad/gamepad_device_linux.cc +++ b/device/gamepad/gamepad_device_linux.cc
@@ -233,6 +233,11 @@ } #endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) +// Small helper to avoid constructing a StringPiece from nullptr. +base::StringPiece ToStringPiece(const char* str) { + return str ? base::StringPiece(str) : base::StringPiece(); +} + } // namespace GamepadDeviceLinux::GamepadDeviceLinux( @@ -442,13 +447,13 @@ device, kInputSubsystem, nullptr); const base::StringPiece vendor_id = - udev_device_get_sysattr_value(parent_device, "id/vendor"); + ToStringPiece(udev_device_get_sysattr_value(parent_device, "id/vendor")); const base::StringPiece product_id = - udev_device_get_sysattr_value(parent_device, "id/product"); + ToStringPiece(udev_device_get_sysattr_value(parent_device, "id/product")); const base::StringPiece hid_version = - udev_device_get_sysattr_value(parent_device, "id/version"); + ToStringPiece(udev_device_get_sysattr_value(parent_device, "id/version")); const base::StringPiece name = - udev_device_get_sysattr_value(parent_device, "name"); + ToStringPiece(udev_device_get_sysattr_value(parent_device, "name")); uint16_t vendor_id_int = HexStringToUInt16WithDefault(vendor_id, 0); uint16_t product_id_int = HexStringToUInt16WithDefault(product_id, 0); @@ -465,9 +470,9 @@ std::string name_string(name); if (usb_device) { const base::StringPiece usb_vendor_id = - udev_device_get_sysattr_value(usb_device, "idVendor"); + ToStringPiece(udev_device_get_sysattr_value(usb_device, "idVendor")); const base::StringPiece usb_product_id = - udev_device_get_sysattr_value(usb_device, "idProduct"); + ToStringPiece(udev_device_get_sysattr_value(usb_device, "idProduct")); if (vendor_id == usb_vendor_id && product_id == usb_product_id) { const char* manufacturer = @@ -483,7 +488,7 @@ } const base::StringPiece version_number = - udev_device_get_sysattr_value(usb_device, "bcdDevice"); + ToStringPiece(udev_device_get_sysattr_value(usb_device, "bcdDevice")); version_number_int = HexStringToUInt16WithDefault(version_number, 0); }
diff --git a/docs/gpu/pixel_wrangling.md b/docs/gpu/pixel_wrangling.md index f1ba7b54..ca18a706 100644 --- a/docs/gpu/pixel_wrangling.md +++ b/docs/gpu/pixel_wrangling.md
@@ -1,336 +1,7 @@ # GPU Bots & Pixel Wrangling - +GPU Pixel Wrangling is the process of keeping various GPU bots green. On the GPU bots, tests run on physical hardware with real GPUs, not in VMs like the majority of the bots on the Chromium waterfall. -(December 2017: presentation on GPU bots and pixel wrangling: see [slides].) +Wrangling document has moved. See [GPU Pixel +Wrangler](http://goto.google.com/gpu-pixel-wrangler). -GPU Pixel Wrangling is the process of keeping various GPU bots green. On the -GPU bots, tests run on physical hardware with real GPUs, not in VMs like the -majority of the bots on the Chromium waterfall. - -[slides]: https://docs.google.com/presentation/d/1sZjyNe2apUhwr5sinRfPs7eTzH-3zO0VQ-Cj-8DlEDQ/edit?usp=sharing - -[TOC] - -## Fleet Status - -* [Chrome GPU Fleet Status](http://vi/chrome-infra/Projects/gpu) - -(Sorry, this link is Google internal only.) - -These graphs show 1 day of activity by default. The drop-down boxes at the top -allow viewing of longer durations. - -See [this CL](http://cl/238562533) for an example of how to update these graphs. - -## GPU Bots' Waterfalls - -The waterfalls work much like any other; see the [Tour of the Chromium Buildbot -Waterfall] for a more detailed explanation of how this is laid out. We have -more subtle configurations because the GPU matters, not just the OS and release -v. debug. Hence we have Windows Nvidia Release bots, Mac Intel Debug bots, and -so on. The waterfalls we’re interested in are: - -* [Chromium GPU] - * Various operating systems, configurations, GPUs, etc. -* [Chromium GPU FYI] - * These bots run less-standard configurations like Windows with AMD GPUs, - Linux with Intel GPUs, etc. - * These bots build with top of tree ANGLE rather than the `DEPS` version. - * The [ANGLE tryservers] help ensure that these bots stay green. However, - it is possible that due to ANGLE changes these bots may be red while - the chromium.gpu bots are green. - * The [ANGLE Wrangler] is on-call to help resolve ANGLE-related breakage - on this watefall. - * To determine if a different ANGLE revision was used between two builds, - compare the `got_angle_revision` buildbot property on the GPU builders - or `parent_got_angle_revision` on the testers. This revision can be - used to do a `git log` in the `third_party/angle` repository. -* [Chromium SwANGLE] - * These bots run GPU tests on top of ANGLE's GLES implementation running - on top of SwiftShader's Vulkan implementation purely in software. - Regressions should mostly be handled by the [ANGLE Wrangler], but some - failures fall into Pixel Wrangler's domain, for example, WebGL failures - due to Chromium-side and WebGL-side changes on - linux-swangle-chromium-x64, mac-swangle-chromium-x64 and - win-swangle-chromium-x86 bots. - -<!-- TODO(kainino): update link when the page is migrated --> -[Tour of the Chromium Buildbot Waterfall]: http://www.chromium.org/developers/testing/chromium-build-infrastructure/tour-of-the-chromium-buildbot -[Chromium GPU]: https://ci.chromium.org/p/chromium/g/chromium.gpu/console?reload=120 -[Chromium GPU FYI]: https://ci.chromium.org/p/chromium/g/chromium.gpu.fyi/console?reload=120 -[Chromium SwANGLE]: https://ci.chromium.org/p/chromium/g/chromium.swangle/console?reload=120 -[ANGLE tryservers]: https://build.chromium.org/p/tryserver.chromium.angle/waterfall -[ANGLE Wrangler]: https://chromium.googlesource.com/angle/angle/+/main/infra/ANGLEWrangling.md - -## Test Suites - -The bots run several test suites. The majority of them have been migrated to -the Telemetry harness, and are run within the full browser, in order to better -test the code that is actually shipped. As of this writing, the tests included: - -* Tests using the Telemetry harness: - * The WebGL conformance tests: `webgl_conformance_integration_test.py` - * A Google Maps test: `maps_integration_test.py` - * Context loss tests: `context_lost_integration_test.py` - * Depth capture tests: `depth_capture_integration_test.py` - * GPU process launch tests: `gpu_process_integration_test.py` - * Hardware acceleration validation tests: - `hardware_accelerated_feature_integration_test.py` - * Pixel tests validating the end-to-end rendering pipeline: - `pixel_integration_test.py` - * Stress tests of the screenshot functionality other tests use: - `screenshot_sync_integration_test.py` -* `angle_unittests`: see `src/third_party/angle/src/tests/BUILD.gn` -* drawElements tests (on the chromium.gpu.fyi waterfall): see - `src/third_party/angle/src/tests/BUILD.gn` -* `gles2_conform_test` (requires internal sources): see - `src/gpu/gles2_conform_support/BUILD.gn` -* `gl_tests`: see `src/gpu/BUILD.gn` -* `gl_unittests`: see `src/ui/gl/BUILD.gn` -* `rendering_representative_perf_tests` (on the chromium.gpu.fyi waterfall): - see `src/chrome/test/BUILD.gn` - -And more. See -[`src/testing/buildbot/README.md`](../../testing/buildbot/README.md) -and the GPU sections of `test_suites.pyl` and `waterfalls.pyl` for the -complete description of bots and tests. - -Additionally, the Release bots run: - -* `tab_capture_end2end_tests:` see - `src/chrome/browser/extensions/api/tab_capture/tab_capture_apitest.cc` and - `src/chrome/browser/extensions/api/cast_streaming/cast_streaming_apitest.cc` - -### More Details - -More details about the bots' setup can be found on the [GPU Testing] page. - -[GPU Testing]: https://sites.google.com/a/chromium.org/dev/developers/testing/gpu-testing - -## Wrangling - -### Prerequisites - -1. Ideally a wrangler should be a Chromium committer. If you're on the GPU -pixel wrangling rotation, there will be an email notifying you of the upcoming -shift, and a calendar appointment. - * If you aren't a committer, don't panic. It's still best for everyone on - the team to become acquainted with the procedures of maintaining the - GPU bots. - * In this case you'll upload CLs to Gerrit to perform reverts (optionally - using the new "Revert" button in the UI), and might consider using - `Tbr:` to speed through trivial and urgent CLs. In general, try to send - all CLs through the commit queue. - * Contact bajones, kainino, kbr, vmiura, zmo, or another member of the - Chrome GPU team who's already a committer for help landing patches or - reverts during your shift. -1. Apply for [access to the bots]. -1. You may want to install the [Flake linker] extension, which adds several useful features to the bot build log pages. - * Links to Chromium flakiness dashboard from build result pages, so you can see all failures for a single test across the fleet. - * Automatically hides green build steps so you can see the failure immediately. - * Turns build log links into deep links directly to the failure line in the log. - -[access to the bots]: https://sites.google.com/a/google.com/chrome-infrastructure/golo/remote-access?pli=1 -[Flake linker]: https://chrome.google.com/webstore/detail/flake-linker/boamnmbgmfnobomddmenbaicodgglkhc - -### How to Keep the Bots Green - -1. Watch for redness on the tree. - 1. [Sheriff-O-Matic] now has support for all the - [GPU Bots' Waterfalls](#GPU-Bots_Waterfalls) under the - [Chromium GPU][Sheriff-O-Matic] tab! - 1. The bots are expected to be green all the time. Flakiness on these bots - is neither expected nor acceptable. - 1. If a bot goes consistently red, it's necessary to figure out whether a - recent CL caused it, or whether it's a problem with the bot or - infrastructure. - 1. If it looks like a problem with the bot (deep problems like failing to - check out the sources, the isolate server failing, etc.) notify the - Chromium troopers and file a P1 bug with labels: Infra\>Labs, - Infra\>Troopers and Internals\>GPU\>Testing. See the general [tree - sheriffing page] for more details. - 1. Otherwise, examine the builds just before and after the redness was - introduced. Look at the revisions in the builds before and after the - failure was introduced. - 1. **File a bug** capturing the regression range and excerpts of any - associated logs. Regressions should be marked P1. CC engineers who you - think may be able to help triage the issue. Keep in mind that the logs - on the bots expire after a few days, so make sure to add copies of - relevant logs to the bug report. - 1. Use the `Hotlist=PixelWrangler` label to mark bugs that require the - pixel wrangler's attention, so it's easy to find relevant bugs when - handing off shifts. - 1. Study the regression range carefully. Use drover to revert any CLs - which break the chromium.gpu bots. Use your judgment about - chromium.gpu.fyi, since not all bots are covered by trybots. In the - revert message, provide a clear description of what broke, links to - failing builds, and excerpts of the failure logs, because the build - logs expire after a few days. - 1. If the failure is one that you believe should have been caught by an - optional GPU trybot, you can use the script at - [`//content/test/gpu/trim_culprit_cls.py`][trim culprit cls] to help - trim down the blamelist by finding out which CLs passed said trybot - before submission. See the documentation at the top of the script for - example usage, etc. -1. Make sure the bots are running jobs. - 1. Keep an eye on the console views of the various bots. - 1. Make sure the bots are all actively processing jobs. If they go offline - for a long period of time, the "summary bubble" at the top may still be - green, but the column in the console view will be gray. - 1. Email the Chromium troopers if you find a bot that's not processing - jobs. -1. Make sure the GPU try servers are in good health. - 1. The GPU try servers are no longer distinct bots on a separate - waterfall, but instead run as part of the regular tryjobs on the - Chromium waterfalls. The GPU tests run as part of the following - tryservers' jobs: - 1. `[linux-rel]` on the [luci.chromium.try] waterfall - 1. `[mac-rel]` on the [luci.chromium.try] waterfall - 1. `[win7-rel]` on the [luci.chromium.try] waterfall - 1. The best tool to use to quickly find flakiness on the tryservers is the - new [Chromium Try Flakes] tool. Look for the names of GPU tests (like - maps_pixel_test) as well as the test machines (e.g. mac-rel). If you - see a flaky test, file a bug like [this one](http://crbug.com/444430). - Also look for compile flakes that may indicate that a bot needs to be - clobbered. Contact the Chromium sheriffs or troopers if so. - 1. Glance at these trybots from time to time and see if any GPU tests are - failing frequently. **Note** that test failures are **expected** on - these bots: individuals' patches may fail to apply, fail to compile, or - break various tests. Look specifically for patterns in the failures. It - isn't necessary to spend a lot of time investigating each individual - failure. (Use the "Show: 200" link at the bottom of the page to see - more history.) - 1. If the same set of tests are failing repeatedly, look at the individual - runs. Examine the swarming results and see whether they're all running - on the same machine. (This is the "Bot assigned to task" when clicking - any of the test's shards in the build logs.) If they are, something - might be wrong with the hardware. Use the [Swarming Server Stats] tool - to drill down into the specific builder. - 1. If you see the same test failing in a flaky manner across multiple - machines and multiple CLs, it's crucial to investigate why it's - happening. [crbug.com/395914](http://crbug.com/395914) was one example - of an innocent-looking Blink change which made it through the commit - queue and introduced widespread flakiness in a range of GPU tests. The - failures were also most visible on the try servers as opposed to the - main waterfalls. -1. Check if any pixel test failures are actual failures or need to be - rebaselined. - 1. For a given build failing the pixel tests, look for either: - 1. One or more links named `gold_triage_link for <test name>`. This will - be the case if there are fewer than 10 links. If the test was run on - a trybot, the link will instead be named - `triage_link_for_entire_cl for <test name>` (the weird naming comes - with how the recipe processes and displays links). - 1. A single link named - `Too many artifacts produced to link individually, click for links`. - This will be the case if there are 10 or more links. - 1. In either case, follow the link(s) to the triage page for the image the - failing test produced. - 1. If the test was run on a trybot, all the links will point to the same - page, which will be the triage page for every untriaged image - produced by the CL being tested. - 1. Ensure you are signed in to the Gold server the links take you to (both - @google.com and @chromium.org accounts work). - 1. Triage images on those pages (typically by approving them, but you can - mark them as negative if it is an image that should not be produced). In - the case of a negative image, a bug should be filed on - [crbug](https://crbug.com) to investigate and fix the cause of that - particular image being produced, as future occurrences of it will cause - the test to fail. Such bugs should include the `Internals>GPU>Testing` - component and whatever component is suitable for the type of failing - test (likely `Blink>WebGL` or `Blink>Canvas`). The test should also be - marked as failing or skipped(see the item below on updating the - Telemetry-based test expectations) so that the test failure doesn't show - up as a builder failure. If the failure is consistent, prefer to skip - instead of mark as failing so that the failure links don't pile up. If - the failure occurs on the trybots, include the change to the - expectations in your CL. - 1. Additional, less common triage steps for the pixel tests can be found in - [this section][gold less common failures] of the GPU Gold documentation. -1. Update Telemetry-based test expectations if necessary. - 1. Most of the GPU tests are run inside a full Chromium browser, launched - by Telemetry, rather than a Gtest harness. The tests and their - expectations are contained in [src/content/test/gpu/gpu_tests/test_expectations] . See - for example <code>[webgl_conformance_expectations.txt]</code>, - <code>[gpu_process_expectations.txt]</code> and - <code>[pixel_expectations.txt]</code>. - 1. See the header of the file a list of modifiers to specify a bot - configuration. It is possible to specify OS (down to a specific - version, say, Windows 7 or Mountain Lion), GPU vendor - (NVIDIA/AMD/Intel), and a specific GPU device. - 1. The key is to maintain the highest coverage: if you have to disable a - test, disable it only on the specific configurations it's failing. Note - that it is not possible to discern between Debug and Release - configurations. - 1. Mark tests failing or skipped, which will suppress flaky failures, only - as a last resort. It is only really necessary to suppress failures that - are showing up on the GPU tryservers, since failing tests no longer - close the Chromium tree. - 1. Please read the section on [stamping out flakiness] for motivation on - how important it is to eliminate flakiness rather than hiding it. - 1. For failures of rendering_representative_perf_tests please refer to its - [instructions on updating expectations][rendering_representative_perf_tests]. - 1. It's always better to have the CL reviewed properly, but for urgent - suppressions when no reviewer is available, it is possible to rubber - stamp the CL via adding `rubber-stamper@appspot.gserviceaccount.com` as - your reviewer, in addition to the regular reviewer. -1. For the remaining Gtest-style tests, use the [`DISABLED_` - modifier][gtest-DISABLED] to suppress any failures if necessary. - -[Sheriff-O-Matic]: https://sheriff-o-matic.appspot.com/chromium.gpu -[trim culprit cls]: https://source.chromium.org/chromium/chromium/src/+/main:content/test/gpu/trim_culprit_cls.py -[tree sheriffing page]: https://sites.google.com/a/chromium.org/dev/developers/tree-sheriffs -[linux-rel]: https://ci.chromium.org/p/chromium/builders/luci.chromium.try/linux-rel -[luci.chromium.try]: https://ci.chromium.org/p/chromium/g/luci.chromium.try/builders -[mac-rel]: https://ci.chromium.org/p/chromium/builders/luci.chromium.try/mac-rel -[tryserver.chromium.mac]: https://ci.chromium.org/p/chromium/g/tryserver.chromium.mac/builders -[win7-rel]: -https://ci.chromium.org/p/chromium/builders/luci.chromium.try/win7-rel -[tryserver.chromium.win]: https://ci.chromium.org/p/chromium/g/tryserver.chromium.win/builders -[Chromium Try Flakes]: http://chromium-try-flakes.appspot.com/ -<!-- TODO(kainino): link doesn't work, but is still included from chromium-swarm homepage so not removing it now --> -[Swarming Server Stats]: https://chromium-swarm.appspot.com/stats -[gold less common failures]: gpu_pixel_testing_with_gold.md#Triaging-Less-Common-Failures -[Chrome Internal GPU Pixel Wrangling Instructions]: https://sites.google.com/a/google.com/client3d/documents/chrome-internal-gpu-pixel-wrangling-instructions -[src/content/test/gpu/gpu_tests/test_expectations]: https://chromium.googlesource.com/chromium/src/+/main/content/test/gpu/gpu_tests/test_expectations -[webgl_conformance_expectations.txt]: https://chromium.googlesource.com/chromium/src/+/main/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt -[gpu_process_expectations.txt]: https://chromium.googlesource.com/chromium/src/+/main/content/test/gpu/gpu_tests/test_expectations/gpu_process_expectations.txt -[pixel_expectations.txt]: https://chromium.googlesource.com/chromium/src/+/main/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt -[stamping out flakiness]: gpu_testing.md#Stamping-out-Flakiness -[gtest-DISABLED]: https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#temporarily-disabling-tests -[rendering_representative_perf_tests]: ../testing/rendering_representative_perf_tests.md#Updating-Expectations - -### When Bots Misbehave (SSHing into a bot) - -1. See the [Chrome Internal GPU Pixel Wrangling Instructions] for information - on ssh'ing in to the GPU bots. - -[Chrome Internal GPU Pixel Wrangling Instructions]: https://sites.google.com/a/google.com/client3d/documents/chrome-internal-gpu-pixel-wrangling-instructions - -### Reproducing WebGL conformance test failures locally - -1. From the buildbot build output page, click on the failed shard to get to - the swarming task page. Scroll to the bottom of the left panel for a - command to run the task locally. This will automatically download the build - and any other inputs needed. -2. Alternatively, to run the test on a local build, pass the arguments - `--browser=exact --browser-executable=/path/to/binary` to - `content/test/gpu/run_gpu_integration_test.py`. - Also see the [telemetry documentation]. - -[telemetry documentation]: https://cs.chromium.org/chromium/src/third_party/catapult/telemetry/docs/run_benchmarks_locally.md - -## Modifying the GPU Pixel Wrangling Rotation - -You may find yourself needing to modify the current rotation. Whether to extend -the rotation, or if scheduling conflicts arise. - -For scheduling conflicts you can swap your shift with another wrangler. A good -approach is to look at the rotation calendar, finding someone with nearby dates -to yours. Reach out to them, as they will often be willing to swap. - -To actually modify the rotation: -See the [Chrome Internal GPU Pixel Wrangling Instructions] for information. - -[Chrome Internal GPU Pixel Wrangling Instructions]: https://sites.google.com/a/google.com/client3d/documents/chrome-internal-gpu-pixel-wrangling-instructions
diff --git a/gpu/command_buffer/service/skia_utils.cc b/gpu/command_buffer/service/skia_utils.cc index 431ecfb..5e4de9e6 100644 --- a/gpu/command_buffer/service/skia_utils.cc +++ b/gpu/command_buffer/service/skia_utils.cc
@@ -108,13 +108,15 @@ use_version_es2 = base::FeatureList::IsEnabled(features::kUseGles2ForOopR); #endif - // Use R8 and R16F when using later GLs where LUMINANCE8 and LUMINANCE18F are - // deprecated + // Use R8 and R16F when using later GLs where ALPHA8, LUMINANCE8, ALPHA16F and + // LUMINANCE16F are deprecated if (feature_info->gl_version_info().NeedsLuminanceAlphaEmulation()) { switch (internal_format) { + case GL_ALPHA8_EXT: case GL_LUMINANCE8: internal_format = GL_R8_EXT; break; + case GL_ALPHA16F_EXT: case GL_LUMINANCE16F_EXT: internal_format = GL_R16F_EXT; break;
diff --git a/headless/lib/browser/headless_clipboard.cc b/headless/lib/browser/headless_clipboard.cc index 00a362c..b69c2f57 100644 --- a/headless/lib/browser/headless_clipboard.cc +++ b/headless/lib/browser/headless_clipboard.cc
@@ -76,6 +76,10 @@ const auto& data = GetStore(buffer).data; std::vector<std::u16string> types; types.reserve(data.size()); + std::map<std::string, std::string> custom_format_names = + ExtractCustomPlatformNames(buffer, data_dst); + for (const auto& item : custom_format_names) + types.push_back(base::UTF8ToUTF16(item.first)); for (const auto& it : data) { std::u16string type = base::UTF8ToUTF16(it.first.GetName()); types.push_back(type);
diff --git a/headless/test/headless_devtools_client_browsertest.cc b/headless/test/headless_devtools_client_browsertest.cc index 4e9a0fa..6f27ebb8 100644 --- a/headless/test/headless_devtools_client_browsertest.cc +++ b/headless/test/headless_devtools_client_browsertest.cc
@@ -1030,31 +1030,6 @@ DISABLED_HEADLESS_ASYNC_DEVTOOLED_TEST_F(BlockedByClient_NetworkObserver_Test); -class DevToolsSetCookieTest : public HeadlessAsyncDevTooledBrowserTest, - public network::Observer { - public: - void RunDevTooledTest() override { - EXPECT_TRUE(embedded_test_server()->Start()); - devtools_client_->GetNetwork()->AddObserver(this); - - base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed); - devtools_client_->GetNetwork()->Enable(run_loop.QuitClosure()); - run_loop.Run(); - - devtools_client_->GetPage()->Navigate( - embedded_test_server()->GetURL("/set-cookie?cookie1").spec()); - } - - void OnResponseReceived( - const network::ResponseReceivedParams& params) override { - EXPECT_NE(std::string::npos, params.GetResponse()->GetHeadersText().find( - "Set-Cookie: cookie1")); - FinishAsynchronousTest(); - } -}; - -HEADLESS_ASYNC_DEVTOOLED_TEST_F(DevToolsSetCookieTest); - class DevtoolsInterceptionWithAuthProxyTest : public HeadlessAsyncDevTooledBrowserTest, public network::ExperimentalObserver,
diff --git a/infra/config/generated/cr-buildbucket.cfg b/infra/config/generated/cr-buildbucket.cfg index 98ed12c..18304be1 100644 --- a/infra/config/generated/cr-buildbucket.cfg +++ b/infra/config/generated/cr-buildbucket.cfg
@@ -38144,7 +38144,7 @@ ' "chrome",' ' "chrome_100_percent.pak",' ' "chrome_200_percent.pak",' - ' "crashpad_handler",' + ' "chrome_crashpad_handler",' ' "headless_lib.pak",' ' "icudtl.dat",' ' "nacl_helper",' @@ -39623,7 +39623,7 @@ ' "chrome",' ' "chrome_100_percent.pak",' ' "chrome_200_percent.pak",' - ' "crashpad_handler",' + ' "chrome_crashpad_handler",' ' "headless_lib.pak",' ' "icudtl.dat",' ' "libminigbm.so",' @@ -90066,7 +90066,6 @@ swarming_host: "chromium-swarm.appspot.com" swarming_tags: "vpython:native-python-wrapper" dimensions: "builder:win10-rel-compilator" - dimensions: "cores:16" dimensions: "cpu:x86-64" dimensions: "os:Windows-10" dimensions: "pool:luci.chromium.try"
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star index 54d5e782..1b9f0cfc 100644 --- a/infra/config/subprojects/chromium/ci.star +++ b/infra/config/subprojects/chromium/ci.star
@@ -1846,7 +1846,7 @@ "chrome", "chrome_100_percent.pak", "chrome_200_percent.pak", - "crashpad_handler", + "chrome_crashpad_handler", "headless_lib.pak", "icudtl.dat", "nacl_helper", @@ -3306,7 +3306,7 @@ "chrome", "chrome_100_percent.pak", "chrome_200_percent.pak", - "crashpad_handler", + "chrome_crashpad_handler", "headless_lib.pak", "icudtl.dat", "libminigbm.so",
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star index 734cecd..eb7d0a6 100644 --- a/infra/config/subprojects/chromium/try.star +++ b/infra/config/subprojects/chromium/try.star
@@ -1881,8 +1881,8 @@ try_.chromium_win_builder( name = "win10-rel-compilator", builderless = False, - cores = 16, os = os.WINDOWS_10, + cores = None, ssd = True, goma_jobs = goma.jobs.J300, executable = "recipe:chromium/compilator",
diff --git a/ios/build/bots/scripts/shard_util.py b/ios/build/bots/scripts/shard_util.py index f1dd580..97bcd2525 100644 --- a/ios/build/bots/scripts/shard_util.py +++ b/ios/build/bots/scripts/shard_util.py
@@ -18,7 +18,7 @@ # Regex to parse all compiled EG tests, including disabled (prepended with # DISABLED_ or FLAKY_). TEST_NAMES_DEBUG_APP_PATTERN = re.compile( - 'imp +(?:0[xX][0-9a-fA-F]+ )?-\[(?P<testSuite>[A-Za-z_][A-Za-z0-9_]' + 'imp .*-\[(?P<testSuite>[A-Za-z_][A-Za-z0-9_]' '*Test[Case]*) (?P<testMethod>(?:DISABLED_|FLAKY_)?test[A-Za-z0-9_]*)\]') TEST_CLASS_RELEASE_APP_PATTERN = re.compile( r'name +0[xX]\w+ ' @@ -26,7 +26,7 @@ # Regex to parse all compiled EG tests, including disabled (prepended with # DISABLED_ or FLAKY_). TEST_NAME_RELEASE_APP_PATTERN = re.compile( - r'name +0[xX]\w+ (?P<testCase>(?:DISABLED_|FLAKY_)?test[A-Za-z0-9_]+)\n') + r'name +0[xX].+ (?P<testCase>(?:DISABLED_|FLAKY_)?test[A-Za-z0-9_]+)\n') # 'ChromeTestCase' and 'BaseEarlGreyTestCase' are parent classes # of all EarlGrey/EarlGrey2 test classes. 'appConfigurationForTestCase' is a # class method. They have no real tests.
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index ae037c11..10975589 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -51,6 +51,7 @@ "//components/signin/public/identity_manager/objc", "//components/strings", "//ios/chrome/app:tests_hook", + "//ios/chrome/app/application_delegate:app_state_header", "//ios/chrome/app/strings", "//ios/chrome/browser", "//ios/chrome/browser/browser_state",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm index 5e24b08..057719d5 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -19,6 +19,7 @@ #include "components/prefs/pref_service.h" #import "components/search_engines/template_url.h" #import "components/search_engines/template_url_service.h" +#import "ios/chrome/app/application_delegate/app_state.h" #include "ios/chrome/app/tests_hook.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/drag_and_drop/url_drag_drop_handler.h" @@ -98,6 +99,7 @@ #endif @interface ContentSuggestionsCoordinator () < + AppStateObserver, ContentSuggestionsActionHandler, ContentSuggestionsHeaderCommands, ContentSuggestionsMenuProvider, @@ -208,6 +210,20 @@ self.browser->GetBrowserState()); self.headerController.toolbarDelegate = self.toolbarDelegate; + // Only handle app state for the new First Run UI. + if (base::FeatureList::IsEnabled(kEnableFREUIModuleIOS)) { + SceneState* sceneState = + SceneStateBrowserAgent::FromBrowser(self.browser)->GetSceneState(); + AppState* appState = sceneState.appState; + [appState addObserver:self]; + + // Do not focus on omnibox for voice over if there are other screens to + // show. + if (appState.initStage < InitStageFinal) { + self.headerController.focusOmniboxWhenViewAppears = NO; + } + } + favicon::LargeIconService* largeIconService = IOSChromeLargeIconServiceFactory::GetForBrowserState( self.browser->GetBrowserState()); @@ -860,4 +876,18 @@ !tests_hook::DisableDiscoverFeed(); } +#pragma mark - AppStateObserver + +- (void)appState:(AppState*)appState + didTransitionFromInitStage:(InitStage)previousInitStage { + if (base::FeatureList::IsEnabled(kEnableFREUIModuleIOS)) { + if (previousInitStage == InitStageFirstRun) { + self.headerController.focusOmniboxWhenViewAppears = YES; + [self.headerController focusAccessibilityOnOmnibox]; + + [appState removeObserver:self]; + } + } +} + @end
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.h index 187a9ee..0ff54152 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.h
@@ -53,6 +53,10 @@ // |YES| if a what's new promo can be displayed. @property(nonatomic, assign) BOOL promoCanShow; +// |YES| if the omnibox should be focused on when the view appears for voice +// over. +@property(nonatomic, assign) BOOL focusOmniboxWhenViewAppears; + // Return the toolbar view; - (UIView*)toolBarView; @@ -60,6 +64,9 @@ // omnibox. - (void)focusFakebox; +// Sends notification to focus the accessibility of the omnibox. +- (void)focusAccessibilityOnOmnibox; + // Identity disc shown in this ViewController. // TODO(crbug.com/1170995): Remove once the Feed header properly supports // ContentSuggestions.
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm index 8c2c314..427124f 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
@@ -110,7 +110,10 @@ @synthesize logoFetched = _logoFetched; - (instancetype)init { - return [super initWithNibName:nil bundle:nil]; + if (self = [super initWithNibName:nil bundle:nil]) { + _focusOmniboxWhenViewAppears = YES; + } + return self; } #pragma mark - Public @@ -229,8 +232,10 @@ - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; - UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, - self.fakeOmnibox); + + if (self.focusOmniboxWhenViewAppears) { + [self focusAccessibilityOnOmnibox]; + } } - (CGFloat)headerHeight { @@ -446,6 +451,11 @@ [self shiftTilesUp]; } +- (void)focusAccessibilityOnOmnibox { + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, + self.fakeOmnibox); +} + - (void)identityDiscTapped { base::RecordAction(base::UserMetricsAction("MobileNTPIdentityDiscTapped")); if (base::FeatureList::IsEnabled(signin::kMobileIdentityConsistency)) {
diff --git a/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.h b/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.h index 7c1a8f3..742db5a 100644 --- a/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.h +++ b/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.h
@@ -20,6 +20,10 @@ // NO, the banner will be of normal height (25% of view height). Defaults to NO. @property(nonatomic, assign) BOOL isTallBanner; +// The label of the headline below the image. Must be set before the view is +// loaded. This is declared public so the accessibility can be enabled. +@property(nonatomic, strong) UILabel* titleLabel; + // The headline below the image. Must be set before the view is loaded. @property(nonatomic, copy) NSString* titleText;
diff --git a/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.mm b/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.mm index 2bb838e3..d8e9b78 100644 --- a/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.mm +++ b/ios/chrome/browser/ui/first_run/first_run_screen_view_controller.mm
@@ -51,7 +51,6 @@ @property(nonatomic, strong) UIImageView* imageView; // UIView that wraps the scrollable content. @property(nonatomic, strong) UIView* scrollContentView; -@property(nonatomic, strong) UILabel* titleLabel; @property(nonatomic, strong) UILabel* subtitleLabel; @property(nonatomic, strong) HighlightedButton* primaryActionButton; @property(nonatomic, strong) UIButton* secondaryActionButton;
diff --git a/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm b/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm index 0b76c6c..70e584c 100644 --- a/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm +++ b/ios/chrome/browser/ui/first_run/welcome/welcome_screen_view_controller.mm
@@ -120,6 +120,13 @@ [super viewDidLoad]; } +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, + self.titleLabel); +} + #pragma mark - Accessors - (BOOL)checkBoxSelected {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm index 3e94118..c9ac354 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
@@ -7,6 +7,7 @@ #include "base/check_op.h" #include "base/cxx17_backports.h" #include "base/ios/block_types.h" +#import "base/ios/ios_util.h" #import "base/mac/foundation_util.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" @@ -1070,6 +1071,15 @@ } else { [self selectItemWithIDForEditing:itemID]; } + // Dragging multiple tabs to reorder them is not supported. So there is no + // need to enable dragging when multiple items are selected in devices that + // don't support multiple windows. + if (self.selectedItemIDsForEditing.count > 1 && + !base::ios::IsMultipleScenesSupported()) { + self.collectionView.dragInteractionEnabled = NO; + } else { + self.collectionView.dragInteractionEnabled = YES; + } [self.collectionView reloadItemsAtIndexPaths:@[ indexPath ]]; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm index 757caa8..79e7787c 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_egtest.mm
@@ -21,6 +21,7 @@ #import "ios/testing/earl_grey/earl_grey_test.h" #import "ios/web/public/test/http_server/http_server.h" #import "ios/web/public/test/http_server/http_server_util.h" +#import "net/base/mac/url_conversions.h" #import "ui/base/device_form_factor.h" #include "ui/base/l10n/l10n_util.h" @@ -117,7 +118,9 @@ if ([self isRunningTest:@selector(testTabGridBulkActionCloseTabs)] || [self isRunningTest:@selector(testTabGridBulkActionDeselectAll)] || [self isRunningTest:@selector(testTabGridBulkActionSelectAll)] || - [self isRunningTest:@selector(testTabGridBulkActionAddToReadingList)]) { + [self isRunningTest:@selector(testTabGridBulkActionAddToBookmarks)] || + [self isRunningTest:@selector(testTabGridBulkActionAddToReadingList)] || + [self isRunningTest:@selector(testTabGridBulkActionShare)]) { config.features_enabled.push_back(kTabsBulkActions); } @@ -1090,6 +1093,66 @@ [ChromeEarlGrey waitForMainTabCount:0 inWindowWithNumber:0]; } +// Tests adding items to Bookmarks from the tab grid edit mode. +- (void)testTabGridBulkActionAddToBookmarks { + if (!base::ios::IsRunningOnIOS14OrLater()) { + EARL_GREY_TEST_SKIPPED( + @"Bulk actions are only supported on iOS 14 and later."); + } + + [ChromeEarlGrey loadURL:_URL1]; + [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; + + [ChromeEarlGrey openNewTab]; + [ChromeEarlGrey loadURL:_URL2]; + [ChromeEarlGrey waitForWebStateContainingText:kResponse2]; + + [ChromeEarlGrey openNewTab]; + [ChromeEarlGrey loadURL:_URL3]; + [ChromeEarlGrey waitForWebStateContainingText:kResponse3]; + + [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridEditButton()] + performAction:grey_tap()]; + + [[EarlGrey + selectElementWithMatcher:chrome_test_util::TabGridSelectTabsMenuButton()] + performAction:grey_tap()]; + + // Select the first and last items. + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(2)] + performAction:grey_tap()]; + + [[EarlGrey + selectElementWithMatcher:chrome_test_util::TabGridEditAddToButton()] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:AddToBookmarksButton()] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher: + chrome_test_util::NavigationBarTitleWithAccessibilityLabelId( + IDS_IOS_BOOKMARK_CHOOSE_GROUP_BUTTON)] + assertWithMatcher:grey_notNil()]; + + // Choose "Mobile Bookmarks" folder as the destination. + // Duplicate matcher here instead of using +[BookmarkEarlGreyUI + // openMobileBookmarks] in order to properly wait for the snackbar message. + NSString* snackBarMessage = + l10n_util::GetNSStringF(IDS_IOS_BOOKMARK_PAGE_SAVED_FOLDER, + base::SysNSStringToUTF16(@"Mobile Bookmarks")); + [self waitForSnackBarMessageText:snackBarMessage + triggeredByTappingItemWithMatcher:grey_allOf(grey_kindOfClassName( + @"UITableViewCell"), + grey_descendant(grey_text( + @"Mobile Bookmarks")), + nil)]; +} + // Tests adding items to the readinglist from the tab grid edit mode. - (void)testTabGridBulkActionAddToReadingList { if (!base::ios::IsRunningOnIOS14OrLater()) { @@ -1132,6 +1195,74 @@ triggeredByTappingItemWithMatcher:AddToReadingListButton()]; } +// Tests sharing multiple tabs from the tab grid edit mode. +- (void)testTabGridBulkActionShare { + if (!base::ios::IsRunningOnIOS14OrLater()) { + EARL_GREY_TEST_SKIPPED( + @"Bulk actions are only supported on iOS 14 and later."); + } + + [ChromeEarlGrey loadURL:_URL1]; + [ChromeEarlGrey waitForWebStateContainingText:kResponse1]; + + [ChromeEarlGrey openNewTab]; + [ChromeEarlGrey loadURL:_URL2]; + [ChromeEarlGrey waitForWebStateContainingText:kResponse2]; + + [ChromeEarlGrey openNewTab]; + [ChromeEarlGrey loadURL:_URL3]; + [ChromeEarlGrey waitForWebStateContainingText:kResponse3]; + + [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridEditButton()] + performAction:grey_tap()]; + + [[EarlGrey + selectElementWithMatcher:chrome_test_util::TabGridSelectTabsMenuButton()] + performAction:grey_tap()]; + + // Select the first and last items. + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(2)] + performAction:grey_tap()]; + + [[EarlGrey + selectElementWithMatcher:chrome_test_util::TabGridEditShareButton()] + performAction:grey_tap()]; + + [[EarlGrey selectElementWithMatcher:chrome_test_util::CopyActivityButton()] + performAction:grey_tap()]; + + NSString* URL1String = base::SysUTF8ToNSString(_URL1.spec()); + NSString* URL3String = base::SysUTF8ToNSString(_URL3.spec()); + + // Copying can take a while, wait for it to happen. + GREYCondition* copyCondition = [GREYCondition + conditionWithName:@"test text copied condition" + block:^BOOL { + NSArray<NSString*>* URLStrings = + UIPasteboard.generalPasteboard.strings; + if (URLStrings.count != 2) { + return false; + } + + // Strings may appear in either order. + if (([URLStrings[0] isEqualToString:URL1String] && + [URLStrings[1] isEqualToString:URL3String]) || + ([URLStrings[0] isEqualToString:URL3String] && + [URLStrings[1] isEqualToString:URL1String])) { + return true; + } + + return false; + }]; + // Wait for copy to happen or timeout after 5 seconds. + GREYAssertTrue([copyCondition waitWithTimeout:5], @"Copying URLs failed"); +} + #pragma mark - Helper Methods - (void)loadTestURLs { @@ -1218,4 +1349,36 @@ @"Snackbar did not disappear."); } +- (void)waitForSnackBarMessageText:(NSString*)snackBarLabel + triggeredByTappingItemWithMatcher:(id<GREYMatcher>)matcher { + // Start custom monitor, because there's a chance the snackbar is + // already gone by the time we wait for it (and it was like that sometimes). + [ChromeEarlGrey watchForButtonsWithLabels:@[ snackBarLabel ] + timeout:kSnackbarAppearanceTimeout]; + + [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()]; + + // Wait for the snackbar to appear. + id<GREYMatcher> snackbar_matcher = + chrome_test_util::ButtonWithAccessibilityLabel(snackBarLabel); + ConditionBlock wait_for_appearance = ^{ + return [ChromeEarlGrey watcherDetectedButtonWithLabel:snackBarLabel]; + }; + GREYAssert(base::test::ios::WaitUntilConditionOrTimeout( + kSnackbarAppearanceTimeout, wait_for_appearance), + @"Snackbar did not appear."); + + // Wait for the snackbar to disappear. + ConditionBlock wait_for_disappearance = ^{ + NSError* error = nil; + [[EarlGrey selectElementWithMatcher:snackbar_matcher] + assertWithMatcher:grey_nil() + error:&error]; + return error == nil; + }; + GREYAssert(base::test::ios::WaitUntilConditionOrTimeout( + kSnackbarDisappearanceTimeout, wait_for_disappearance), + @"Snackbar did not disappear."); +} + @end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm index d2c2afa..6430c966 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_view_controller.mm
@@ -606,6 +606,8 @@ self.incognitoTabsViewController.mode = self.tabGridMode; self.topToolbar.mode = self.tabGridMode; self.scrollView.scrollEnabled = (self.tabGridMode != TabGridModeSelection); + if (mode == TabGridModeSelection) + [self updateSelectionModeToolbars]; } #pragma mark - LayoutSwitcherProvider @@ -1542,6 +1544,7 @@ self.bottomToolbar.selectedTabsCount = selectedItemsCount; [self.bottomToolbar setShareTabsButtonEnabled:sharableSelectedItemsCount > 0]; [self.bottomToolbar setAddToButtonEnabled:sharableSelectedItemsCount > 0]; + [self.bottomToolbar setCloseTabsButtonEnabled:selectedItemsCount]; if (currentGridViewController.allItemsSelectedForEditing) { [self.topToolbar configureDeselectAllButtonTitle];
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.h b/ios/chrome/test/earl_grey/chrome_matchers.h index fc9cb87..267d793b 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.h +++ b/ios/chrome/test/earl_grey/chrome_matchers.h
@@ -604,6 +604,9 @@ // Returns a matcher for the button to select all tabs. id<GREYMatcher> TabGridEditSelectAllButton(); +// Returns a matcher for the button to share tabs. +id<GREYMatcher> TabGridEditShareButton(); + } // namespace chrome_test_util #endif // IOS_CHROME_TEST_EARL_GREY_CHROME_MATCHERS_H_
diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm index 586f61dd..a1e0e23c 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
@@ -763,4 +763,8 @@ return [ChromeMatchersAppInterface tabGridEditSelectAllButton]; } +id<GREYMatcher> TabGridEditShareButton() { + return [ChromeMatchersAppInterface tabGridEditShareButton]; +} + } // namespace chrome_test_util
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h index e4d4cdf..e75dc0c9 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.h
@@ -596,6 +596,9 @@ // Returns a matcher for the button to select all tabs. + (id<GREYMatcher>)tabGridEditSelectAllButton; +// Returns a matcher for the button to share tabs. ++ (id<GREYMatcher>)tabGridEditShareButton; + @end #endif // IOS_CHROME_TEST_EARL_GREY_CHROME_MATCHERS_APP_INTERFACE_H_
diff --git a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm index 0e5ad73..2e46f8d1 100644 --- a/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_matchers_app_interface.mm
@@ -1149,4 +1149,9 @@ grey_sufficientlyVisible(), nil); } ++ (id<GREYMatcher>)tabGridEditShareButton { + return grey_allOf(grey_accessibilityID(kTabGridEditShareButtonIdentifier), + grey_sufficientlyVisible(), nil); +} + @end
diff --git a/ios/chrome/test/earl_grey/chrome_test_case.mm b/ios/chrome/test/earl_grey/chrome_test_case.mm index a73aff0..29513d0 100644 --- a/ios/chrome/test/earl_grey/chrome_test_case.mm +++ b/ios/chrome/test/earl_grey/chrome_test_case.mm
@@ -190,6 +190,30 @@ return _testServer.get(); } +- (void)disableKeyboardTutorials { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // Set the preferences values directly on simulator for the keyboard + // modifiers. For persisting these values, CFPreferencesSynchronize must be + // called after. + CFStringRef app = CFSTR("com.apple.Preferences"); + CFPreferencesSetValue(CFSTR("DidShowContinuousPathIntroduction"), + kCFBooleanTrue, app, kCFPreferencesAnyUser, + kCFPreferencesAnyHost); + CFPreferencesSetValue(CFSTR("KeyboardDidShowProductivityTutorial"), + kCFBooleanTrue, app, kCFPreferencesAnyUser, + kCFPreferencesAnyHost); + CFPreferencesSetValue(CFSTR("DidShowGestureKeyboardIntroduction"), + kCFBooleanTrue, app, kCFPreferencesAnyUser, + kCFPreferencesAnyHost); + CFPreferencesSetValue( + CFSTR("UIKeyboardDidShowInternationalInfoIntroduction"), kCFBooleanTrue, + app, kCFPreferencesAnyUser, kCFPreferencesAnyHost); + CFPreferencesSynchronize(kCFPreferencesAnyApplication, + kCFPreferencesAnyUser, kCFPreferencesAnyHost); + }); +} + // Set up called once per test, to open a new tab. - (void)setUp { // Add this class as an AppLaunchManager observer before [super setUp], @@ -199,6 +223,7 @@ [super setUp]; // TODO(crbug.com/1218575): Remove once moved to EG. + [self disableKeyboardTutorials]; [ChromeTestCaseAppInterface disableKeyboardTutorials]; [self resetAppState];
diff --git a/ios/chrome/test/earl_grey/chrome_test_case_app_interface.mm b/ios/chrome/test/earl_grey/chrome_test_case_app_interface.mm index f0b3891..8f18d44 100644 --- a/ios/chrome/test/earl_grey/chrome_test_case_app_interface.mm +++ b/ios/chrome/test/earl_grey/chrome_test_case_app_interface.mm
@@ -58,22 +58,20 @@ // modifiers. For persisting these values, CFPreferencesSynchronize must be // called after. CFStringRef app = CFSTR("com.apple.keyboard.preferences.plist"); - if (@available(iOS 15, *)) { - CFPreferencesSetValue(CFSTR("DidShowContinuousPathIntroduction"), - kCFBooleanTrue, app, kCFPreferencesAnyUser, - kCFPreferencesAnyHost); - CFPreferencesSetValue(CFSTR("KeyboardDidShowProductivityTutorial"), - kCFBooleanTrue, app, kCFPreferencesAnyUser, - kCFPreferencesAnyHost); - CFPreferencesSetValue(CFSTR("DidShowGestureKeyboardIntroduction"), - kCFBooleanTrue, app, kCFPreferencesAnyUser, - kCFPreferencesAnyHost); - CFPreferencesSetValue( - CFSTR("UIKeyboardDidShowInternationalInfoIntroduction"), - kCFBooleanTrue, app, kCFPreferencesAnyUser, kCFPreferencesAnyHost); - CFPreferencesSynchronize(kCFPreferencesAnyApplication, - kCFPreferencesAnyUser, kCFPreferencesAnyHost); - } + CFPreferencesSetValue(CFSTR("DidShowContinuousPathIntroduction"), + kCFBooleanTrue, app, kCFPreferencesAnyUser, + kCFPreferencesAnyHost); + CFPreferencesSetValue(CFSTR("KeyboardDidShowProductivityTutorial"), + kCFBooleanTrue, app, kCFPreferencesAnyUser, + kCFPreferencesAnyHost); + CFPreferencesSetValue(CFSTR("DidShowGestureKeyboardIntroduction"), + kCFBooleanTrue, app, kCFPreferencesAnyUser, + kCFPreferencesAnyHost); + CFPreferencesSetValue( + CFSTR("UIKeyboardDidShowInternationalInfoIntroduction"), kCFBooleanTrue, + app, kCFPreferencesAnyUser, kCFPreferencesAnyHost); + CFPreferencesSynchronize(kCFPreferencesAnyApplication, + kCFPreferencesAnyUser, kCFPreferencesAnyHost); }); }
diff --git a/ios/testing/earl_grey/app_launch_manager.mm b/ios/testing/earl_grey/app_launch_manager.mm index d7c16a51..2a01b72 100644 --- a/ios/testing/earl_grey/app_launch_manager.mm +++ b/ios/testing/earl_grey/app_launch_manager.mm
@@ -11,6 +11,7 @@ #import "base/ios/crb_protocol_observers.h" #include "base/strings/sys_string_conversions.h" #import "ios/testing/earl_grey/app_launch_manager_app_interface.h" +#import "ios/testing/earl_grey/base_earl_grey_test_case_app_interface.h" #import "ios/testing/earl_grey/coverage_utils.h" #import "ios/testing/earl_grey/earl_grey_test.h" #import "ios/third_party/edo/src/Service/Sources/EDOServiceException.h" @@ -227,6 +228,9 @@ [self ensureAppLaunchedWithArgs:arguments relaunchPolicy:configuration.relaunch_policy]; + + if (@available(iOS 14, *)) + [BaseEarlGreyTestCaseAppInterface enableFastAnimation]; } - (void)ensureAppLaunchedWithFeaturesEnabled:
diff --git a/ios/testing/earl_grey/base_earl_grey_test_case_app_interface.h b/ios/testing/earl_grey/base_earl_grey_test_case_app_interface.h index 63f21f0..68c82fc 100644 --- a/ios/testing/earl_grey/base_earl_grey_test_case_app_interface.h +++ b/ios/testing/earl_grey/base_earl_grey_test_case_app_interface.h
@@ -15,6 +15,9 @@ // Logs |message| from the app process (as opposed to the test process). + (void)logMessage:(NSString*)message; +// Adjusts the speed property of CALayer to 100 to speed up XCUITests. ++ (void)enableFastAnimation; + @end #endif // IOS_TESTING_EARL_GREY_BASE_EARL_GREY_TEST_CASE_APP_INTERFACE_H_
diff --git a/ios/testing/earl_grey/base_earl_grey_test_case_app_interface.mm b/ios/testing/earl_grey/base_earl_grey_test_case_app_interface.mm index ffcf840..0fa591d 100644 --- a/ios/testing/earl_grey/base_earl_grey_test_case_app_interface.mm +++ b/ios/testing/earl_grey/base_earl_grey_test_case_app_interface.mm
@@ -4,6 +4,8 @@ #import "ios/testing/earl_grey/base_earl_grey_test_case_app_interface.h" +#import <UIKit/UIKit.h> + #include "base/logging.h" #include "base/strings/sys_string_conversions.h" @@ -17,4 +19,10 @@ DLOG(WARNING) << base::SysNSStringToUTF8(message); } ++ (void)enableFastAnimation { + for (UIWindow* window in [UIApplication sharedApplication].windows) { + [[window layer] setSpeed:100]; + } +} + @end
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc index 5a214b4..5eeaa29 100644 --- a/media/gpu/chromeos/video_decoder_pipeline.cc +++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -61,10 +61,12 @@ } // namespace VideoDecoderMixin::VideoDecoderMixin( + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, base::WeakPtr<VideoDecoderMixin::Client> client) : decoder_task_runner_(std::move(decoder_task_runner)), client_(std::move(client)) {} + VideoDecoderMixin::~VideoDecoderMixin() = default; bool VideoDecoderMixin::NeedsTranscryption() { @@ -283,8 +285,9 @@ // |decoder_| may be Initialize()d multiple times (e.g. on |config| changes) // but can only be created once. if (!decoder_ && !create_decoder_function_cb_.is_null()) { - decoder_ = std::move(create_decoder_function_cb_) - .Run(decoder_task_runner_, decoder_weak_this_); + decoder_ = + std::move(create_decoder_function_cb_) + .Run(media_log_->Clone(), decoder_task_runner_, decoder_weak_this_); } // Note: |decoder_| might fail to be created, e.g. on V4L2 platforms. if (!decoder_) {
diff --git a/media/gpu/chromeos/video_decoder_pipeline.h b/media/gpu/chromeos/video_decoder_pipeline.h index fa3b37a..a321b04 100644 --- a/media/gpu/chromeos/video_decoder_pipeline.h +++ b/media/gpu/chromeos/video_decoder_pipeline.h
@@ -69,6 +69,7 @@ }; VideoDecoderMixin( + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, base::WeakPtr<VideoDecoderMixin::Client> client); ~VideoDecoderMixin() override; @@ -84,6 +85,8 @@ virtual bool NeedsTranscryption(); protected: + const std::unique_ptr<MediaLog> media_log_; + // Decoder task runner. All public methods of // VideoDecoderMixin are executed at this task runner. const scoped_refptr<base::SequencedTaskRunner> decoder_task_runner_; @@ -99,6 +102,7 @@ public: using CreateDecoderFunctionCB = base::OnceCallback<std::unique_ptr<VideoDecoderMixin>( + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner>, base::WeakPtr<VideoDecoderMixin::Client>)>;
diff --git a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc index 1387a63..e67004c 100644 --- a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc +++ b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
@@ -63,7 +63,8 @@ class MockDecoder : public VideoDecoderMixin { public: MockDecoder() - : VideoDecoderMixin(base::ThreadTaskRunnerHandle::Get(), + : VideoDecoderMixin(std::make_unique<MockMediaLog>(), + base::ThreadTaskRunnerHandle::Get(), base::WeakPtr<VideoDecoderMixin::Client>(nullptr)) {} ~MockDecoder() override = default; @@ -218,6 +219,7 @@ #endif // BUILDFLAG(IS_CHROMEOS_ASH) static std::unique_ptr<VideoDecoderMixin> CreateNullMockDecoder( + std::unique_ptr<MediaLog> /* media_log */, scoped_refptr<base::SequencedTaskRunner> /* decoder_task_runner */, base::WeakPtr<VideoDecoderMixin::Client> /* client */) { return nullptr; @@ -225,6 +227,7 @@ // Creates a MockDecoder with an EXPECT_CALL on Initialize that returns ok. static std::unique_ptr<VideoDecoderMixin> CreateGoodMockDecoder( + std::unique_ptr<MediaLog> /* media_log */, scoped_refptr<base::SequencedTaskRunner> /* decoder_task_runner */, base::WeakPtr<VideoDecoderMixin::Client> /* client */) { std::unique_ptr<MockDecoder> decoder(new MockDecoder()); @@ -239,6 +242,7 @@ // Creates a MockDecoder with an EXPECT_CALL on Initialize that returns ok and // also indicates that it requires transcryption. static std::unique_ptr<VideoDecoderMixin> CreateGoodMockTranscryptDecoder( + std::unique_ptr<MediaLog> /* media_log */, scoped_refptr<base::SequencedTaskRunner> /* decoder_task_runner */, base::WeakPtr<VideoDecoderMixin::Client> /* client */) { std::unique_ptr<MockDecoder> decoder(new MockDecoder()); @@ -252,6 +256,7 @@ // Creates a MockDecoder with an EXPECT_CALL on Initialize that returns error. static std::unique_ptr<VideoDecoderMixin> CreateBadMockDecoder( + std::unique_ptr<MediaLog> /* media_log */, scoped_refptr<base::SequencedTaskRunner> /* decoder_task_runner */, base::WeakPtr<VideoDecoderMixin::Client> /* client */) { std::unique_ptr<MockDecoder> decoder(new MockDecoder());
diff --git a/media/gpu/v4l2/v4l2_video_decoder.cc b/media/gpu/v4l2/v4l2_video_decoder.cc index 70d569f4..9125d5d7 100644 --- a/media/gpu/v4l2/v4l2_video_decoder.cc +++ b/media/gpu/v4l2/v4l2_video_decoder.cc
@@ -12,6 +12,7 @@ #include "base/memory/ptr_util.h" #include "base/task/post_task.h" #include "media/base/limits.h" +#include "media/base/media_log.h" #include "media/base/video_types.h" #include "media/base/video_util.h" #include "media/gpu/chromeos/dmabuf_video_frame_pool.h" @@ -51,6 +52,7 @@ // static std::unique_ptr<VideoDecoderMixin> V4L2VideoDecoder::Create( + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, base::WeakPtr<VideoDecoderMixin::Client> client) { DCHECK(decoder_task_runner->RunsTasksInCurrentSequence()); @@ -62,8 +64,9 @@ return nullptr; } - return base::WrapUnique<VideoDecoderMixin>(new V4L2VideoDecoder( - std::move(decoder_task_runner), std::move(client), std::move(device))); + return base::WrapUnique<VideoDecoderMixin>( + new V4L2VideoDecoder(std::move(media_log), std::move(decoder_task_runner), + std::move(client), std::move(device))); } // static @@ -79,10 +82,13 @@ } V4L2VideoDecoder::V4L2VideoDecoder( + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, base::WeakPtr<VideoDecoderMixin::Client> client, scoped_refptr<V4L2Device> device) - : VideoDecoderMixin(std::move(decoder_task_runner), std::move(client)), + : VideoDecoderMixin(std::move(media_log), + std::move(decoder_task_runner), + std::move(client)), device_(std::move(device)), weak_this_factory_(this) { DCHECK_CALLED_ON_VALID_SEQUENCE(decoder_sequence_checker_);
diff --git a/media/gpu/v4l2/v4l2_video_decoder.h b/media/gpu/v4l2/v4l2_video_decoder.h index 67514f7..784816e 100644 --- a/media/gpu/v4l2/v4l2_video_decoder.h +++ b/media/gpu/v4l2/v4l2_video_decoder.h
@@ -44,6 +44,7 @@ // ensure V4L2VideoDecoder is available on the device. It will be // determined in Initialize(). static std::unique_ptr<VideoDecoderMixin> Create( + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, base::WeakPtr<VideoDecoderMixin::Client> client); @@ -82,7 +83,8 @@ private: friend class V4L2VideoDecoderTest; - V4L2VideoDecoder(scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, + V4L2VideoDecoder(std::unique_ptr<MediaLog> media_log, + scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, base::WeakPtr<VideoDecoderMixin::Client> client, scoped_refptr<V4L2Device> device); ~V4L2VideoDecoder() override;
diff --git a/media/gpu/vaapi/vaapi_video_decoder.cc b/media/gpu/vaapi/vaapi_video_decoder.cc index f426ff3a..6245147d 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.cc +++ b/media/gpu/vaapi/vaapi_video_decoder.cc
@@ -18,6 +18,7 @@ #include "build/chromeos_buildflags.h" #include "media/base/bind_to_current_loop.h" #include "media/base/format_utils.h" +#include "media/base/media_log.h" #include "media/base/media_switches.h" #include "media/base/video_frame.h" #include "media/base/video_util.h" @@ -93,10 +94,11 @@ // static std::unique_ptr<VideoDecoderMixin> VaapiVideoDecoder::Create( + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, base::WeakPtr<VideoDecoderMixin::Client> client) { - return base::WrapUnique<VideoDecoderMixin>( - new VaapiVideoDecoder(std::move(decoder_task_runner), std::move(client))); + return base::WrapUnique<VideoDecoderMixin>(new VaapiVideoDecoder( + std::move(media_log), std::move(decoder_task_runner), std::move(client))); } // static @@ -111,9 +113,12 @@ } VaapiVideoDecoder::VaapiVideoDecoder( + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, base::WeakPtr<VideoDecoderMixin::Client> client) - : VideoDecoderMixin(std::move(decoder_task_runner), std::move(client)), + : VideoDecoderMixin(std::move(media_log), + std::move(decoder_task_runner), + std::move(client)), buffer_id_to_timestamp_(kTimestampCacheSize), weak_this_factory_(this) { VLOGF(2);
diff --git a/media/gpu/vaapi/vaapi_video_decoder.h b/media/gpu/vaapi/vaapi_video_decoder.h index b2f6f59..5407010 100644 --- a/media/gpu/vaapi/vaapi_video_decoder.h +++ b/media/gpu/vaapi/vaapi_video_decoder.h
@@ -50,6 +50,7 @@ public DecodeSurfaceHandler<VASurface> { public: static std::unique_ptr<VideoDecoderMixin> Create( + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, base::WeakPtr<VideoDecoderMixin::Client> client); @@ -114,6 +115,7 @@ }; VaapiVideoDecoder( + std::unique_ptr<MediaLog> media_log, scoped_refptr<base::SequencedTaskRunner> decoder_task_runner, base::WeakPtr<VideoDecoderMixin::Client> client); ~VaapiVideoDecoder() override;
diff --git a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc index 20c3faa..8ace81f 100644 --- a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc +++ b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc
@@ -106,11 +106,13 @@ const auto& spatial_layer = config.spatial_layers[sid]; const size_t num_temporal_layers = spatial_layer.num_of_temporal_layers; DCHECK_LE(num_temporal_layers, VP9SVCLayers::kMaxSupportedTemporalLayers); + // The same bitrate factors as the software encoder. + // https://source.chromium.org/chromium/chromium/src/+/main:media/video/vpx_video_encoder.cc;l=131;drc=d383d0b3e4f76789a6de2a221c61d3531f4c59da constexpr double kTemporalLayersBitrateScaleFactors [][VP9SVCLayers::kMaxSupportedTemporalLayers] = { {1.00, 0.00, 0.00}, // For one temporal layer. - {0.50, 0.50, 0.00}, // For two temporal layers. - {0.25, 0.25, 0.50}, // For three temporal layers. + {0.60, 0.40, 0.00}, // For two temporal layers. + {0.50, 0.20, 0.30}, // For three temporal layers. }; const uint32_t bitrate_bps = spatial_layer.bitrate_bps;
diff --git a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc index 40b821143..566d869 100644 --- a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc +++ b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate_unittest.cc
@@ -46,8 +46,8 @@ }; constexpr double kTemporalLayersBitrateScaleFactors[][3] = { {1.00, 0.00, 0.00}, // For one temporal layer. - {0.50, 0.50, 0.00}, // For two temporal layers. - {0.25, 0.25, 0.50}, // For three temporal layers. + {0.60, 0.40, 0.00}, // For two temporal layers. + {0.50, 0.20, 0.30}, // For three temporal layers. }; constexpr uint8_t kTemporalLayerPattern[][4] = { {0, 0, 0, 0},
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl index 807845a..06647c6 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl
@@ -140,10 +140,12 @@ {%- endfor %} {%- endif %} -{#--- Constants #} +{#--- Constants that do not rely on other headers (basic types) #} {%- for constant in module.constants %} +{%- if not constant.kind|is_enum_kind %} {{ kythe_annotation("%s.%s"|format(module_prefix, constant.name)) }} {{constant|format_constant_declaration}}; +{%- endif %} {%- endfor %} {#--- Struct Forward Declarations -#}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl index 60d30f43..b16066e9 100644 --- a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl +++ b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -134,6 +134,14 @@ {%- endfor %} {%- endif %} +{#--- Constants that need headers (enum types) (basic types go in forward.h) #} +{%- for constant in module.constants %} +{%- if constant.kind|is_enum_kind %} +{{ kythe_annotation("%s.%s"|format(module_prefix, constant.name)) }} +{{constant|format_enum_constant_declaration}}; +{%- endif %} +{%- endfor %} + {{namespace_begin()}} {%- set module_prefix = "%s"|format(namespaces_as_array|join(".")) %}
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py index 1156987..95c8f81b 100644 --- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -389,6 +389,7 @@ "default_value": self._DefaultValue, "expression_to_text": self._ExpressionToText, "format_constant_declaration": self._FormatConstantDeclaration, + "format_enum_constant_declaration": self._FormatEnumConstantDeclaration, "get_container_validate_params_ctor_args": self._GetContainerValidateParamsCtorArgs, "get_full_mojom_name_for_kind": self._GetFullMojomNameForKind, @@ -625,6 +626,7 @@ return self.typemap[self._GetFullMojomNameForKind(typemapped_kind)][ "typename"] + # Constants that go in module-forward.h. def _FormatConstantDeclaration(self, constant, nested=False): if mojom.IsStringKind(constant.kind): if nested: @@ -636,6 +638,12 @@ GetCppPodType(constant.kind), constant.name, self._ConstantValue(constant)) + # Constants that go in module.h. + def _FormatEnumConstantDeclaration(self, constant): + if mojom.IsEnumKind(constant.kind): + return "constexpr %s %s = %s" % (self._GetNameForKind( + constant.kind), constant.name, self._ConstantValue(constant)) + def _GetCppWrapperType(self, kind, add_same_module_namespaces=False, @@ -774,6 +782,12 @@ # For Blink, map values need the full definition for tracing. return True + for constant in self.module.constants: + # Constants referencing enums need the full definition. + if mojom.IsEnumKind( + constant.kind) and constant.value.module == imported_module: + return True + return False def _IsReceiverKind(self, kind):
diff --git a/net/BUILD.gn b/net/BUILD.gn index 11499cd8..f2b67ef 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -5164,6 +5164,14 @@ seed_corpus = "data/fuzzer_data/net_canonical_cookie_fuzzer/" } +fuzzer_test("net_cookie_partition_key_fuzzer") { + sources = [ "cookies/cookie_partition_key_fuzzer.cc" ] + deps = [ + ":net_fuzzer_test_support", + "//net", + ] +} + fuzzer_test("net_parse_cookie_line_fuzzer") { sources = [ "cookies/parse_cookie_line_fuzzer.cc" ] deps = [
diff --git a/net/cookies/cookie_partition_key.h b/net/cookies/cookie_partition_key.h index cc1102b9..de5580d96 100644 --- a/net/cookies/cookie_partition_key.h +++ b/net/cookies/cookie_partition_key.h
@@ -10,6 +10,7 @@ #include "net/base/net_export.h" #include "net/base/schemeful_site.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/gurl.h" namespace network { namespace mojom { @@ -24,7 +25,6 @@ namespace net { -// TODO(crbug.com/1225444): Add fuzzer test. class NET_EXPORT CookiePartitionKey { public: CookiePartitionKey();
diff --git a/net/cookies/cookie_partition_key_fuzzer.cc b/net/cookies/cookie_partition_key_fuzzer.cc new file mode 100644 index 0000000..ddc089ac --- /dev/null +++ b/net/cookies/cookie_partition_key_fuzzer.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 <stddef.h> +#include <stdint.h> + +#include <fuzzer/FuzzedDataProvider.h> + +#include "net/cookies/cookie_partition_key.h" + +namespace net { + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + FuzzedDataProvider data_provider(data, size); + + std::string url_str = data_provider.ConsumeRandomLengthString(800); + GURL url(url_str); + if (!url.is_valid()) + return 0; + + SchemefulSite site(url::Origin::Create(url)); + absl::optional<CookiePartitionKey> partition_key = + absl::make_optional(CookiePartitionKey(site)); + + bool result = CookiePartitionKey::Deserialize(url_str, partition_key); + if (site.opaque()) + CHECK(!result); + else + CHECK(result); + + std::string tmp; + result = CookiePartitionKey::Serialize(partition_key, tmp); + if (site.opaque()) + CHECK(!result); + else + CHECK(result); + + return 0; +} + +} // namespace net
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json index 6d985bd..9b078f5 100644 --- a/net/http/transport_security_state_static.json +++ b/net/http/transport_security_state_static.json
@@ -152223,6 +152223,461 @@ { "name": "wisdotplans.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, { "name": "yavapaiaz.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, { "name": "yellowstonecountymt.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "acnj.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "acnjpolice.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "adamscountyil.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "adamscountypa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "alabamaable.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "alabamabuys.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "alabamasoilandwater.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "alachuacounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "alachuacountyfl.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "alachuacountyfla.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "alachuacountyflorida.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "albanyoregon.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "albme.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "alcovidvaccine.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "aledotx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "allencountyinvoters.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "allencountykentucky.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "almlc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "americorpsoig.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "andersoncountytn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "andersontownshipoh.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ansoncountync.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "apopka.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "arcolatexas.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "arvadaco.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ashtoncityid.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ashtonid.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "aspen.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "auroramarionvillepd-mo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "avondaleestatesga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "azsalud.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bakercitypd.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bakercounty911or.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bakercountyor.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bakercountysheriffor.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bannockcountyidaho.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bartlettil.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bartowcountyga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "batesvillearkansas.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "baxleyga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "beaconny.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "belleplaineiowa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "berlinct.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bethelparkpa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bettendorf.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bigstonecounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "binghamcountyid.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "blackhistorymonth.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bluefieldwvpd.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bluffcitytn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "boerandolphcountyga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bonnevillecountyidaho.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "boonecountyne.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bouldercounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "boxbuttecountyne.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "bradentonfl.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "braxtoncountywv.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "browardvotes.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "buchanancountyvirginia.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "buchananga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "buckscounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "budatx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "burnettcountywi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "calhouncountyflsheriff.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "capecoral.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "careyohio.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "carmeltownship-mi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cartercountymo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cavaliernd.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "chathamcountync.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "chattahoocheefl.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "childtaxcredit.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "chisagocountymn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "chnj.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "christiansburgva.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "chsvotes.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "circlevilleoh.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cityofbrookings-sd.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cityofdelcity.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cityofgirardoh.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cityofmargaretalabama.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cityofmebanenc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cityofpearidgear.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cityofpinconningmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "clantonal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "clarendonvt.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "clarkcountywi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "clarkstown.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "claytonca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "claytwpmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cochise.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "coeburnva.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "coil.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "colliervotes.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "columbiatwpmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "colwichks.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "comanchecountyks.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "conwaysc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "coopercityfl.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "coralspringsfl.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "corsicanatx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "coryellcountytx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cottagegroveor.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cottonwoodcountymn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "crystalspringsms.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cumberlandcountync.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cumberlandcountypa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cumingcountyne.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cybersafetn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cybertn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "cypressca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "daviscountyiowa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "dcpudwa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "delcity.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "delhitownshipmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "denisontx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "detroit.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "dillonco.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "dkcoks.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "dodgecountyne.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "dotlakevillagecouncil-nsn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "douglascountyga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "doverma.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "draperutah.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "dupagecounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "durhammaine.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "eaganmn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "eaglecounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "eastwashingtonpa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ebci-nsn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ebcired-nsn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ebki-nsn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "eclectic-al.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "elburnfire.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "elcajon.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "electionsshelbytn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "elmwoodmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "eriecountyohioboe.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "escondidoca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "evaluation.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fairfieldcountyohioworkforcecenter.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fairfieldtexas.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "falconerny.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fallspa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "falmouthretirementma.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fatetx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "faulknercountyar.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fayettemopd.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fbctx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fbihr.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "findlayohio.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "flaglercounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fldjj.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fleet.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "flofr.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "floir.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "flsa6.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fontanaca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "forsythcountync.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "framinghampd.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "franklincountyia.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fremontfire.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fremontmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "frenchtownmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fsst-nsn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fultoncountyar.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "fultondaleal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "galaw.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "garlandcountyar.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "glacierviewfire.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "goodlandks.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "gpodev.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "greenlakecountywi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "griswoldia.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "gsafleet.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "guamcourts.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "guilfordct.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "halifaxma.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "hancockcountymaine.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "hancockcountywv.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "harrisonar.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "harrisoncountyms.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "harrisoncountymschanceryclerk.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "hartwellga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "hcdatn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "health-ashlandcounty-oh.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "hermonmaine.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "hernandovotes.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "hgcityca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "highlandsclerkfl.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "holbrookaz.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "hotspringsar.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "houstoncountyal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "howardcountysheriffmo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "hudhomestore.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "hudsonregional.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "icams-portal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "icas-nsn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "idahofalls.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ilag.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ilcourthelp.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "indianhill.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "indianriver.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "iowaintex.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "iowamissingpersons.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "iowastem.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "irondequoit.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "islandheightsborough.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "iwtsd.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "jeffdaviscountyga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "jems-il.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "jerseycounty-il.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "jerseycountyclerk-il.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "jonestowntx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "kansasvaccine.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "kaysville.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "keizeror.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "kemahtx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "kingstonma.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "kitsap.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "lahabra.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "lakeshiremo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "lakewoodoh.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "laramiecountywy.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "larimer.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "lavontx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "lavote.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "lawrencecountypa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "lcemsami.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "lennoxsd.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "libertylakewapd.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "linncountyiowa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "logancountyks.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "longcountyga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "longlakeny.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "loraincountyohio.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "lsc-mn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "lyndontownshipmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "manitowoccountywi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mariavilleme.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "marillatownshipmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "marshallcountywv.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "marshfieldvt.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "masoncountywa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mcleodcountymn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mdatc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "medfordoregon.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "menomineecountymi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mesaazpolice.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mgclercoh.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "middleboroughma.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "milanmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "milnerga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "miltonga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "miltontwpmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "minnesotahealthcareconsortium.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mnhc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "monroecountywv.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "montclairca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "montgomerycountyal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "montgomeryohio.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "montgomeryprobatecourtal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "montgomeryvotesal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "morgancountyutah.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "moselwi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mountaingrovemo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mrrjva.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mtcoks.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mtlegnews.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mtredistricting.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mtvernonlisbonpd-ia.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "murraycountymn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mvdmt.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "mynjhelps.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ncauditor.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ncem.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "nclea.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ncsbe-apps.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ncuc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ndlegis.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ndlegistest.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "newaygocountymi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "newcastleok.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "newcombny.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "newmilfordct.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "newwaterford-oh.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "nhbp.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "noblecountyprosecutoroh.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "noexcusesc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "nomasfraudecolorado.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "northaugustasc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "northcharlestonsc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "norwoodma150.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "nyirc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "nystrs.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "oakcreekwi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ocfelections.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ocvote.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "okemahok.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "oklahomaworkstogether.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "oldcc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "olivetownship-mi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "omag.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "onondaga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "orangecityfl.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "orangetexas.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "osagecounty-ok.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ossipee-nh.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ourayco.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "owensboroky.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "painesvillemunicipalcourt-ohio.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "palmbeachelections.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "palmbeachvotes.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "palmcoast.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "palmdesert.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "parkcounty-wy.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pasadena.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pcscotus.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pdtppfl.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pennhillspa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "petal-ms.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "piketonohio.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pilotknobmo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pleasantviewmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pocahontascountyiowa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pomonaca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "popecountymn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "poplargrove-il.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pottcountyks.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ppms.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pricevillepdal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "pvtx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "qac.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "readycolorado.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "readync.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "rexburgid.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ridgecrestca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "riversidemo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "rockyford-co.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "romega.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "romegafire.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "romegapolice.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "rrtribalcourts-nsn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "ruskcountytx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "saccountyiowa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "salinecountyks.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "sallisawok.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "saltlakecounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "santaclaracounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "santarosanm.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "sapulpaok.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "sapulpapd.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "sbcountyatc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "schaumburgil.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "scottsboropdal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "screvencountyga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "sedro-woolley.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "selmer-tn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "semrecc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "shanikofireor.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "shawnee-nsn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "shorewoodwi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "simplereport.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "simpsoncountyky.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "skillsenhancementtexas.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "skillsenhancementtx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "southamptontownnypolice.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "southjacksonville-il.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "southlaketx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "southmarengoal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "southwestkansaslibrarysystem.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "spencernc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "spokanecounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "srp.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "stalbansvt.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "stantonca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "statelibraryofiowa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "stcharlescountycsfamo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "stcloudfl.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "stillwatertownshipmn.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "stjosephmo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "stlouiscountymovotes.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "stockbridge-ma.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "stopransomware.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "stratfordct.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "sullivancountypa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "sumtercountysc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "surrycountync.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "swcleanair.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "swocaoh.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "tasefiling.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "taylorcountyhdwv.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "testiowa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "tillamookcounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "timbercreekcanyontx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "tndagc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "tollandct.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "tonasketwa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "tooelecountyvotes.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "townofbrookwoodal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "townofcaponbridgewv.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "townofclevelandnc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "townofhamiltonny.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "townofwinneconne.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "trempcountywi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "unioncountyiowa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "vaccinateiowa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "vaccine.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "vacine.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "vacines.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "vacuna.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "valentinene.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "vallejoca.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "vanburencounty-mi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "victoriacountytx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "villaparkil.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "villarica.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "visalia.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "visitconwaysc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "votedenton.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "votehillsborough.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "voteidaho.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "votepalmbeach.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "votepinellas.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "voterockfordil.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "voteseminole.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "votesjc.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "votewalton.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "waldenvt.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "waldportoregon.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "walkermi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "warrencountynj.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "warrencountypa.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "warrenri.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "washoecounty.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "watertownmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "waupacacounty-wi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "wcema-ok.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "weberelections.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "webstergrovesmo.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "websternytoday.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "weld.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "westbathmaine.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "westfordwi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "westmelbourne.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "westpointne.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "wetumpkaal.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "wheatfieldtwpmi.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "whitfieldcountyga.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "willspointtx.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "wilsoncountync.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "winkelmanaz.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "wirtcountywvsheriff.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "yochadehe.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, + { "name": "yumacountyco.gov", "policy": "public-suffix-requested", "mode": "force-https", "include_subdomains": true }, // END OF ETLD-OWNER REQUESTED ENTRIES // To avoid trailing comma changes from showing up in diffs, we place a
diff --git a/net/quic/address_utils.h b/net/quic/address_utils.h index 3c8d0962..056c428 100644 --- a/net/quic/address_utils.h +++ b/net/quic/address_utils.h
@@ -57,9 +57,9 @@ sockaddr_storage result; socklen_t size = sizeof(result); - bool success = - address.ToSockAddr(reinterpret_cast<sockaddr*>(&result), &size); - DCHECK(success); + if (!address.ToSockAddr(reinterpret_cast<sockaddr*>(&result), &size)) { + return quic::QuicSocketAddress(); + } return quic::QuicSocketAddress(result); }
diff --git a/services/network/cors/preflight_controller.cc b/services/network/cors/preflight_controller.cc index cc2338b9..260340df 100644 --- a/services/network/cors/preflight_controller.cc +++ b/services/network/cors/preflight_controller.cc
@@ -21,7 +21,6 @@ #include "services/network/public/cpp/resource_request.h" #include "services/network/public/cpp/simple_url_loader.h" #include "services/network/public/mojom/devtools_observer.mojom.h" -#include "services/network/public/mojom/http_raw_request_response_info.mojom.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/parsed_headers.mojom.h" #include "services/network/public/mojom/url_loader.mojom.h"
diff --git a/services/network/cors/preflight_controller_unittest.cc b/services/network/cors/preflight_controller_unittest.cc index b2b5e7a0..1511b03 100644 --- a/services/network/cors/preflight_controller_unittest.cc +++ b/services/network/cors/preflight_controller_unittest.cc
@@ -22,6 +22,7 @@ #include "services/network/network_service.h" #include "services/network/public/cpp/cors/cors.h" #include "services/network/public/mojom/devtools_observer.mojom.h" +#include "services/network/public/mojom/http_raw_headers.mojom.h" #include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h"
diff --git a/services/network/first_party_sets/first_party_sets.cc b/services/network/first_party_sets/first_party_sets.cc index 81e7003f..f7e732e 100644 --- a/services/network/first_party_sets/first_party_sets.cc +++ b/services/network/first_party_sets/first_party_sets.cc
@@ -194,12 +194,9 @@ // Erase the intersection between the manually-specified set and the // CU-supplied set, and any members whose owner was in the intersection. - sets_.erase(base::ranges::remove_if(sets_, - [&was_manually_provided](const auto& p) { - return was_manually_provided(p.first) || - was_manually_provided(p.second); - }), - sets_.end()); + base::EraseIf(sets_, [&was_manually_provided](const auto& p) { + return was_manually_provided(p.first) || was_manually_provided(p.second); + }); // Now remove singleton sets. We already removed any sites that were part // of the intersection, or whose owner was part of the intersection. This @@ -210,13 +207,9 @@ if (it.first != it.second) owners_with_members.insert(it.second); } - sets_.erase(base::ranges::remove_if( - sets_, - [&owners_with_members](const auto& p) { - return p.first == p.second && - !base::Contains(owners_with_members, p.first); - }), - sets_.end()); + base::EraseIf(sets_, [&owners_with_members](const auto& p) { + return p.first == p.second && !base::Contains(owners_with_members, p.first); + }); // Next, we must add the manually-added set to the parsed value. for (const net::SchemefulSite& member : manual_members) {
diff --git a/services/network/network_service_network_delegate.cc b/services/network/network_service_network_delegate.cc index a99fa08..f0162399 100644 --- a/services/network/network_service_network_delegate.cc +++ b/services/network/network_service_network_delegate.cc
@@ -96,7 +96,7 @@ NetworkService* network_service = network_context_->network_service(); if (network_service) { - loader->SetAllowReportingRawHeaders(network_service->HasRawHeadersAccess( + loader->SetEnableReportingRawHeaders(network_service->HasRawHeadersAccess( loader->GetProcessId(), *effective_url)); } return net::OK;
diff --git a/services/network/network_service_unittest.cc b/services/network/network_service_unittest.cc index db26503..7c8cbbbb 100644 --- a/services/network/network_service_unittest.cc +++ b/services/network/network_service_unittest.cc
@@ -1045,92 +1045,8 @@ StartLoadingURL(request, 0); client()->RunUntilRedirectReceived(); EXPECT_TRUE(client()->has_received_redirect()); - EXPECT_TRUE(!client()->response_head()->raw_request_response_info); loader()->FollowRedirect({}, {}, {}, absl::nullopt); client()->RunUntilComplete(); - EXPECT_TRUE(!client()->response_head()->raw_request_response_info); -} - -TEST_F(NetworkServiceTestWithService, RawRequestHeadersPresent) { - CreateNetworkContext(); - ResourceRequest request; - request.url = test_server()->GetURL("/server-redirect?/echo"); - request.method = "GET"; - request.report_raw_headers = true; - request.request_initiator = url::Origin(); - StartLoadingURL(request, 0); - client()->RunUntilRedirectReceived(); - EXPECT_TRUE(client()->has_received_redirect()); - { - auto& request_response_info = - client()->response_head()->raw_request_response_info; - ASSERT_TRUE(request_response_info); - EXPECT_EQ(301, request_response_info->http_status_code); - EXPECT_EQ("Moved Permanently", request_response_info->http_status_text); - EXPECT_TRUE(base::StartsWith(request_response_info->request_headers_text, - "GET /server-redirect?/echo HTTP/1.1\r\n", - base::CompareCase::SENSITIVE)); - EXPECT_GE(request_response_info->request_headers.size(), 1lu); - EXPECT_GE(request_response_info->response_headers.size(), 1lu); - EXPECT_TRUE(base::StartsWith(request_response_info->response_headers_text, - "HTTP/1.1 301 Moved Permanently\r", - base::CompareCase::SENSITIVE)); - } - loader()->FollowRedirect({}, {}, {}, absl::nullopt); - client()->RunUntilComplete(); - { - auto& request_response_info = - client()->response_head()->raw_request_response_info; - EXPECT_EQ(200, request_response_info->http_status_code); - EXPECT_EQ("OK", request_response_info->http_status_text); - EXPECT_TRUE(base::StartsWith(request_response_info->request_headers_text, - "GET /echo HTTP/1.1\r\n", - base::CompareCase::SENSITIVE)); - EXPECT_GE(request_response_info->request_headers.size(), 1lu); - EXPECT_GE(request_response_info->response_headers.size(), 1lu); - EXPECT_TRUE(base::StartsWith(request_response_info->response_headers_text, - "HTTP/1.1 200 OK\r", - base::CompareCase::SENSITIVE)); - } -} - -TEST_F(NetworkServiceTestWithService, RawRequestAccessControl) { - const uint32_t process_id = 42; - CreateNetworkContext(); - ResourceRequest request; - request.url = test_server()->GetURL("/nocache.html"); - request.method = "GET"; - request.report_raw_headers = true; - request.request_initiator = url::Origin(); - - StartLoadingURL(request, process_id); - client()->RunUntilComplete(); - EXPECT_FALSE(client()->response_head()->raw_request_response_info); - service()->SetRawHeadersAccess( - process_id, - {url::Origin::CreateFromNormalizedTuple("http", "example.com", 80), - url::Origin::Create(request.url)}); - StartLoadingURL(request, process_id); - client()->RunUntilComplete(); - { - auto& request_response_info = - client()->response_head()->raw_request_response_info; - ASSERT_TRUE(request_response_info); - EXPECT_EQ(200, request_response_info->http_status_code); - EXPECT_EQ("OK", request_response_info->http_status_text); - } - - service()->SetRawHeadersAccess(process_id, {}); - StartLoadingURL(request, process_id); - client()->RunUntilComplete(); - EXPECT_FALSE(client()->response_head()->raw_request_response_info.get()); - - service()->SetRawHeadersAccess( - process_id, - {url::Origin::CreateFromNormalizedTuple("http", "example.com", 80)}); - StartLoadingURL(request, process_id); - client()->RunUntilComplete(); - EXPECT_FALSE(client()->response_head()->raw_request_response_info.get()); } class NetworkServiceTestWithResolverMap : public NetworkServiceTestWithService { @@ -1141,54 +1057,6 @@ } }; -TEST_F(NetworkServiceTestWithResolverMap, RawRequestAccessControlWithRedirect) { - CreateNetworkContext(); - - const uint32_t process_id = 42; - // initial_url in a.test redirects to b_url (in b.test) that then redirects to - // url_a in a.test. - GURL url_a = test_server()->GetURL("a.test", "/echo"); - GURL url_b = - test_server()->GetURL("b.test", "/server-redirect?" + url_a.spec()); - GURL initial_url = - test_server()->GetURL("a.test", "/server-redirect?" + url_b.spec()); - ResourceRequest request; - request.url = initial_url; - request.method = "GET"; - request.report_raw_headers = true; - request.request_initiator = url::Origin(); - - service()->SetRawHeadersAccess(process_id, {url::Origin::Create(url_a)}); - - StartLoadingURL(request, process_id); - client()->RunUntilRedirectReceived(); // from a.test to b.test - EXPECT_TRUE(client()->response_head()->raw_request_response_info); - - loader()->FollowRedirect({}, {}, {}, absl::nullopt); - client()->ClearHasReceivedRedirect(); - client()->RunUntilRedirectReceived(); // from b.test to a.test - EXPECT_FALSE(client()->response_head()->raw_request_response_info); - - loader()->FollowRedirect({}, {}, {}, absl::nullopt); - client()->RunUntilComplete(); // Done loading a.test - EXPECT_TRUE(client()->response_head()->raw_request_response_info.get()); - - service()->SetRawHeadersAccess(process_id, {url::Origin::Create(url_b)}); - - StartLoadingURL(request, process_id); - client()->RunUntilRedirectReceived(); // from a.test to b.test - EXPECT_FALSE(client()->response_head()->raw_request_response_info); - - loader()->FollowRedirect({}, {}, {}, absl::nullopt); - client()->ClearHasReceivedRedirect(); - client()->RunUntilRedirectReceived(); // from b.test to a.test - EXPECT_TRUE(client()->response_head()->raw_request_response_info); - - loader()->FollowRedirect({}, {}, {}, absl::nullopt); - client()->RunUntilComplete(); // Done loading a.test - EXPECT_FALSE(client()->response_head()->raw_request_response_info.get()); -} - TEST_F(NetworkServiceTestWithService, SetNetworkConditions) { const base::UnguessableToken profile_id = base::UnguessableToken::Create(); CreateNetworkContext();
diff --git a/services/network/public/cpp/resource_request.cc b/services/network/public/cpp/resource_request.cc index 184b026..e2e170a 100644 --- a/services/network/public/cpp/resource_request.cc +++ b/services/network/public/cpp/resource_request.cc
@@ -227,7 +227,6 @@ do_not_prompt_for_login == request.do_not_prompt_for_login && is_main_frame == request.is_main_frame && transition_type == request.transition_type && - report_raw_headers == request.report_raw_headers && previews_state == request.previews_state && upgrade_if_insecure == request.upgrade_if_insecure && is_revalidating == request.is_revalidating &&
diff --git a/services/network/public/cpp/resource_request.h b/services/network/public/cpp/resource_request.h index a2ca6e2..1c2aecf 100644 --- a/services/network/public/cpp/resource_request.h +++ b/services/network/public/cpp/resource_request.h
@@ -150,7 +150,6 @@ bool do_not_prompt_for_login = false; bool is_main_frame = false; int transition_type = 0; - bool report_raw_headers = false; int previews_state = 0; bool upgrade_if_insecure = false; bool is_revalidating = false;
diff --git a/services/network/public/cpp/url_request_mojom_traits.cc b/services/network/public/cpp/url_request_mojom_traits.cc index 4deae02..cc75591a 100644 --- a/services/network/public/cpp/url_request_mojom_traits.cc +++ b/services/network/public/cpp/url_request_mojom_traits.cc
@@ -188,7 +188,6 @@ out->do_not_prompt_for_login = data.do_not_prompt_for_login(); out->is_main_frame = data.is_main_frame(); out->transition_type = data.transition_type(); - out->report_raw_headers = data.report_raw_headers(); out->previews_state = data.previews_state(); out->upgrade_if_insecure = data.upgrade_if_insecure(); out->is_revalidating = data.is_revalidating();
diff --git a/services/network/public/cpp/url_request_mojom_traits.h b/services/network/public/cpp/url_request_mojom_traits.h index cda9b2f..7390c69 100644 --- a/services/network/public/cpp/url_request_mojom_traits.h +++ b/services/network/public/cpp/url_request_mojom_traits.h
@@ -253,9 +253,6 @@ static int32_t transition_type(const network::ResourceRequest& request) { return request.transition_type; } - static bool report_raw_headers(const network::ResourceRequest& request) { - return request.report_raw_headers; - } static int32_t previews_state(const network::ResourceRequest& request) { return request.previews_state; }
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 b6c590be..4db56cb 100644 --- a/services/network/public/cpp/url_request_mojom_traits_unittest.cc +++ b/services/network/public/cpp/url_request_mojom_traits_unittest.cc
@@ -84,7 +84,6 @@ original.do_not_prompt_for_login = true; original.is_main_frame = true; original.transition_type = 0; - original.report_raw_headers = true; original.previews_state = 0; original.upgrade_if_insecure = true; original.is_revalidating = false;
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn index 68492d98..0aedffb 100644 --- a/services/network/public/mojom/BUILD.gn +++ b/services/network/public/mojom/BUILD.gn
@@ -172,7 +172,6 @@ "early_hints.mojom", "fetch_api.mojom", "http_raw_headers.mojom", - "http_raw_request_response_info.mojom", "http_request_headers.mojom", "ip_address_space.mojom", "isolation_info.mojom",
diff --git a/services/network/public/mojom/http_raw_request_response_info.mojom b/services/network/public/mojom/http_raw_request_response_info.mojom deleted file mode 100644 index 96e617b7..0000000 --- a/services/network/public/mojom/http_raw_request_response_info.mojom +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2014 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 network.mojom; - -import "services/network/public/mojom/http_raw_headers.mojom"; - -struct HttpRawRequestResponseInfo { - int32 http_status_code; - string http_status_text; // Not present in HTTP/2 - array<HttpRawHeaderPair> request_headers; - array<HttpRawHeaderPair> response_headers; - string request_headers_text; - string response_headers_text; -};
diff --git a/services/network/public/mojom/url_request.mojom b/services/network/public/mojom/url_request.mojom index f336937..4b0ba93a 100644 --- a/services/network/public/mojom/url_request.mojom +++ b/services/network/public/mojom/url_request.mojom
@@ -303,12 +303,6 @@ // about this. int32 transition_type; - // Whether to intercept headers to pass back to the renderer. - // This also enables reporting of SSLInfo in URLLoaderClient's - // OnResponseReceived and OnComplete, as well as invocation of - // OnTransferSizeUpdated(). - bool report_raw_headers; - // Whether or not to request a Preview version of the resource or let the // browser decide. // Note: this is an enum of type PreviewsState.
diff --git a/services/network/public/mojom/url_response_head.mojom b/services/network/public/mojom/url_response_head.mojom index 9518e78..cea1fb8 100644 --- a/services/network/public/mojom/url_response_head.mojom +++ b/services/network/public/mojom/url_response_head.mojom
@@ -7,7 +7,6 @@ import "mojo/public/mojom/base/time.mojom"; import "mojo/public/mojom/base/unguessable_token.mojom"; import "services/network/public/mojom/fetch_api.mojom"; -import "services/network/public/mojom/http_raw_request_response_info.mojom"; import "services/network/public/mojom/ip_endpoint.mojom"; import "services/network/public/mojom/load_timing_info.mojom"; import "services/network/public/mojom/network_param.mojom"; @@ -67,11 +66,6 @@ // Tools. Includes socket ID and socket reuse information. LoadTimingInfo load_timing; - // Actual request and response headers, as obtained from the network stack. - // Only present if the renderer set report_raw_headers to true and had the - // CanReadRawCookies permission. - HttpRawRequestResponseInfo? raw_request_response_info; - // True if the response was delivered using SPDY. bool was_fetched_via_spdy = false; @@ -145,7 +139,7 @@ // Only provided if kURLLoadOptionSendSSLInfoWithResponse was specified to // the URLLoaderFactory::CreateLoaderAndStart option or - // if ResourceRequest::report_raw_headers is set. When set via + // if ResourceRequest::devtools_request_id is set. When set via // |report_raw_headers|, the SSLInfo is not guaranteed to be fully populated // and may only contain certain fields of interest (namely, connection // parameters and certificate information).
diff --git a/services/network/test/test_url_loader_factory_unittest.cc b/services/network/test/test_url_loader_factory_unittest.cc index 57d28faf..c940d975 100644 --- a/services/network/test/test_url_loader_factory_unittest.cc +++ b/services/network/test/test_url_loader_factory_unittest.cc
@@ -24,12 +24,10 @@ void StartRequest(const std::string& url, TestURLLoaderClient* client, - int load_flags = 0, - bool report_raw_headers = false) { + int load_flags = 0) { ResourceRequest request; request.url = GURL(url); request.load_flags = load_flags; - request.report_raw_headers = report_raw_headers; loader_.reset(); factory_.CreateLoaderAndStart( loader_.BindNewPipeAndPassReceiver(), 0, 0, request, @@ -360,33 +358,6 @@ EXPECT_TRUE(factory()->SimulateResponseForPendingRequest( GURL(url), ok_status, std::move(response_head), /*content=*/"")); EXPECT_TRUE(client()->has_received_completion()); - EXPECT_FALSE(client()->response_head()->raw_request_response_info); -} - -TEST_F(TestURLLoaderFactoryTest, SimulateResponseReportRawHeaders) { - std::string url = "http://foo/"; - std::string cookie_line = "my_cookie=myvalue"; - - TestURLLoaderClient client; - StartRequest(url, &client, /*load_flags=*/0, /*report_raw_headers=*/true); - network::URLLoaderCompletionStatus ok_status(net::OK); - mojom::URLResponseHeadPtr response_head = - CreateURLResponseHead(net::HTTP_NOT_FOUND, /*report_raw_headers=*/true); - AddCookiesToURLResponseHead({cookie_line}, response_head.get()); - EXPECT_TRUE(factory()->SimulateResponseForPendingRequest( - GURL(url), ok_status, std::move(response_head), /*content=*/"hello")); - EXPECT_TRUE(client.has_received_completion()); - auto& raw_response_info = client.response_head()->raw_request_response_info; - ASSERT_TRUE(raw_response_info); - EXPECT_EQ(net::HTTP_NOT_FOUND, raw_response_info->http_status_code); - auto& headers = raw_response_info->response_headers; - int cookie_count = 0; - for (auto iter = headers.begin(); iter != headers.end(); ++iter) { - if ((*iter)->key == "Set-Cookie") { - cookie_count++; - EXPECT_EQ(cookie_line, (*iter)->value); - } - } } TEST_F(TestURLLoaderFactoryTest,
diff --git a/services/network/test/test_utils.cc b/services/network/test/test_utils.cc index 48d641d..3a4aaad4 100644 --- a/services/network/test/test_utils.cc +++ b/services/network/test/test_utils.cc
@@ -8,8 +8,8 @@ #include "build/build_config.h" #include "net/http/http_util.h" #include "net/proxy_resolution/proxy_config_with_annotation.h" -#include "services/network/public/cpp/http_raw_request_response_info.h" #include "services/network/public/cpp/resource_request.h" +#include "services/network/public/mojom/http_raw_headers.mojom.h" #include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" @@ -30,8 +30,8 @@ return std::string(element.As<DataElementBytes>().AsStringPiece()); } -mojom::URLResponseHeadPtr CreateURLResponseHead(net::HttpStatusCode http_status, - bool report_raw_headers) { +mojom::URLResponseHeadPtr CreateURLResponseHead( + net::HttpStatusCode http_status) { auto head = mojom::URLResponseHead::New(); std::string status_line( base::StringPrintf("HTTP/1.1 %d %s", static_cast<int>(http_status), @@ -39,11 +39,6 @@ std::string headers = status_line + "\nContent-type: text/html\n\n"; head->headers = base::MakeRefCounted<net::HttpResponseHeaders>( net::HttpUtil::AssembleRawHeaders(headers)); - if (report_raw_headers) { - head->raw_request_response_info = mojom::HttpRawRequestResponseInfo::New(); - head->raw_request_response_info->http_status_text = status_line; - head->raw_request_response_info->http_status_code = http_status; - } return head; } @@ -51,10 +46,6 @@ mojom::URLResponseHead* response_head) { for (const auto& cookie_string : cookies) { response_head->headers->AddCookie(cookie_string); - if (response_head->raw_request_response_info) { - response_head->raw_request_response_info->response_headers.push_back( - mojom::HttpRawHeaderPair::New("Set-Cookie", cookie_string)); - } } }
diff --git a/services/network/test/test_utils.h b/services/network/test/test_utils.h index d4f717c..7599a55 100644 --- a/services/network/test/test_utils.h +++ b/services/network/test/test_utils.h
@@ -24,8 +24,7 @@ // reported by the network stack (it's useful to report cookies, for example, // as they are filtered out of the net::HttpResponseHeaders when serialized). mojom::URLResponseHeadPtr CreateURLResponseHead( - net::HttpStatusCode http_status, - bool report_raw_headers = false); + net::HttpStatusCode http_status); // Adds cookies to the passed in mojom::URLResponseHead. If it was created with // |report_raw_headers| true, the cookies are also added to the raw headers.
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 34703874..d22c722 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -76,6 +76,7 @@ #include "services/network/public/mojom/devtools_observer.mojom.h" #include "services/network/public/mojom/early_hints.mojom.h" #include "services/network/public/mojom/fetch_api.mojom.h" +#include "services/network/public/mojom/http_raw_headers.mojom.h" #include "services/network/public/mojom/origin_policy_manager.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" @@ -333,57 +334,6 @@ net::CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY); } -mojom::HttpRawRequestResponseInfoPtr BuildRawRequestResponseInfo( - const net::URLRequest& request, - const net::HttpRawRequestHeaders& raw_request_headers, - const net::HttpResponseHeaders* raw_response_headers) { - auto info = mojom::HttpRawRequestResponseInfo::New(); - - const net::HttpResponseInfo& response_info = request.response_info(); - // Unparsed headers only make sense if they were sent as text, i.e. HTTP 1.x. - bool report_headers_text = - !response_info.DidUseQuic() && !response_info.was_fetched_via_spdy; - - for (const auto& pair : raw_request_headers.headers()) { - info->request_headers.push_back( - mojom::HttpRawHeaderPair::New(pair.first, pair.second)); - } - std::string request_line = raw_request_headers.request_line(); - if (report_headers_text && !request_line.empty()) { - std::string text = std::move(request_line); - for (const auto& pair : raw_request_headers.headers()) { - if (!pair.second.empty()) { - base::StringAppendF(&text, "%s: %s\r\n", pair.first.c_str(), - pair.second.c_str()); - } else { - base::StringAppendF(&text, "%s:\r\n", pair.first.c_str()); - } - } - info->request_headers_text = std::move(text); - } - - if (!raw_response_headers) - raw_response_headers = request.response_headers(); - if (raw_response_headers) { - info->http_status_code = raw_response_headers->response_code(); - info->http_status_text = raw_response_headers->GetStatusText(); - - std::string name; - std::string value; - for (size_t it = 0; - raw_response_headers->EnumerateHeaderLines(&it, &name, &value);) { - info->response_headers.push_back( - mojom::HttpRawHeaderPair::New(name, value)); - } - if (report_headers_text) { - info->response_headers_text = - net::HttpUtil::ConvertHeadersBackToHTTPResponse( - raw_response_headers->raw_headers()); - } - } - return info; -} - // Concerning headers that consumers probably shouldn't be allowed to set. // Gathering numbers on these before adding them to kUnsafeHeaders. const struct { @@ -533,7 +483,6 @@ peer_closed_handle_watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, base::SequencedTaskRunnerHandle::Get()), - want_raw_headers_(request.report_raw_headers), devtools_request_id_(request.devtools_request_id), request_mode_(request.mode), request_credentials_mode_(request.credentials_mode), @@ -570,7 +519,7 @@ header_client_.set_disconnect_handler( base::BindOnce(&URLLoader::OnMojoDisconnect, base::Unretained(this))); } - if (want_raw_headers_) { + if (devtools_request_id()) { options_ |= mojom::kURLLoadOptionSendSSLInfoWithResponse | mojom::kURLLoadOptionSendSSLInfoForCertificateError; } @@ -671,7 +620,7 @@ url_request_->SetRequestHeadersCallback(base::BindRepeating( &URLLoader::SetRawRequestHeadersAndNotify, base::Unretained(this))); - if (want_raw_headers_) { + if (devtools_request_id()) { url_request_->SetResponseHeadersCallback(base::BindRepeating( &URLLoader::SetRawResponseHeaders, base::Unretained(this))); } @@ -1153,12 +1102,6 @@ auto response = network::mojom::URLResponseHead::New(); PopulateResourceResponse(url_request_.get(), is_load_timing_enabled_, options_, response.get()); - if (report_raw_headers_) { - response->raw_request_response_info = BuildRawRequestResponseInfo( - *url_request_, raw_request_headers_, raw_response_headers_.get()); - raw_request_headers_ = net::HttpRawRequestHeaders(); - raw_response_headers_ = nullptr; - } ReportFlaggedResponseCookies(); @@ -1303,12 +1246,6 @@ response_ = network::mojom::URLResponseHead::New(); PopulateResourceResponse(url_request_.get(), is_load_timing_enabled_, options_, response_.get()); - if (report_raw_headers_) { - response_->raw_request_response_info = BuildRawRequestResponseInfo( - *url_request_, raw_request_headers_, raw_response_headers_.get()); - raw_request_headers_ = net::HttpRawRequestHeaders(); - raw_response_headers_ = nullptr; - } // Parse and remove the Trust Tokens response headers, if any are expected, // potentially failing the request if an error occurs. @@ -1704,8 +1641,8 @@ return factory_params_->process_id; } -void URLLoader::SetAllowReportingRawHeaders(bool allow) { - report_raw_headers_ = want_raw_headers_ && allow; +void URLLoader::SetEnableReportingRawHeaders(bool allow) { + enable_reporting_raw_headers_ = allow; } uint32_t URLLoader::GetResourceType() const { @@ -1992,7 +1929,7 @@ } } - if (want_raw_headers_) + if (devtools_request_id()) raw_request_headers_.Assign(std::move(headers)); } @@ -2164,10 +2101,23 @@ url_request_->response_headers()) { std::vector<network::mojom::HttpRawHeaderPairPtr> header_array; + // This is gated by enable_reporting_raw_headers_ to be backwards compatible + // with the old report_raw_headers behavior, where we wouldn't even send + // raw_response_headers_ to the trusted browser process based devtools + // instrumentation. This is observed in the case of HSTS redirects, where + // url_request_->response_headers has the HSTS redirect headers, like + // Non-Authoritative-Reason, but raw_response_headers_ has something else + // which doesn't include HSTS information. This is tested by + // DevToolsTest.TestRawHeadersWithRedirectAndHSTS. + // TODO(crbug.com/1234823): Remove enable_reporting_raw_headers_ + const net::HttpResponseHeaders* response_headers = + raw_response_headers_ && enable_reporting_raw_headers_ + ? raw_response_headers_.get() + : url_request_->response_headers(); + size_t iterator = 0; std::string name, value; - while (url_request_->response_headers()->EnumerateHeaderLines( - &iterator, &name, &value)) { + while (response_headers->EnumerateHeaderLines(&iterator, &name, &value)) { network::mojom::HttpRawHeaderPairPtr pair = network::mojom::HttpRawHeaderPair::New(); pair->key = name; @@ -2184,14 +2134,14 @@ if (!response_info.DidUseQuic() && !response_info.was_fetched_via_spdy) { raw_response_headers = absl::make_optional(net::HttpUtil::ConvertHeadersBackToHTTPResponse( - url_request_->response_headers()->raw_headers())); + response_headers->raw_headers())); } devtools_observer->OnRawResponse( devtools_request_id().value(), url_request_->maybe_stored_cookies(), std::move(header_array), raw_response_headers, IPEndPointToIPAddressSpace(response_info.remote_endpoint), - url_request_->response_headers()->response_code()); + response_headers->response_code()); } if (auto* cookie_observer = GetCookieAccessObserver()) {
diff --git a/services/network/url_loader.h b/services/network/url_loader.h index 8e85379..0f3f95a 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h
@@ -233,7 +233,7 @@ return url_loader_factory_; } - void SetAllowReportingRawHeaders(bool allow); + void SetEnableReportingRawHeaders(bool enable); mojom::LoadInfoPtr CreateLoadInfo(); @@ -466,10 +466,7 @@ std::unique_ptr<ResourceScheduler::ScheduledResourceRequest> resource_scheduler_request_handle_; - // Whether client requested raw headers. - const bool want_raw_headers_; - // Whether we actually should report them. - bool report_raw_headers_ = false; + bool enable_reporting_raw_headers_ = false; net::HttpRawRequestHeaders raw_request_headers_; scoped_refptr<const net::HttpResponseHeaders> raw_response_headers_;
diff --git a/services/network/web_bundle_url_loader_factory.cc b/services/network/web_bundle_url_loader_factory.cc index bfbbb3e8..b377f46 100644 --- a/services/network/web_bundle_url_loader_factory.cc +++ b/services/network/web_bundle_url_loader_factory.cc
@@ -18,6 +18,7 @@ #include "services/network/public/cpp/cross_origin_read_blocking.h" #include "services/network/public/cpp/resource_request.h" #include "services/network/public/mojom/early_hints.mojom.h" +#include "services/network/public/mojom/http_raw_headers.mojom.h" #include "services/network/public/mojom/url_loader.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" #include "services/network/web_bundle_chunked_buffer.h"
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index 0fc20da..0657d8e 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -4592,6 +4592,7 @@ "--avd-config=../../tools/android/avd/proto/generic_android30.textpb", "--gtest_filter=-org.chromium.weblayer.test.MediaCaptureTest.*" ], + "experiment_percentage": 100, "merge": { "args": [ "--bucket", @@ -10245,6 +10246,16 @@ "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" } ], + "dimension_sets": [ + { + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "machine_type": "e2-standard-8", + "os": "Ubuntu-16.04|Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], "named_caches": [ { "name": "avd_generic_android29", @@ -10305,6 +10316,16 @@ "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" } ], + "dimension_sets": [ + { + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "machine_type": "e2-standard-8", + "os": "Ubuntu-16.04|Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], "named_caches": [ { "name": "avd_generic_android29", @@ -10365,6 +10386,16 @@ "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" } ], + "dimension_sets": [ + { + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "machine_type": "e2-standard-8", + "os": "Ubuntu-16.04|Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], "named_caches": [ { "name": "avd_generic_android29", @@ -10425,6 +10456,16 @@ "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" } ], + "dimension_sets": [ + { + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "machine_type": "e2-standard-8", + "os": "Ubuntu-16.04|Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], "named_caches": [ { "name": "avd_generic_android29", @@ -10485,6 +10526,16 @@ "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" } ], + "dimension_sets": [ + { + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "machine_type": "e2-standard-8", + "os": "Ubuntu-16.04|Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], "named_caches": [ { "name": "avd_generic_android29", @@ -10545,6 +10596,16 @@ "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" } ], + "dimension_sets": [ + { + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "machine_type": "e2-standard-8", + "os": "Ubuntu-16.04|Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], "named_caches": [ { "name": "avd_generic_android29", @@ -10606,6 +10667,16 @@ "revision": "git_revision:ff387eadf445b24c935f1cf7d6ddd279f8a6b04c" } ], + "dimension_sets": [ + { + "cpu": "x86-64", + "device_os": null, + "device_type": null, + "machine_type": "e2-standard-8", + "os": "Ubuntu-16.04|Ubuntu-18.04", + "pool": "chromium.tests.avd" + } + ], "named_caches": [ { "name": "avd_generic_android29",
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 303df54..7e483990 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -48600,57 +48600,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "absl_hardening_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "absl_hardening_tests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -48702,57 +48651,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -48804,57 +48702,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -48906,57 +48753,6 @@ "--platform", "iPhone 6s Plus", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests_iPhone 6s Plus 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -49008,57 +48804,6 @@ "--platform", "iPhone SE (1st generation)", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "base_unittests_iPhone SE (1st generation) 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://base:base_unittests/" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -49110,57 +48855,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "boringssl_crypto_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "boringssl_crypto_tests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -49212,57 +48906,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "boringssl_ssl_tests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "boringssl_ssl_tests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -49314,57 +48957,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -49416,57 +49008,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -49518,57 +49059,6 @@ "--platform", "iPhone 6s Plus", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests_iPhone 6s Plus 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -49620,57 +49110,6 @@ "--platform", "iPhone SE (1st generation)", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "components_unittests_iPhone SE (1st generation) 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://components:components_unittests/" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -49722,57 +49161,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "crypto_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "crypto_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://crypto:crypto_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -49824,57 +49212,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -49926,57 +49263,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -50028,57 +49314,6 @@ "--platform", "iPhone 6s Plus", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests_iPhone 6s Plus 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -50130,57 +49365,6 @@ "--platform", "iPhone SE (1st generation)", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "gfx_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "gfx_unittests_iPhone SE (1st generation) 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -50232,57 +49416,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "google_apis_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "google_apis_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://google_apis:google_apis_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -50334,58 +49467,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_bookmarks_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_eg2tests_module_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -50438,58 +49519,6 @@ "--platform", "iPhone 7", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_bookmarks_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_eg2tests_module_iPhone 7 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -50542,58 +49571,6 @@ "--platform", "iPhone X", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_bookmarks_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_bookmarks_eg2tests_module_iPhone X 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_bookmarks_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -50646,59 +49623,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_integration_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_integration_eg2tests_module_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -50803,112 +49727,6 @@ { "args": [ "--platform", - "iPhone 6s", - "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_integration_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_integration_eg2tests_module_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_integration_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_integration_eg2tests_module_iPhone 7 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_integration_eg2tests_module/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "14.5", @@ -50964,59 +49782,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_settings_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_eg2tests_module_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -51070,59 +49835,6 @@ "--platform", "iPhone 7", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_settings_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_eg2tests_module_iPhone 7 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -51176,59 +49888,6 @@ "--platform", "iPhone X", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_settings_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_settings_eg2tests_module_iPhone X 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_settings_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -51282,58 +49941,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_signin_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_signin_eg2tests_module_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -51436,110 +50043,6 @@ { "args": [ "--platform", - "iPhone 6s", - "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_signin_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_signin_eg2tests_module_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_signin_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_signin_eg2tests_module_iPhone 7 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_signin_eg2tests_module/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "14.5", @@ -51594,58 +50097,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_smoke_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_smoke_eg2tests_module_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -51698,58 +50149,6 @@ "--platform", "iPhone 7", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_smoke_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_smoke_eg2tests_module_iPhone 7 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -51802,58 +50201,6 @@ "--platform", "iPhone X", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_smoke_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_smoke_eg2tests_module_iPhone X 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_smoke_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -51906,59 +50253,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_ui_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_ui_eg2tests_module_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 5 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -52063,112 +50357,6 @@ { "args": [ "--platform", - "iPhone 6s", - "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_ui_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_ui_eg2tests_module_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 5 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_ui_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_ui_eg2tests_module_iPhone 7 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 5 - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_ui_eg2tests_module/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "14.5", @@ -52224,57 +50412,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -52326,57 +50463,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -52428,57 +50514,6 @@ "--platform", "iPhone 6s Plus", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests_iPhone 6s Plus 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -52530,57 +50565,6 @@ "--platform", "iPhone SE (1st generation)", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_chrome_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_unittests_iPhone SE (1st generation) 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test:ios_chrome_unittests/" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -52632,58 +50616,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_web_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_eg2tests_module_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -52736,58 +50668,6 @@ "--platform", "iPhone 7", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_web_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_eg2tests_module_iPhone 7 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -52840,58 +50720,6 @@ "--platform", "iPhone X", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_chrome_web_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_chrome_web_eg2tests_module_iPhone X 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/chrome/test/earl_grey2:ios_chrome_web_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -52944,57 +50772,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_components_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_components_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/components:ios_components_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -53046,57 +50823,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_net_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_net_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/net:ios_net_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -53148,57 +50874,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_remoting_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_remoting_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://remoting/ios:ios_remoting_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -53250,58 +50925,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_showcase_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_eg2tests_module_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -53354,58 +50977,6 @@ "--platform", "iPhone 7", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_showcase_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_eg2tests_module_iPhone 7 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -53458,58 +51029,6 @@ "--platform", "iPhone X", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_showcase_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_showcase_eg2tests_module_iPhone X 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/showcase:ios_showcase_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone X", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -53562,57 +51081,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_testing_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_testing_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/testing:ios_testing_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -53664,57 +51132,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -53766,57 +51183,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -53868,57 +51234,6 @@ "--platform", "iPhone 6s Plus", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests_iPhone 6s Plus 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -53970,57 +51285,6 @@ "--platform", "iPhone SE (1st generation)", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_inttests_iPhone SE (1st generation) 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_inttests/" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -54072,58 +51336,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_web_shell_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_shell_eg2tests_module_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -54226,110 +51438,6 @@ { "args": [ "--platform", - "iPhone 6s", - "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_web_shell_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_shell_eg2tests_module_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/" - }, - { - "args": [ - "--platform", - "iPhone 7", - "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest", - "--xcode-parallelization" - ], - "isolate_name": "ios_web_shell_eg2tests_module", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_shell_eg2tests_module_iPhone 7 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web/shell/test:ios_web_shell_eg2tests_module/" - }, - { - "args": [ - "--platform", "iPhone X", "--version", "14.5", @@ -54384,57 +51492,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -54486,57 +51543,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -54588,57 +51594,6 @@ "--platform", "iPhone 6s Plus", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests_iPhone 6s Plus 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -54690,57 +51645,6 @@ "--platform", "iPhone SE (1st generation)", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_unittests_iPhone SE (1st generation) 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web:ios_web_unittests/" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -54792,57 +51696,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -54894,57 +51747,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -54996,57 +51798,6 @@ "--platform", "iPhone 6s Plus", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests_iPhone 6s Plus 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -55098,57 +51849,6 @@ "--platform", "iPhone SE (1st generation)", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_view_inttests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_inttests_iPhone SE (1st generation) 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_inttests/" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -55200,57 +51900,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -55302,57 +51951,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -55404,57 +52002,6 @@ "--platform", "iPhone 6s Plus", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests_iPhone 6s Plus 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -55506,57 +52053,6 @@ "--platform", "iPhone SE (1st generation)", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ios_web_view_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ios_web_view_unittests_iPhone SE (1st generation) 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ios/web_view:ios_web_view_unittests/" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -55608,57 +52104,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "net_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "net_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://net:net_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -55710,57 +52155,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "services_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "services_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://services:services_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -55812,57 +52206,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -55914,57 +52257,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -56016,57 +52308,6 @@ "--platform", "iPhone 6s Plus", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests_iPhone 6s Plus 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -56118,57 +52359,6 @@ "--platform", "iPhone SE (1st generation)", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "skia_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "skia_unittests_iPhone SE (1st generation) 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://skia:skia_unittests/" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -56220,57 +52410,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "sql_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "sql_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://sql:sql_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -56322,57 +52461,6 @@ "--platform", "iPad Air 2", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests_iPad Air 2 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/" - }, - { - "args": [ - "--platform", - "iPad Air 2", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -56424,57 +52512,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -56526,57 +52563,6 @@ "--platform", "iPhone 6s Plus", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests_iPhone 6s Plus 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s Plus", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -56628,57 +52614,6 @@ "--platform", "iPhone SE (1st generation)", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "ui_base_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "ui_base_unittests_iPhone SE (1st generation) 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://ui/base:ui_base_unittests/" - }, - { - "args": [ - "--platform", - "iPhone SE (1st generation)", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}", @@ -56730,57 +52665,6 @@ "--platform", "iPhone 6s", "--version", - "13.6", - "--out-dir", - "${ISOLATED_OUTDIR}", - "--xcode-build-version", - "12e262", - "--xctest" - ], - "isolate_name": "url_unittests", - "merge": { - "args": [], - "script": "//testing/merge_scripts/standard_isolated_script_merge.py" - }, - "name": "url_unittests_iPhone 6s 13.6", - "resultdb": { - "enable": true, - "has_native_resultdb_integration": true - }, - "swarming": { - "can_use_on_swarming_builders": true, - "cipd_packages": [ - { - "cipd_package": "infra/tools/mac_toolchain/${platform}", - "location": ".", - "revision": "git_revision:723fc1a6c8cdf2631a57851f5610e598db0c1de1" - } - ], - "dimension_sets": [ - { - "cpu": "arm64", - "os": "Mac-11" - } - ], - "named_caches": [ - { - "name": "xcode_ios_12e262", - "path": "Xcode.app" - }, - { - "name": "runtime_ios_13_6", - "path": "Runtime-ios-13.6" - } - ], - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" - }, - "test_id_prefix": "ninja://url:url_unittests/" - }, - { - "args": [ - "--platform", - "iPhone 6s", - "--version", "14.5", "--out-dir", "${ISOLATED_OUTDIR}",
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl index 0619139..525529f 100644 --- a/testing/buildbot/mixins.pyl +++ b/testing/buildbot/mixins.pyl
@@ -485,18 +485,6 @@ ], }, }, - 'ios_runtime_cache_13_6': { - '$mixin_append': { - 'swarming': { - 'named_caches': [ - { - 'name': 'runtime_ios_13_6', - 'path': 'Runtime-ios-13.6', - }, - ], - }, - }, - }, 'ios_runtime_cache_14_4': { '$mixin_append': { 'swarming': {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 1ca1f86..018b83ca5 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -3205,6 +3205,8 @@ 'args': [ '--gtest_filter=-org.chromium.weblayer.test.MediaCaptureTest.*', ], + # TODO(crbug.com/1137474): Remove after the test suite is green. + 'experiment_percentage': 100, }, }, },
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index faefa7d..610acea 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -7016,7 +7016,6 @@ 'variants': [ # Latest beta iOS version Sims 'SIM_IPHONE_6S_14_5', - 'SIM_IPHONE_6S_13_6', ], }, 'ios_eg2_tests': { @@ -7026,9 +7025,6 @@ 'SIM_IPHONE_7_14_5', 'SIM_IPAD_AIR_2_14_5', 'SIM_IPHONE_X_14_5', - 'SIM_IPHONE_7_13_6', - 'SIM_IPAD_AIR_2_13_6', - 'SIM_IPHONE_X_13_6', ] }, 'ios_eg2_cq_tests': { @@ -7038,9 +7034,6 @@ 'SIM_IPHONE_X_14_5', 'SIM_IPAD_AIR_2_14_5', 'SIM_IPAD_PRO_2ND_GEN_14_5', - 'SIM_IPHONE_7_13_6', - 'SIM_IPAD_AIR_2_13_6', - 'SIM_IPHONE_6S_13_6', ] }, 'ios_screen_size_dependent_tests': { @@ -7050,10 +7043,6 @@ 'SIM_IPHONE_6S_14_5', 'SIM_IPHONE_SE_1ST_GEN_14_5', 'SIM_IPAD_AIR_2_14_5', - 'SIM_IPHONE_6S_PLUS_13_6', - 'SIM_IPHONE_6S_13_6', - 'SIM_IPHONE_SE_1ST_GEN_13_6', - 'SIM_IPAD_AIR_2_13_6', ], }, },
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index bce569f..8019fe93 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -76,18 +76,6 @@ ], }, }, - 'SIM_IPAD_AIR_2_13_6': { - 'args': [ - '--platform', - 'iPad Air 2', - '--version', - '13.6' - ], - 'identifier': 'iPad Air 2 13.6', - 'mixins': [ - 'ios_runtime_cache_13_6', - ], - }, 'SIM_IPAD_AIR_2_14_4': { 'args': [ '--platform', @@ -162,18 +150,6 @@ 'ios_runtime_cache_14_5', ], }, - 'SIM_IPHONE_6S_13_6': { - 'args': [ - '--platform', - 'iPhone 6s', - '--version', - '13.6', - ], - 'identifier': 'iPhone 6s 13.6', - 'mixins': [ - 'ios_runtime_cache_13_6', - ], - }, 'SIM_IPHONE_6S_14_4': { 'args': [ '--platform', @@ -210,18 +186,6 @@ 'ios_runtime_cache_15_0', ], }, - 'SIM_IPHONE_6S_PLUS_13_6': { - 'args': [ - '--platform', - 'iPhone 6s Plus', - '--version', - '13.6', - ], - 'identifier': 'iPhone 6s Plus 13.6', - 'mixins': [ - 'ios_runtime_cache_13_6', - ], - }, 'SIM_IPHONE_6S_PLUS_14_4': { 'args': [ '--platform', @@ -258,18 +222,6 @@ 'ios_runtime_cache_15_0', ], }, - 'SIM_IPHONE_7_13_6': { - 'args': [ - '--platform', - 'iPhone 7', - '--version', - '13.6', - ], - 'identifier': 'iPhone 7 13.6', - 'mixins': [ - 'ios_runtime_cache_13_6', - ], - }, 'SIM_IPHONE_7_14_4': { 'args': [ '--platform', @@ -306,18 +258,6 @@ 'ios_runtime_cache_15_0', ], }, - 'SIM_IPHONE_SE_1ST_GEN_13_6': { - 'args': [ - '--platform', - 'iPhone SE (1st generation)', - '--version', - '13.6', - ], - 'identifier': 'iPhone SE (1st generation) 13.6', - 'mixins': [ - 'ios_runtime_cache_13_6', - ], - }, 'SIM_IPHONE_SE_1ST_GEN_14_4': { 'args': [ '--platform', @@ -354,18 +294,6 @@ 'ios_runtime_cache_15_0', ], }, - 'SIM_IPHONE_X_13_6': { - 'args': [ - '--platform', - 'iPhone X', - '--version', - '13.6', - ], - 'identifier': 'iPhone X 13.6', - 'mixins': [ - 'ios_runtime_cache_13_6', - ], - }, 'SIM_IPHONE_X_14_4': { 'args': [ '--platform', @@ -698,4 +626,4 @@ ], }, }, -} \ No newline at end of file +}
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index d2495c4..a0f3c76 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -1005,13 +1005,16 @@ }, 'android-cronet-x86-dbg-10-tests': { 'mixins': [ - 'has_native_resultdb_integration', '10-x86-emulator', + 'emulator-8-cores', + 'has_native_resultdb_integration', + 'linux-xenial-or-bionic', + 'x86-64', ], + 'os_type': 'android', 'test_suites': { 'gtest_tests': 'cronet_gtests', }, - 'os_type': 'android', }, 'android-pie-arm64-wpt-rel-non-cq': { 'mixins': [
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 4aef31c..b75e286 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -7392,6 +7392,28 @@ "disable_features": [ "ClientSideDetectionModelIsFlatBuffer" ] + }, + { + "name": "EnabledTfLiteOnly_20210723", + "params": { + "reporter_omaha_tag": "25.4" + }, + "enable_features": [ + "ClientSideDetectionModelIsFlatBuffer", + "ClientSideDetectionModelOnAndroid", + "ClientSideDetectionTag" + ] + }, + { + "name": "EnabledTfLiteAndFlatbuffer_20210723", + "params": { + "reporter_omaha_tag": "25.5" + }, + "enable_features": [ + "ClientSideDetectionModelIsFlatBuffer", + "ClientSideDetectionModelOnAndroid", + "ClientSideDetectionTag" + ] } ] }
diff --git a/third_party/blink/PRESUBMIT.py b/third_party/blink/PRESUBMIT.py index ed4f38c..6239517 100644 --- a/third_party/blink/PRESUBMIT.py +++ b/third_party/blink/PRESUBMIT.py
@@ -231,12 +231,35 @@ return results +def _CheckForDeprecatedFunctions(input_api, output_api): + """Checks that Blink does not use deprecated functions.""" + # TODO(https://crbug.com/1058527) Remove this presubmit once we've finished + # the refactor and no callers of `WTF::HashMap::DeprecatedAtOrEmptyValue()` remain. + deprecated_re = input_api.re.compile( + r'[^/][^/].*\bDeprecatedAtOrEmptyValue\b') + errors = input_api.canned_checks._FindNewViolationsOfRule( + lambda _, x: not deprecated_re.search(x), input_api, None) + errors = [' * %s' % violation for violation in errors] + if errors: + return [ + output_api.PresubmitPromptOrNotify( + 'WTF::HashMap::DeprecatedAtOrEmptyValue() is deprecated. Please use ' + 'at() moving forward. Note that at() will crash if the HashMap ' + 'does not contain the given key, so it is recommended to use ' + 'find() or Contains() if you are not sure. Please fix the ' + 'following occurrences before uploading:\n%s' % + '\n'.join(errors)) + ] + return [] + + def CheckChangeOnUpload(input_api, output_api): results = [] results.extend(_CommonChecks(input_api, output_api)) results.extend(_CheckStyle(input_api, output_api)) results.extend(_CheckForPrintfDebugging(input_api, output_api)) results.extend(_CheckForForbiddenChromiumCode(input_api, output_api)) + results.extend(_CheckForDeprecatedFunctions(input_api, output_api)) return results
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 7738595..6ddc54c2e 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -245,11 +245,6 @@ #endif }; -// Kill switch for getCurrentBrowsingContextMedia(), which allows capturing of -// web content from the tab from which it is called. (crbug.com/1136940) -const base::Feature kRTCGetCurrentBrowsingContextMedia{ - "RTCGetCurrentBrowsingContextMedia", base::FEATURE_ENABLED_BY_DEFAULT}; - // Changes the default RTCPeerConnection constructor behavior to use Unified // Plan as the SDP semantics. When the feature is enabled, Unified Plan is used // unless the default is overridden (by passing {sdpSemantics:'plan-b'} as the
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 487a38d..871e39e9 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -217,7 +217,6 @@ "platform/web_graphics_context_3d_provider.h", "platform/web_http_body.h", "platform/web_http_header_visitor.h", - "platform/web_http_load_info.h", "platform/web_icon_sizes_parser.h", "platform/web_image_generator.h", "platform/web_impression.h",
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index f3ff92b..52bcc82 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -82,8 +82,6 @@ kPreviewsResourceLoadingHintsSpecificResourceTypes; BLINK_COMMON_EXPORT extern const base::Feature kPurgeRendererMemoryWhenBackgrounded; -BLINK_COMMON_EXPORT extern const base::Feature - kRTCGetCurrentBrowsingContextMedia; BLINK_COMMON_EXPORT extern const base::Feature kRTCUnifiedPlanByDefault; BLINK_COMMON_EXPORT extern const base::Feature kRTCDisallowPlanBOutsideDeprecationTrial;
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index c207537..88a7d64 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -4935,14 +4935,14 @@ string statusText # HTTP response headers. Headers headers - # HTTP response headers text. - optional string headersText + # HTTP response headers text. This has been replaced by the headers in Network.responseReceivedExtraInfo. + deprecated optional string headersText # Resource mimeType as determined by the browser. string mimeType # Refined HTTP request headers that were actually transmitted over the network. optional Headers requestHeaders - # HTTP request headers text. - optional string requestHeadersText + # HTTP request headers text. This has been replaced by the headers in Network.requestWillBeSentExtraInfo. + deprecated optional string requestHeadersText # Specifies whether physical connection was actually reused for this request. boolean connectionReused # Physical connection id that was actually used for this request. @@ -5953,7 +5953,8 @@ # established the connection, so we can't send it in `requestWillBeSentExtraInfo`. IPAddressSpace resourceIPAddressSpace # The status code of the response. This is useful in cases the request failed and no responseReceived - # event is triggered, which is the case for, e.g., CORS errors. + # event is triggered, which is the case for, e.g., CORS errors. This is also the correct status code + # for cached requests, where the status in responseReceived is a 200 and this will be 304. integer statusCode # Raw response header text as it was received over the wire. The raw text may not always be # available, such as in the case of HTTP/2 or QUIC. @@ -9155,6 +9156,8 @@ optional binary postData # If set, overrides the request headers. optional array of HeaderEntry headers + # If set, overrides response interception behavior for this request. + experimental optional boolean interceptResponse # Continues a request supplying authChallengeResponse following authRequired event. command continueWithAuth
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 4d73405..760df7c8 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -3022,7 +3022,7 @@ kOBSOLETE_CSSPseudoHostCompoundList = 3716, kOBSOLETE_CSSPseudoHostContextCompoundList = 3717, kOBSOLETE_CSSPseudoHostDynamicSpecificity = 3718, - kGetCurrentBrowsingContextMedia = 3719, + kOBSOLETE_GetCurrentBrowsingContextMedia = 3719, kMouseEventRelativePositionForInlineElement = 3720, kV8SharedArrayBufferConstructedWithoutIsolation = 3721, kV8HTMLVideoElement_GetVideoPlaybackQuality_Method = 3722,
diff --git a/third_party/blink/public/platform/input/input_handler_proxy.h b/third_party/blink/public/platform/input/input_handler_proxy.h index ec8d339..ab527bb 100644 --- a/third_party/blink/public/platform/input/input_handler_proxy.h +++ b/third_party/blink/public/platform/input/input_handler_proxy.h
@@ -172,6 +172,7 @@ void WillShutdown() override; void Animate(base::TimeTicks time) override; void ReconcileElasticOverscrollAndRootScroll() override; + void SetPrefersReducedMotion(bool prefers_reduced_motion) override; void UpdateRootLayerStateForSynchronousInputHandler( const gfx::ScrollOffset& total_scroll_offset, const gfx::ScrollOffset& max_scroll_offset, @@ -224,6 +225,7 @@ void DispatchSingleInputEvent(std::unique_ptr<EventWithCallback>, const base::TimeTicks); void DispatchQueuedInputEvents(); + void UpdateElasticOverscroll(); // Helper functions for handling more complicated input events. EventDisposition HandleMouseWheel(const blink::WebMouseWheelEvent& event); @@ -364,6 +366,9 @@ // hit test information is unnecessary (e.g. tests). bool event_attribution_enabled_ = true; + // This tracks whether the user has set prefers reduced motion. + bool prefers_reduced_motion_ = false; + // Helpers for the momentum scroll jank UMAs. std::unique_ptr<MomentumScrollJankTracker> momentum_scroll_jank_tracker_;
diff --git a/third_party/blink/public/platform/web_http_load_info.h b/third_party/blink/public/platform/web_http_load_info.h deleted file mode 100644 index ea1aef6..0000000 --- a/third_party/blink/public/platform/web_http_load_info.h +++ /dev/null
@@ -1,87 +0,0 @@ -/* - * Copyright (C) 2010 Google 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 THE COPYRIGHT - * OWNER 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. - */ - -#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_HTTP_LOAD_INFO_H_ -#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_HTTP_LOAD_INFO_H_ - -#include "third_party/blink/public/platform/web_common.h" -#include "third_party/blink/public/platform/web_private_ptr.h" - -namespace blink { - -class WebString; -struct ResourceLoadInfo; - -class WebHTTPLoadInfo { - public: - WebHTTPLoadInfo() { Initialize(); } - ~WebHTTPLoadInfo() { Reset(); } - WebHTTPLoadInfo(const WebHTTPLoadInfo& r) { Assign(r); } - WebHTTPLoadInfo& operator=(const WebHTTPLoadInfo& r) { - Assign(r); - return *this; - } - - BLINK_PLATFORM_EXPORT void Initialize(); - BLINK_PLATFORM_EXPORT void Reset(); - BLINK_PLATFORM_EXPORT void Assign(const WebHTTPLoadInfo& r); - - BLINK_PLATFORM_EXPORT int HttpStatusCode() const; - BLINK_PLATFORM_EXPORT void SetHTTPStatusCode(int); - - BLINK_PLATFORM_EXPORT WebString HttpStatusText() const; - BLINK_PLATFORM_EXPORT void SetHTTPStatusText(const WebString&); - - BLINK_PLATFORM_EXPORT void AddRequestHeader(const WebString& name, - const WebString& value); - BLINK_PLATFORM_EXPORT void AddResponseHeader(const WebString& name, - const WebString& value); - - BLINK_PLATFORM_EXPORT WebString RequestHeadersText() const; - BLINK_PLATFORM_EXPORT void SetRequestHeadersText(const WebString&); - - BLINK_PLATFORM_EXPORT WebString ResponseHeadersText() const; - BLINK_PLATFORM_EXPORT void SetResponseHeadersText(const WebString&); - - BLINK_PLATFORM_EXPORT WebString NpnNegotiatedProtocol() const; - BLINK_PLATFORM_EXPORT void SetNPNNegotiatedProtocol(const WebString&); - -#if INSIDE_BLINK - BLINK_PLATFORM_EXPORT WebHTTPLoadInfo(scoped_refptr<ResourceLoadInfo>); - BLINK_PLATFORM_EXPORT operator scoped_refptr<ResourceLoadInfo>() const; -#endif - - private: - WebPrivatePtr<ResourceLoadInfo> private_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_HTTP_LOAD_INFO_H_
diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h index f910957..b01e2b9 100644 --- a/third_party/blink/public/platform/web_runtime_features.h +++ b/third_party/blink/public/platform/web_runtime_features.h
@@ -218,7 +218,6 @@ BLINK_PLATFORM_EXPORT static void EnableAutoplayIgnoresWebAudio(bool); BLINK_PLATFORM_EXPORT static void EnableMediaControlsExpandGesture(bool); BLINK_PLATFORM_EXPORT static void EnableGetDisplayMedia(bool); - BLINK_PLATFORM_EXPORT static void EnableGetCurrentBrowsingContextMedia(bool); BLINK_PLATFORM_EXPORT static void EnableAllowSyncXHRInPageDismissal(bool); BLINK_PLATFORM_EXPORT static void EnableSignedExchangePrefetchCacheForNavigations(bool);
diff --git a/third_party/blink/public/platform/web_url_request.h b/third_party/blink/public/platform/web_url_request.h index 59ae894..bfba1a93 100644 --- a/third_party/blink/public/platform/web_url_request.h +++ b/third_party/blink/public/platform/web_url_request.h
@@ -153,11 +153,6 @@ BLINK_PLATFORM_EXPORT bool ReportUploadProgress() const; BLINK_PLATFORM_EXPORT void SetReportUploadProgress(bool); - // Controls whether actual headers sent and received for request are - // collected and reported. - BLINK_PLATFORM_EXPORT bool ReportRawHeaders() const; - BLINK_PLATFORM_EXPORT void SetReportRawHeaders(bool); - BLINK_PLATFORM_EXPORT mojom::RequestContextType GetRequestContext() const; BLINK_PLATFORM_EXPORT void SetRequestContext(mojom::RequestContextType);
diff --git a/third_party/blink/public/platform/web_url_response.h b/third_party/blink/public/platform/web_url_response.h index 9a65a93..70334f9b 100644 --- a/third_party/blink/public/platform/web_url_response.h +++ b/third_party/blink/public/platform/web_url_response.h
@@ -56,7 +56,6 @@ class ResourceResponse; class WebHTTPHeaderVisitor; -class WebHTTPLoadInfo; class WebURL; class WebURLResponse { @@ -179,8 +178,6 @@ BLINK_PLATFORM_EXPORT void SetLoadTiming( const network::mojom::LoadTimingInfo&); - BLINK_PLATFORM_EXPORT void SetHTTPLoadInfo(const WebHTTPLoadInfo&); - BLINK_PLATFORM_EXPORT base::Time ResponseTime() const; BLINK_PLATFORM_EXPORT void SetResponseTime(base::Time); @@ -357,6 +354,8 @@ BLINK_PLATFORM_EXPORT void SetRequestIncludeCredentials(bool); BLINK_PLATFORM_EXPORT bool RequestIncludeCredentials() const; + BLINK_PLATFORM_EXPORT void SetWasFetchedViaCache(bool); + #if INSIDE_BLINK protected: // Permit subclasses to set arbitrary ResourceResponse pointer as
diff --git a/third_party/blink/renderer/core/animation/keyframe_effect_model.cc b/third_party/blink/renderer/core/animation/keyframe_effect_model.cc index a4b6d0f..7f99c61 100644 --- a/third_party/blink/renderer/core/animation/keyframe_effect_model.cc +++ b/third_party/blink/renderer/core/animation/keyframe_effect_model.cc
@@ -211,7 +211,7 @@ return false; PropertySpecificKeyframeGroup* keyframe_group = - keyframe_groups_->at(property); + keyframe_groups_->DeprecatedAtOrEmptyValue(property); if (!keyframe_group) return false;
diff --git a/third_party/blink/renderer/core/css/counter_style_map.cc b/third_party/blink/renderer/core/css/counter_style_map.cc index fd5f5ec..31d7c9f9 100644 --- a/third_party/blink/renderer/core/css/counter_style_map.cc +++ b/third_party/blink/renderer/core/css/counter_style_map.cc
@@ -59,7 +59,7 @@ if (!counter_style) continue; AtomicString name = rule->GetName(); - if (CounterStyle* replaced = counter_styles_.at(name)) + if (CounterStyle* replaced = counter_styles_.DeprecatedAtOrEmptyValue(name)) replaced->SetIsDirty(); counter_styles_.Set(rule->GetName(), counter_style); } @@ -100,7 +100,7 @@ return &const_cast<CounterStyleMap*>(this)->CreateUACounterStyle(name); } - if (CounterStyle* style = counter_styles_.at(name)) + if (CounterStyle* style = counter_styles_.DeprecatedAtOrEmptyValue(name)) return style; return GetAncestorMap()->FindCounterStyleAcrossScopes(name); }
diff --git a/third_party/blink/renderer/core/css/css_paint_value.cc b/third_party/blink/renderer/core/css/css_paint_value.cc index 4619b7d2..20d6997 100644 --- a/third_party/blink/renderer/core/css/css_paint_value.cc +++ b/third_party/blink/renderer/core/css/css_paint_value.cc
@@ -63,7 +63,8 @@ const Vector<CSSPropertyID>* CSSPaintValue::NativeInvalidationProperties( const Document& document) const { - const CSSPaintImageGenerator* generator = generators_.at(&document); + const CSSPaintImageGenerator* generator = + generators_.DeprecatedAtOrEmptyValue(&document); if (!generator) return nullptr; return &generator->NativeInvalidationProperties(); @@ -71,7 +72,8 @@ const Vector<AtomicString>* CSSPaintValue::CustomInvalidationProperties( const Document& document) const { - const CSSPaintImageGenerator* generator = generators_.at(&document); + const CSSPaintImageGenerator* generator = + generators_.DeprecatedAtOrEmptyValue(&document); if (!generator) return nullptr; return &generator->CustomInvalidationProperties(); @@ -80,7 +82,8 @@ bool CSSPaintValue::IsUsingCustomProperty( const AtomicString& custom_property_name, const Document& document) const { - const CSSPaintImageGenerator* generator = generators_.at(&document); + const CSSPaintImageGenerator* generator = + generators_.DeprecatedAtOrEmptyValue(&document); if (!generator || !generator->IsImageGeneratorReady()) return false; return generator->CustomInvalidationProperties().Contains( @@ -198,9 +201,10 @@ !RuntimeEnabledFeatures::CSSPaintAPIArgumentsEnabled()) return true; - DCHECK(generators_.at(&document)->IsImageGeneratorReady()); + DCHECK( + generators_.DeprecatedAtOrEmptyValue(&document)->IsImageGeneratorReady()); const Vector<CSSSyntaxDefinition>& input_argument_types = - generators_.at(&document)->InputArgumentTypes(); + generators_.DeprecatedAtOrEmptyValue(&document)->InputArgumentTypes(); if (argument_variable_data_.size() != input_argument_types.size()) { input_arguments_invalid_ = true; return false;
diff --git a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc index 4be98c2..6dff022d 100644 --- a/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc +++ b/third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.cc
@@ -87,7 +87,7 @@ const CSSValue* PrepopulatedComputedStylePropertyMap::GetCustomProperty( AtomicString property_name) const { - return custom_values_.at(property_name); + return custom_values_.DeprecatedAtOrEmptyValue(property_name); } void PrepopulatedComputedStylePropertyMap::ForEachProperty(
diff --git a/third_party/blink/renderer/core/css/media_feature_overrides.h b/third_party/blink/renderer/core/css/media_feature_overrides.h index 96e2e1d..5ad58a1 100644 --- a/third_party/blink/renderer/core/css/media_feature_overrides.h +++ b/third_party/blink/renderer/core/css/media_feature_overrides.h
@@ -15,7 +15,7 @@ public: void SetOverride(const AtomicString& feature, const String& value_string); MediaQueryExpValue GetOverride(const AtomicString& feature) const { - return overrides_.at(feature); + return overrides_.DeprecatedAtOrEmptyValue(feature); } private:
diff --git a/third_party/blink/renderer/core/css/property_registry.cc b/third_party/blink/renderer/core/css/property_registry.cc index 226faaf..6150a83 100644 --- a/third_party/blink/renderer/core/css/property_registry.cc +++ b/third_party/blink/renderer/core/css/property_registry.cc
@@ -32,9 +32,10 @@ // the registration from CSS.registerProperty must win. // // https://drafts.css-houdini.org/css-properties-values-api-1/#determining-registration - if (const auto* registration = registered_properties_.at(name)) + if (const auto* registration = + registered_properties_.DeprecatedAtOrEmptyValue(name)) return registration; - return declared_properties_.at(name); + return declared_properties_.DeprecatedAtOrEmptyValue(name); } bool PropertyRegistry::IsEmpty() const {
diff --git a/third_party/blink/renderer/core/css/resolver/cascade_map.cc b/third_party/blink/renderer/core/css/resolver/cascade_map.cc index 10c56197..91ac523 100644 --- a/third_party/blink/renderer/core/css/resolver/cascade_map.cc +++ b/third_party/blink/renderer/core/css/resolver/cascade_map.cc
@@ -48,7 +48,7 @@ inline CascadePriority AtCustom(const CSSPropertyName& name, const CascadeMap::CustomMap& map) { - return map.at(name); + return map.DeprecatedAtOrEmptyValue(name); } inline CascadePriority AtNative(const CSSPropertyName& name,
diff --git a/third_party/blink/renderer/core/css/rule_set.h b/third_party/blink/renderer/core/css/rule_set.h index 09afd61..9ee704a2 100644 --- a/third_party/blink/renderer/core/css/rule_set.h +++ b/third_party/blink/renderer/core/css/rule_set.h
@@ -256,22 +256,22 @@ const HeapVector<Member<const RuleData>>* IdRules( const AtomicString& key) const { DCHECK(!pending_rules_); - return id_rules_.at(key); + return id_rules_.DeprecatedAtOrEmptyValue(key); } const HeapVector<Member<const RuleData>>* ClassRules( const AtomicString& key) const { DCHECK(!pending_rules_); - return class_rules_.at(key); + return class_rules_.DeprecatedAtOrEmptyValue(key); } const HeapVector<Member<const RuleData>>* TagRules( const AtomicString& key) const { DCHECK(!pending_rules_); - return tag_rules_.at(key); + return tag_rules_.DeprecatedAtOrEmptyValue(key); } const HeapVector<Member<const RuleData>>* UAShadowPseudoElementRules( const AtomicString& key) const { DCHECK(!pending_rules_); - return ua_shadow_pseudo_element_rules_.at(key); + return ua_shadow_pseudo_element_rules_.DeprecatedAtOrEmptyValue(key); } const HeapVector<Member<const RuleData>>* LinkPseudoClassRules() const { DCHECK(!pending_rules_);
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index d7c9bb4..fcd7c3a22 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -1980,7 +1980,7 @@ CSSScrollTimeline* StyleEngine::FindScrollTimeline(const AtomicString& name) { DCHECK(!timelines_need_update_); - return scroll_timeline_map_.at(name); + return scroll_timeline_map_.DeprecatedAtOrEmptyValue(name); } void StyleEngine::ScrollTimelineInvalidated(CSSScrollTimeline& timeline) {
diff --git a/third_party/blink/renderer/core/css/style_sheet_contents.cc b/third_party/blink/renderer/core/css/style_sheet_contents.cc index 120dd10c..e7d5116b 100644 --- a/third_party/blink/renderer/core/css/style_sheet_contents.cc +++ b/third_party/blink/renderer/core/css/style_sheet_contents.cc
@@ -316,7 +316,7 @@ const AtomicString& StyleSheetContents::NamespaceURIFromPrefix( const AtomicString& prefix) const { - return namespaces_.at(prefix); + return namespaces_.DeprecatedAtOrEmptyValue(prefix); } void StyleSheetContents::ParseAuthorStyleSheet(
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index b24ee228..20c2fda 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -484,7 +484,7 @@ const QualifiedName& name) { ExplicitlySetAttrElementsMap* element_attribute_map = element->GetDocument().GetExplicitlySetAttrElementsMap(element); - return element_attribute_map->at(name); + return element_attribute_map->DeprecatedAtOrEmptyValue(name); } // Checks that the given element |candidate| is a descendant of
diff --git a/third_party/blink/renderer/core/dom/id_target_observer_registry.cc b/third_party/blink/renderer/core/dom/id_target_observer_registry.cc index c5d8545..c15940a9 100644 --- a/third_party/blink/renderer/core/dom/id_target_observer_registry.cc +++ b/third_party/blink/renderer/core/dom/id_target_observer_registry.cc
@@ -63,7 +63,7 @@ DCHECK(!id.IsEmpty()); DCHECK(!registry_.IsEmpty()); - notifying_observers_in_set_ = registry_.at(id.Impl()); + notifying_observers_in_set_ = registry_.DeprecatedAtOrEmptyValue(id.Impl()); if (!notifying_observers_in_set_) return; @@ -83,7 +83,7 @@ bool IdTargetObserverRegistry::HasObservers(const AtomicString& id) const { if (id.IsEmpty() || registry_.IsEmpty()) return false; - ObserverSet* set = registry_.at(id.Impl()); + ObserverSet* set = registry_.DeprecatedAtOrEmptyValue(id.Impl()); return set && !set->IsEmpty(); }
diff --git a/third_party/blink/renderer/core/dom/node_lists_node_data.h b/third_party/blink/renderer/core/dom/node_lists_node_data.h index f2457b5..3478fff9 100644 --- a/third_party/blink/renderer/core/dom/node_lists_node_data.h +++ b/third_party/blink/renderer/core/dom/node_lists_node_data.h
@@ -112,8 +112,9 @@ template <typename T> T* Cached(CollectionType collection_type) { - return static_cast<T*>(atomic_name_caches_.at(NamedNodeListKey( - collection_type, CSSSelector::UniversalSelectorAtom()))); + return static_cast<T*>( + atomic_name_caches_.DeprecatedAtOrEmptyValue(NamedNodeListKey( + collection_type, CSSSelector::UniversalSelectorAtom()))); } TagCollectionNS* AddCache(ContainerNode& node,
diff --git a/third_party/blink/renderer/core/dom/processing_instruction.cc b/third_party/blink/renderer/core/dom/processing_instruction.cc index 63f6777b..cc51fe2 100644 --- a/third_party/blink/renderer/core/dom/processing_instruction.cc +++ b/third_party/blink/renderer/core/dom/processing_instruction.cc
@@ -120,12 +120,12 @@ if (!is_css_ && !is_xsl_) return false; - href = attrs.at("href"); - charset = attrs.at("charset"); - String alternate = attrs.at("alternate"); + href = attrs.DeprecatedAtOrEmptyValue("href"); + charset = attrs.DeprecatedAtOrEmptyValue("charset"); + String alternate = attrs.DeprecatedAtOrEmptyValue("alternate"); alternate_ = alternate == "yes"; - title_ = attrs.at("title"); - media_ = attrs.at("media"); + title_ = attrs.DeprecatedAtOrEmptyValue("title"); + media_ = attrs.DeprecatedAtOrEmptyValue("media"); return !alternate_ || !title_.IsEmpty(); }
diff --git a/third_party/blink/renderer/core/dom/tree_ordered_map.cc b/third_party/blink/renderer/core/dom/tree_ordered_map.cc index f44ab4a..2c03a1ec 100644 --- a/third_party/blink/renderer/core/dom/tree_ordered_map.cc +++ b/third_party/blink/renderer/core/dom/tree_ordered_map.cc
@@ -115,7 +115,7 @@ const TreeScope& scope) const { DCHECK(key); - MapEntry* entry = map_.at(key); + MapEntry* entry = map_.DeprecatedAtOrEmptyValue(key); if (!entry) return nullptr; @@ -197,7 +197,7 @@ Element* TreeOrderedMap::GetCachedFirstElementWithoutAccessingNodeTree( const AtomicString& key) { - MapEntry* entry = map_.at(key); + MapEntry* entry = map_.DeprecatedAtOrEmptyValue(key); if (!entry) return nullptr; DCHECK(entry->count);
diff --git a/third_party/blink/renderer/core/dom/weak_identifier_map.h b/third_party/blink/renderer/core/dom/weak_identifier_map.h index a78305b0..8ff0cb2 100644 --- a/third_party/blink/renderer/core/dom/weak_identifier_map.h +++ b/third_party/blink/renderer/core/dom/weak_identifier_map.h
@@ -28,7 +28,8 @@ } static IdentifierType Identifier(T* object) { - IdentifierType result = Instance().object_to_identifier_.at(object); + IdentifierType result = + Instance().object_to_identifier_.DeprecatedAtOrEmptyValue(object); if (WTF::IsHashTraitsEmptyValue<HashTraits<IdentifierType>>(result)) { do { @@ -43,7 +44,8 @@ } static T* Lookup(IdentifierType identifier) { - return Instance().identifier_to_object_.at(identifier); + return Instance().identifier_to_object_.DeprecatedAtOrEmptyValue( + identifier); } static void NotifyObjectDestroyed(T* object) {
diff --git a/third_party/blink/renderer/core/editing/editing_behavior.cc b/third_party/blink/renderer/core/editing/editing_behavior.cc index 38bb91f..c3a7ecb2 100644 --- a/third_party/blink/renderer/core/editing/editing_behavior.cc +++ b/third_party/blink/renderer/core/editing/editing_behavior.cc
@@ -237,14 +237,17 @@ if (key_event->GetType() == WebInputEvent::Type::kRawKeyDown) { int map_key = modifiers << 16 | event.keyCode(); - const char* name = map_key ? key_down_commands_map->at(map_key) : nullptr; + const char* name = + map_key ? key_down_commands_map->DeprecatedAtOrEmptyValue(map_key) + : nullptr; if (!name) name = LookupCommandNameFromDomKeyKeyDown(event.key(), modifiers); return name; } int map_key = modifiers << 16 | event.charCode(); - return map_key ? key_press_commands_map->at(map_key) : nullptr; + return map_key ? key_press_commands_map->DeprecatedAtOrEmptyValue(map_key) + : nullptr; } bool EditingBehavior::ShouldInsertCharacter(const KeyboardEvent& event) const {
diff --git a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc index bd47e275..5b7a3c1 100644 --- a/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc +++ b/third_party/blink/renderer/core/editing/markers/document_marker_controller.cc
@@ -542,7 +542,7 @@ if (start_offset == node_length && end_offset == node_length) return nullptr; - MarkerLists* const markers = markers_.at(&node); + MarkerLists* const markers = markers_.DeprecatedAtOrEmptyValue(&node); if (!markers) return nullptr; @@ -592,7 +592,8 @@ if (!text_node) continue; - MarkerLists* const marker_lists = markers_.at(text_node); + MarkerLists* const marker_lists = + markers_.DeprecatedAtOrEmptyValue(text_node); if (!marker_lists) continue; @@ -645,7 +646,7 @@ auto* text_node = DynamicTo<Text>(node); if (!text_node) continue; - MarkerLists* const markers = markers_.at(text_node); + MarkerLists* const markers = markers_.DeprecatedAtOrEmptyValue(text_node); if (!markers) continue; @@ -684,7 +685,7 @@ if (!PossiblyHasMarkers(marker_types)) return result; - MarkerLists* markers = markers_.at(&text); + MarkerLists* markers = markers_.DeprecatedAtOrEmptyValue(&text); if (!markers) return result; @@ -1164,7 +1165,7 @@ unsigned start_offset, unsigned end_offset, bool active) { - MarkerLists* markers = markers_.at(&text); + MarkerLists* markers = markers_.DeprecatedAtOrEmptyValue(&text); if (!markers) return false; @@ -1224,7 +1225,7 @@ auto* text_node = DynamicTo<Text>(node); if (!text_node) return; - MarkerLists* markers = markers_.at(text_node); + MarkerLists* markers = markers_.DeprecatedAtOrEmptyValue(text_node); if (!markers) return;
diff --git a/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc b/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc index 6d44ced8..45061ea 100644 --- a/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc +++ b/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc
@@ -90,7 +90,8 @@ } AtomicString LookupNamespaceURI(const AtomicString& prefix) const { - return prefix_ns_map_.at(prefix ? prefix : g_empty_atom); + return prefix_ns_map_.DeprecatedAtOrEmptyValue(prefix ? prefix + : g_empty_atom); } const AtomicString& ContextNamespace() const { return context_namespace_; } @@ -108,7 +109,7 @@ } const Vector<AtomicString> PrefixList(const AtomicString& ns) const { - return ns_prefixes_map_.at(ns ? ns : g_empty_atom); + return ns_prefixes_map_.DeprecatedAtOrEmptyValue(ns ? ns : g_empty_atom); } private:
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 920ccfd..7df8643 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -1961,6 +1961,8 @@ if (does_composite_) { // When attaching a local main frame, set up any state on the compositor. MainFrameImpl()->FrameWidgetImpl()->SetBackgroundColor(BackgroundColor()); + MainFrameImpl()->FrameWidgetImpl()->SetPrefersReducedMotion( + web_preferences_.prefers_reduced_motion); auto& viewport = GetPage()->GetVisualViewport(); MainFrameImpl()->FrameWidgetImpl()->SetPageScaleStateAndLimits( viewport.Scale(), viewport.IsPinchGestureActive(), @@ -3301,6 +3303,12 @@ void WebViewImpl::UpdateWebPreferences( const blink::web_pref::WebPreferences& preferences) { web_preferences_ = preferences; + + if (MainFrameImpl()) { + MainFrameImpl()->FrameWidgetImpl()->SetPrefersReducedMotion( + web_preferences_.prefers_reduced_motion); + } + ApplyWebPreferences(preferences, this); ApplyCommandLineToSettings(SettingsImpl()); }
diff --git a/third_party/blink/renderer/core/frame/performance_monitor.cc b/third_party/blink/renderer/core/frame/performance_monitor.cc index bd0b12f..2e489a9 100644 --- a/third_party/blink/renderer/core/frame/performance_monitor.cc +++ b/third_party/blink/renderer/core/frame/performance_monitor.cc
@@ -85,7 +85,8 @@ base::TimeDelta threshold, Client* client) { DCHECK(violation < kAfterLast); - ClientThresholds* client_thresholds = subscriptions_.at(violation); + ClientThresholds* client_thresholds = + subscriptions_.DeprecatedAtOrEmptyValue(violation); if (!client_thresholds) { client_thresholds = MakeGarbageCollected<ClientThresholds>(); subscriptions_.Set(violation, client_thresholds);
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 1ac0bd8..eeec156 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc
@@ -1219,6 +1219,13 @@ widget_base_->LayerTreeHost()->SetOverscrollBehavior(overscroll_behavior); } +void WebFrameWidgetImpl::SetPrefersReducedMotion(bool prefers_reduced_motion) { + if (!View()->does_composite()) + return; + widget_base_->LayerTreeHost()->SetPrefersReducedMotion( + prefers_reduced_motion); +} + void WebFrameWidgetImpl::RegisterSelection(cc::LayerSelection selection) { if (!View()->does_composite()) return;
diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h index f318f6e..7ccca2f 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h
@@ -430,6 +430,9 @@ // paint into another widget which has a background color of its own. void SetBackgroundColor(SkColor color); + // Sets whether the prefers-reduced-motion hint has been enabled. + void SetPrefersReducedMotion(bool prefers_reduced_motion); + // Starts an animation of the page scale to a target scale factor and scroll // offset. // If use_anchor is true, destination is a point on the screen that will
diff --git a/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc b/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc index 8099e07..0a2b9dc5 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc
@@ -22,6 +22,100 @@ namespace blink { +// Used by <selectmenu> to find child parts. The <selectmenu> parts search +// pierces into shadow roots, but ignores all children of nested <selectmenu> +// and <select> elements. So this traversal is similar to a FlatTreeTraversal, +// except that when a <selectmenu> or <select> element is encountered, that +// element and its children are skipped over. +class CORE_EXPORT SelectMenuPartTraversal { + STATIC_ONLY(SelectMenuPartTraversal); + + public: + // Returns the first non-<select> or <selectmenu> child of node in a flat tree + // traversal. + static Node* FirstChild(const Node& node); + // Returns the next non-<select> or <selectmenu> sibling of node in a flat + // tree traversal. + static Node* NextSibling(const Node& node); + // Returns the next Node in a flat tree pre-order traversal that skips + // <select> and <selectemenu> elements and their children. + static Node* Next(const Node& node, const Node* stay_within); + + // Returns true if other is an ancestor of node, and there are no <select> or + // <selectmenu> ancestors in the parent chain between node and other. + static bool IsDescendantOf(const Node& node, const Node& other); + + private: + static Node* NextSkippingChildren(const Node&, const Node* stay_within); + static bool IsNestedSelectMenu(const Node& node); +}; + +Node* SelectMenuPartTraversal::NextSibling(const Node& node) { + Node* next = FlatTreeTraversal::NextSibling(node); + while (next && SelectMenuPartTraversal::IsNestedSelectMenu(*next)) { + next = FlatTreeTraversal::NextSibling(*next); + } + return next; +} + +Node* SelectMenuPartTraversal::FirstChild(const Node& node) { + Node* first = FlatTreeTraversal::FirstChild(node); + while (first && SelectMenuPartTraversal::IsNestedSelectMenu(*first)) { + first = SelectMenuPartTraversal::NextSibling(*first); + } + return first; +} + +namespace { + +static Node* NextAncestorSibling(const Node& node, const Node* stay_within) { + DCHECK(!SelectMenuPartTraversal::NextSibling(node)); + DCHECK_NE(node, stay_within); + for (Node* parent_node = FlatTreeTraversal::Parent(node); parent_node; + parent_node = FlatTreeTraversal::Parent(*parent_node)) { + if (parent_node == stay_within) + return nullptr; + if (Node* next_node = SelectMenuPartTraversal::NextSibling(*parent_node)) + return next_node; + } + return nullptr; +} + +} // namespace + +Node* SelectMenuPartTraversal::NextSkippingChildren(const Node& node, + const Node* stay_within) { + if (node == stay_within) + return nullptr; + if (Node* next_node = NextSibling(node)) + return next_node; + return NextAncestorSibling(node, stay_within); +} + +Node* SelectMenuPartTraversal::Next(const Node& node, const Node* stay_within) { + if (Node* child = FirstChild(node)) + return child; + return NextSkippingChildren(node, stay_within); +} + +bool SelectMenuPartTraversal::IsDescendantOf(const Node& node, + const Node& other) { + for (const Node* ancestor = FlatTreeTraversal::Parent(node); ancestor; + ancestor = FlatTreeTraversal::Parent(*ancestor)) { + if (ancestor == other) + return true; + if (IsNestedSelectMenu(*ancestor)) + return false; + } + return false; +} + +bool SelectMenuPartTraversal::IsNestedSelectMenu(const Node& node) { + // When searching for parts of a given <selectmenu>, don't look + // inside nested <selectmenu> or <select> elements. + return IsA<HTMLSelectMenuElement>(node) || IsA<HTMLSelectElement>(node); +} + class HTMLSelectMenuElement::SelectMutationCallback : public MutationObserver::Delegate { public: @@ -272,16 +366,19 @@ } } -void HTMLSelectMenuElement::SetListboxPart(HTMLPopupElement* listbox_part) { - if (listbox_part_ == listbox_part) +void HTMLSelectMenuElement::SetListboxPart(HTMLPopupElement* new_listbox_part) { + if (listbox_part_ == new_listbox_part) return; if (listbox_part_) { listbox_part_->SetOwnerSelectMenuElement(nullptr); listbox_part_->SetNeedsRepositioningForSelectMenu(false); } - listbox_part_ = listbox_part; - listbox_part_->SetOwnerSelectMenuElement(this); + // TODO(crbug.com/1234899) Emit console warning if new_listbox_part is null + if (new_listbox_part) { + new_listbox_part->SetOwnerSelectMenuElement(this); + } + listbox_part_ = new_listbox_part; } bool HTMLSelectMenuElement::IsValidButtonPart(const Element* part, @@ -330,7 +427,8 @@ bool HTMLSelectMenuElement::IsValidOptionPart(const Element* part, bool show_warning) const { - bool is_valid = FlatTreeTraversal::IsDescendantOf(*part, *listbox_part_); + bool is_valid = + SelectMenuPartTraversal::IsDescendantOf(*part, *listbox_part_); if (!is_valid && show_warning) { GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( mojom::blink::ConsoleMessageSource::kRendering, @@ -342,39 +440,9 @@ return is_valid; } -void HTMLSelectMenuElement::ButtonPartInserted(Element* new_button_part) { - if (!IsValidButtonPart(new_button_part, /*show_warning=*/true)) { - return; - } - - // TODO(crbug.com/1191121) Decide which part gets controller code when there - // are multiple parts available. - if (button_part_ != new_button_part) { - if (button_part_) { - button_part_->removeEventListener(event_type_names::kClick, - button_part_listener_, false); - } - if (new_button_part) { - new_button_part->addEventListener(event_type_names::kClick, - button_part_listener_, false); - } - button_part_ = new_button_part; - } -} - -void HTMLSelectMenuElement::ButtonPartRemoved(Element* button_part) { - if (button_part != button_part_) { - return; - } - - button_part_->removeEventListener(event_type_names::kClick, - button_part_listener_, false); - - // Try to find a new button part by choosing the one that comes first in the - // flat tree traversal. - Element* new_button_part = nullptr; - for (Node* node = FlatTreeTraversal::FirstChild(*this); node != nullptr; - node = FlatTreeTraversal::Next(*node, this)) { +Element* HTMLSelectMenuElement::FirstValidButtonPart() const { + for (Node* node = SelectMenuPartTraversal::FirstChild(*this); node; + node = SelectMenuPartTraversal::Next(*node, this)) { auto* element = DynamicTo<Element>(node); if (!element) { continue; @@ -382,11 +450,22 @@ if (element->getAttribute(html_names::kPartAttr) == kButtonPartName && IsValidButtonPart(element, /*show_warning=*/false)) { - new_button_part = element; - break; + return element; } } + return nullptr; +} + +void HTMLSelectMenuElement::SetButtonPart(Element* new_button_part) { + if (button_part_ == new_button_part) + return; + + if (button_part_) { + button_part_->removeEventListener(event_type_names::kClick, + button_part_listener_, false); + } + // TODO(crbug.com/1234899) Emit console warning if new_button_part is null if (new_button_part) { new_button_part->addEventListener(event_type_names::kClick, button_part_listener_, false); @@ -394,24 +473,25 @@ button_part_ = new_button_part; } -void HTMLSelectMenuElement::SelectedValuePartInserted( - Element* new_selected_value_part) { - // TODO(crbug.com/1191121) Decide which part gets controller code when there - // are multiple parts available. - selected_value_part_ = new_selected_value_part; -} - -void HTMLSelectMenuElement::SelectedValuePartRemoved( - Element* selected_value_part) { - if (selected_value_part_ != selected_value_part) { +void HTMLSelectMenuElement::ButtonPartInserted(Element* new_button_part) { + if (!IsValidButtonPart(new_button_part, /*show_warning=*/true)) { return; } - // Try to find a new selected value part by choosing the one that comes first - // in the flat tree traversal. - Element* new_selected_value_part = nullptr; - for (Node* node = FlatTreeTraversal::FirstChild(*this); node != nullptr; - node = FlatTreeTraversal::Next(*node, this)) { + SetButtonPart(FirstValidButtonPart()); +} + +void HTMLSelectMenuElement::ButtonPartRemoved(Element* button_part) { + if (button_part != button_part_) { + return; + } + + SetButtonPart(FirstValidButtonPart()); +} + +Element* HTMLSelectMenuElement::FirstValidSelectedValuePart() const { + for (Node* node = SelectMenuPartTraversal::FirstChild(*this); node; + node = SelectMenuPartTraversal::Next(*node, this)) { auto* element = DynamicTo<Element>(node); if (!element) { continue; @@ -419,12 +499,36 @@ if (element->getAttribute(html_names::kPartAttr) == kSelectedValuePartName) { - new_selected_value_part = element; - break; + return element; } } + return nullptr; +} - selected_value_part_ = new_selected_value_part; +void HTMLSelectMenuElement::SelectedValuePartInserted( + Element* new_selected_value_part) { + selected_value_part_ = FirstValidSelectedValuePart(); +} + +void HTMLSelectMenuElement::SelectedValuePartRemoved( + Element* selected_value_part) { + selected_value_part_ = FirstValidSelectedValuePart(); +} + +Element* HTMLSelectMenuElement::FirstValidListboxPart() const { + for (Node* node = SelectMenuPartTraversal::FirstChild(*this); node; + node = SelectMenuPartTraversal::Next(*node, this)) { + auto* element = DynamicTo<Element>(node); + if (!element) { + continue; + } + + if (element->getAttribute(html_names::kPartAttr) == kListboxPartName && + IsValidListboxPart(element, /*show_warning=*/false)) { + return element; + } + } + return nullptr; } void HTMLSelectMenuElement::ListboxPartInserted(Element* new_listbox_part) { @@ -432,9 +536,7 @@ return; } - // TODO(crbug.com/1191121) Decide which part gets controller code when there - // are multiple parts available. - SetListboxPart(DynamicTo<HTMLPopupElement>(new_listbox_part)); + SetListboxPart(DynamicTo<HTMLPopupElement>(FirstValidListboxPart())); // TODO(crbug.com/1121840) Should the current option parts be revalidated? } @@ -443,24 +545,7 @@ return; } - // Try to find a new listbox part by choosing the one that comes first in the - // flat tree traversal. - Element* new_listbox_part = nullptr; - for (Node* node = FlatTreeTraversal::FirstChild(*this); node != nullptr; - node = FlatTreeTraversal::Next(*node, this)) { - auto* element = DynamicTo<Element>(node); - if (!element) { - continue; - } - - if (element->getAttribute(html_names::kPartAttr) == kListboxPartName && - IsValidListboxPart(element, /*show_warning=*/false)) { - new_listbox_part = element; - break; - } - } - - SetListboxPart(DynamicTo<HTMLPopupElement>(new_listbox_part)); + SetListboxPart(DynamicTo<HTMLPopupElement>(FirstValidListboxPart())); // TODO(crbug.com/1121840) Should the current option parts be revalidated? } @@ -526,8 +611,8 @@ // TODO(crbug.com/1121840) This is going to be replaced by an option part // list iterator, or we could reuse OptionListIterator if we decide that just // <option>s are supported as option parts. - for (Node* node = FlatTreeTraversal::FirstChild(*this); node != nullptr; - node = FlatTreeTraversal::Next(*node, this)) { + for (Node* node = SelectMenuPartTraversal::FirstChild(*this); node; + node = SelectMenuPartTraversal::Next(*node, this)) { auto* element = DynamicTo<Element>(node); if (!element) { continue;
diff --git a/third_party/blink/renderer/core/html/forms/html_select_menu_element.h b/third_party/blink/renderer/core/html/forms/html_select_menu_element.h index 7a43aaa..c6ecb932 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_menu_element.h +++ b/third_party/blink/renderer/core/html/forms/html_select_menu_element.h
@@ -41,6 +41,9 @@ void UpdatePartElements(); Element* FirstOptionPart() const; + Element* FirstValidButtonPart() const; + Element* FirstValidListboxPart() const; + Element* FirstValidSelectedValuePart() const; void EnsureSelectedOptionIsValid(); Element* SelectedOption(); void SetSelectedOption(Element* selected_option); @@ -59,7 +62,8 @@ bool IsValidListboxPart(const Element* part, bool show_warning) const; bool IsValidOptionPart(const Element* part, bool show_warning) const; - void SetListboxPart(HTMLPopupElement* listbox_part); + void SetButtonPart(Element* new_button_part); + void SetListboxPart(HTMLPopupElement* new_listbox_part); class ButtonPartEventListener : public NativeEventListener { public:
diff --git a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc index 2b3d550..ba9356da 100644 --- a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc +++ b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
@@ -485,7 +485,8 @@ MapLoweredLocalNameToName(case_map, svg_tags.get(), svg_names::kTagsCount); } - const QualifiedName& cased_name = case_map->at(token->GetName()); + const QualifiedName& cased_name = + case_map->DeprecatedAtOrEmptyValue(token->GetName()); if (cased_name.LocalName().IsNull()) return; token->SetName(cased_name.LocalName()); @@ -501,7 +502,8 @@ } for (auto& token_attribute : token->Attributes()) { - const QualifiedName& cased_name = case_map->at(token_attribute.LocalName()); + const QualifiedName& cased_name = + case_map->DeprecatedAtOrEmptyValue(token_attribute.LocalName()); if (!cased_name.LocalName().IsNull()) token_attribute.ParserSetName(cased_name); } @@ -550,7 +552,8 @@ for (unsigned i = 0; i < token->Attributes().size(); ++i) { Attribute& token_attribute = token->Attributes().at(i); - const QualifiedName& name = map->at(token_attribute.LocalName()); + const QualifiedName& name = + map->DeprecatedAtOrEmptyValue(token_attribute.LocalName()); if (!name.LocalName().IsNull()) token_attribute.ParserSetName(name); }
diff --git a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc index ebae59a7..d62b005 100644 --- a/third_party/blink/renderer/core/inspector/inspector_network_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_network_agent.cc
@@ -81,7 +81,6 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_error.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_load_info.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h" @@ -804,22 +803,9 @@ if (response.IsNull()) return nullptr; - int status; - String status_text; - if (response.GetResourceLoadInfo() && - response.GetResourceLoadInfo()->http_status_code) { - status = response.GetResourceLoadInfo()->http_status_code; - status_text = response.GetResourceLoadInfo()->http_status_text; - } else { - status = response.HttpStatusCode(); - status_text = response.HttpStatusText(); - } - HTTPHeaderMap headers_map; - if (response.GetResourceLoadInfo() && - response.GetResourceLoadInfo()->response_headers.size()) - headers_map = response.GetResourceLoadInfo()->response_headers; - else - headers_map = response.HttpHeaderFields(); + int status = response.HttpStatusCode(); + String status_text = response.HttpStatusText(); + HTTPHeaderMap headers_map = response.HttpHeaderFields(); int64_t encoded_data_length = response.EncodedDataLength(); @@ -884,21 +870,6 @@ response_object->setTiming( BuildObjectForTiming(*response.GetResourceLoadTiming())); - if (response.GetResourceLoadInfo()) { - if (!response.GetResourceLoadInfo()->response_headers_text.IsEmpty()) { - response_object->setHeadersText( - response.GetResourceLoadInfo()->response_headers_text); - } - if (response.GetResourceLoadInfo()->request_headers.size()) { - response_object->setRequestHeaders(BuildObjectForHeaders( - response.GetResourceLoadInfo()->request_headers)); - } - if (!response.GetResourceLoadInfo()->request_headers_text.IsEmpty()) { - response_object->setRequestHeadersText( - response.GetResourceLoadInfo()->request_headers_text); - } - } - const net::IPEndPoint& remote_ip_endpoint = response.RemoteIPEndpoint(); if (remote_ip_endpoint.address().IsValid()) { response_object->setRemoteIPAddress( @@ -1221,8 +1192,6 @@ } } - request.SetReportRawHeaders(true); - if (cache_disabled_.Get()) { if (LoadsFromCacheOnly(request) && request.GetRequestContext() !=
diff --git a/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h b/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h index 1305d54..d3d45cef 100644 --- a/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h +++ b/third_party/blink/renderer/core/layout/multi_column_fragmentainer_group.h
@@ -87,6 +87,9 @@ void SetLogicalBottomInFlowThread(LayoutUnit logical_bottom_in_flow_thread) { logical_bottom_in_flow_thread_ = logical_bottom_in_flow_thread; } + void ExtendLogicalBottomInFlowThread(LayoutUnit block_size) { + logical_bottom_in_flow_thread_ += block_size; + } // The height of the flow thread portion for the entire fragmentainer group. LayoutUnit LogicalHeightInFlowThread() const {
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 6c7a445..ac8b6f3 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
@@ -1379,9 +1379,7 @@ builder.SetPercentageResolutionBlockSize(child_percentage_size_.block_size); builder.SetReplacedPercentageResolutionBlockSize( child_percentage_size_.block_size); - if (is_column_) - builder.SetIsInitialBlockSizeIndefinite(true); - else if (WillChildCrossSizeBeContainerCrossSize(child)) + if (!is_column_ && WillChildCrossSizeBeContainerCrossSize(child)) builder.SetBlockAutoBehavior(NGAutoBehavior::kStretchExplicit); const auto space = builder.ToConstraintSpace();
diff --git a/third_party/blink/renderer/core/layout/ng/geometry/ng_bfc_offset.h b/third_party/blink/renderer/core/layout/ng/geometry/ng_bfc_offset.h index 91471c9..def3985 100644 --- a/third_party/blink/renderer/core/layout/ng/geometry/ng_bfc_offset.h +++ b/third_party/blink/renderer/core/layout/ng/geometry/ng_bfc_offset.h
@@ -5,6 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GEOMETRY_NG_BFC_OFFSET_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_GEOMETRY_NG_BFC_OFFSET_H_ +#include <tuple> + #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h"
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc index 3c0b900..084412b2 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_offset_mapping.cc
@@ -286,7 +286,7 @@ const unsigned offset = node_and_offset.second; unsigned range_start; unsigned range_end; - std::tie(range_start, range_end) = ranges_.at(&node); + std::tie(range_start, range_end) = ranges_.DeprecatedAtOrEmptyValue(&node); if (range_start == range_end || units_[range_start].DOMStart() > offset) return nullptr; // Find the last unit where unit.dom_start <= offset
diff --git a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc index f0278bb..a2905a5e 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_absolute_utils.cc
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h" +#include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/geometry/length_functions.h" @@ -489,6 +490,14 @@ {dimensions->size.inline_size, space.AvailableSize().block_size}); builder.SetIsFixedInlineSize(true); builder.SetPercentageResolutionSize(space.PercentageResolutionSize()); + + if (space.IsInitialColumnBalancingPass()) { + // The |fragmentainer_offset_delta| will not make a difference in the + // initial column balancing pass. + SetupSpaceBuilderForFragmentation( + space, node, /* fragmentainer_offset_delta */ LayoutUnit(), + &builder, /* is_new_fc */ true); + } result = node.Layout(builder.ToConstraintSpace()); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc index a8dd91fef2..4dc13a4 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -1426,6 +1426,16 @@ layout_box->SetLocationAndUpdateOverflowControlsIfNeeded(point); } +void NGBlockNode::MakeRoomForExtraColumns(LayoutUnit block_size) const { + auto* block_flow = DynamicTo<LayoutBlockFlow>(GetLayoutBox()); + DCHECK(block_flow && block_flow->MultiColumnFlowThread()); + MultiColumnFragmentainerGroup& last_group = + block_flow->MultiColumnFlowThread() + ->LastMultiColumnSet() + ->LastFragmentainerGroup(); + last_group.ExtendLogicalBottomInFlowThread(block_size); +} + void NGBlockNode::CopyFragmentItemsToLayoutBox( const NGPhysicalBoxFragment& container, const NGFragmentItems& items,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.h b/third_party/blink/renderer/core/layout/ng/ng_block_node.h index 6711e82e..2963332d 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_block_node.h +++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.h
@@ -215,6 +215,11 @@ const NGPhysicalBoxFragment& container_fragment, const NGBlockBreakToken* previous_container_break_token = nullptr) const; + // If extra columns are added after a multicol has been written back to + // legacy, for example for an OOF positioned element, we need to update the + // legacy flow thread to encompass those extra columns. + void MakeRoomForExtraColumns(LayoutUnit block_size) const; + String ToString() const; private:
diff --git a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h index 40a0490..907b060 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h
@@ -137,8 +137,8 @@ LayoutUnit FragmentBlockSize() const { #if DCHECK_IS_ON() - if (has_block_fragmentation_) - DCHECK(!block_size_is_for_all_fragments_); + DCHECK(!block_size_is_for_all_fragments_ || !has_block_fragmentation_ || + IsInitialColumnBalancingPass()); DCHECK(size_.block_size != kIndefiniteSize); #endif return size_.block_size;
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc index 8d0ca2e..c2768ea 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -484,6 +484,11 @@ IsEarlyBreakTarget(*early_break_, container_builder_, spanner_node)) break; + // Handle any OOF fragmentainer descendants that were found before the + // spanner. + NGOutOfFlowLayoutPart(Node(), ConstraintSpace(), &container_builder_) + .HandleFragmentation(); + NGBreakStatus break_status = LayoutSpanner(spanner_node, child_break_token, &margin_strut);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h b/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h index ac08abb5..9444771 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h
@@ -542,10 +542,6 @@ delegate_.SetBlockAutoBehavior(auto_behavior); } - void SetIsInitialBlockSizeIndefinite(bool b) { - delegate_.SetIsInitialBlockSizeIndefinite(b); - } - const NGConstraintSpace ToConstraintSpace() { return delegate_.ToConstraintSpace(); }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h b/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h index 312b4da3..f86e751 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h +++ b/third_party/blink/renderer/core/layout/ng/ng_fragment_builder.h
@@ -56,6 +56,8 @@ } void SetBlockSize(LayoutUnit block_size) { size_.block_size = block_size; } + bool HasBlockSize() const { return size_.block_size != kIndefiniteSize; } + void SetIsHiddenForPaint(bool value) { is_hidden_for_paint_ = value; } void SetHasCollapsedBorders(bool value) { has_collapsed_borders_ = value; }
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc index accb1fcf0..434aef8 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -19,9 +19,7 @@ #include "third_party/blink/renderer/core/layout/ng/ng_box_fragment_builder.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h" #include "third_party/blink/renderer/core/layout/ng/ng_fragment.h" -#include "third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_layout_result.h" -#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_positioned_node.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_fragment.h" @@ -117,12 +115,14 @@ const NGBoxStrut border_scrollbar = container_builder->Borders() + container_builder->Scrollbar(); allow_first_tier_oof_cache_ = border_scrollbar.IsEmpty(); - default_containing_block_info_for_absolute_.rect.size = - ShrinkLogicalSize(container_builder_->Size(), border_scrollbar); - default_containing_block_info_for_fixed_.rect.size = - initial_containing_block_fixed_size - ? *initial_containing_block_fixed_size - : default_containing_block_info_for_absolute_.rect.size; + if (container_builder_->HasBlockSize()) { + default_containing_block_info_for_absolute_.rect.size = + ShrinkLogicalSize(container_builder_->Size(), border_scrollbar); + default_containing_block_info_for_fixed_.rect.size = + initial_containing_block_fixed_size + ? *initial_containing_block_fixed_size + : default_containing_block_info_for_absolute_.rect.size; + } LogicalOffset container_offset = {border_scrollbar.inline_start, border_scrollbar.block_start}; default_containing_block_info_for_absolute_.rect.offset = container_offset; @@ -130,25 +130,7 @@ } void NGOutOfFlowLayoutPart::Run(const LayoutBox* only_layout) { - if (container_builder_->IsBlockFragmentationContextRoot() && - !has_block_fragmentation_) { - while (container_builder_->HasOutOfFlowFragmentainerDescendants() || - container_builder_->HasMulticolsWithPendingOOFs()) { - HandleMulticolsWithPendingOOFs(container_builder_); - if (container_builder_->HasOutOfFlowFragmentainerDescendants()) { - Vector<NGLogicalOutOfFlowPositionedNode> fragmentainer_descendants; - container_builder_->SwapOutOfFlowFragmentainerDescendants( - &fragmentainer_descendants); - DCHECK(!fragmentainer_descendants.IsEmpty()); - LayoutUnit column_inline_progression = ColumnInlineProgression( - container_builder_->ChildAvailableSize().inline_size, - container_builder_->Style()); - LayoutFragmentainerDescendants(&fragmentainer_descendants, - column_inline_progression); - } - } - } - + HandleFragmentation(); const LayoutObject* current_container = container_builder_->GetLayoutObject(); if (!container_builder_->HasOutOfFlowPositionedCandidates() && !To<LayoutBlock>(current_container)->HasPositionedObjects()) { @@ -299,6 +281,28 @@ return true; } +void NGOutOfFlowLayoutPart::HandleFragmentation() { + if (!container_builder_->IsBlockFragmentationContextRoot() || + has_block_fragmentation_) + return; + + while (container_builder_->HasOutOfFlowFragmentainerDescendants() || + container_builder_->HasMulticolsWithPendingOOFs()) { + HandleMulticolsWithPendingOOFs(container_builder_); + if (container_builder_->HasOutOfFlowFragmentainerDescendants()) { + Vector<NGLogicalOutOfFlowPositionedNode> fragmentainer_descendants; + container_builder_->SwapOutOfFlowFragmentainerDescendants( + &fragmentainer_descendants); + DCHECK(!fragmentainer_descendants.IsEmpty()); + LayoutUnit column_inline_progression = ColumnInlineProgression( + container_builder_->ChildAvailableSize().inline_size, + container_builder_->Style()); + LayoutFragmentainerDescendants(&fragmentainer_descendants, + column_inline_progression); + } + } +} + // Retrieve the stored ContainingBlockInfo needed for placing positioned nodes. // When fragmenting, the ContainingBlockInfo is not stored ahead of time and // must be generated on demand. The reason being that during fragmentation, we @@ -637,7 +641,8 @@ const LayoutBox* only_layout, HashSet<const LayoutObject*>* placed_objects) { while (candidates->size() > 0) { - if (!has_block_fragmentation_) + if (!has_block_fragmentation_ || + container_builder_->IsInitialColumnBalancingPass()) ComputeInlineContainingBlocks(*candidates); for (auto& candidate : *candidates) { LayoutBox* layout_box = candidate.box; @@ -647,7 +652,8 @@ (!only_layout || layout_box == only_layout)) { if (layout_box != only_layout) candidate.Node().InsertIntoLegacyPositionedObjects(); - if (has_block_fragmentation_) { + if (has_block_fragmentation_ && + !container_builder_->IsInitialColumnBalancingPass()) { container_builder_->AdjustOffsetsForFragmentainerDescendant( candidate); container_builder_->AdjustFixedposContainingBlockForInnerMulticols(); @@ -662,6 +668,10 @@ container_builder_->AddChild(result->PhysicalFragment(), result->OutOfFlowPositionedOffset(), &candidate.inline_container); + if (container_builder_->IsInitialColumnBalancingPass()) { + container_builder_->PropagateTallestUnbreakableBlockSize( + result->TallestUnbreakableBlockSize()); + } placed_objects->insert(layout_box); } else { container_builder_->AddOutOfFlowDescendant(candidate); @@ -920,13 +930,23 @@ // had. algorithm.CloneOldChildren(); + WritingModeConverter converter(constraint_space.GetWritingDirection(), + old_result->PhysicalFragment().Size()); + LayoutUnit additional_column_block_size; // Then append the new fragmentainers. for (wtf_size_t i = old_fragment_count; i < new_fragment_count; i++) { NGContainerFragmentBuilder::ChildWithOffset child = limited_multicol_container_builder.Children()[i]; algorithm.AppendNewChildFragment(*child.fragment, child.offset); + additional_column_block_size += + converter.ToLogical(child.fragment->Size()).block_size; } + // We've already written back to legacy for |multicol|, but if we added + // new columns to hold any OOF descendants, we need to extend the final + // size of the legacy flow thread to encompass those new columns. + multicol.MakeRoomForExtraColumns(additional_column_block_size); + // Create a new multicol container fragment and replace all references to // the old one with this new one. scoped_refptr<const NGLayoutResult> new_result = @@ -1086,6 +1106,15 @@ builder.SetAvailableSize(container_content_size); builder.SetPercentageResolutionSize(container_content_size); + if (container_builder_->IsInitialColumnBalancingPass()) { + // The |fragmentainer_offset_delta| will not make a difference in the + // initial column balancing pass. + SetupSpaceBuilderForFragmentation( + *container_builder_->ConstraintSpace(), node, + /* fragmentainer_offset_delta */ LayoutUnit(), &builder, + /* is_new_fc */ true); + } + DCHECK(!oof_node.fixedpos_containing_block.fragment || containing_block_fragment); DCHECK(oof_node.fixedpos_containing_block.offset == LogicalOffset() || @@ -1343,6 +1372,10 @@ SetupSpaceBuilderForFragmentation(*fragmentainer_constraint_space, node, block_offset, &builder, /* is_new_fc */ true); + } else if (container_builder_->IsInitialColumnBalancingPass()) { + SetupSpaceBuilderForFragmentation(*container_builder_->ConstraintSpace(), + node, block_offset, &builder, + /* is_new_fc */ true); } NGConstraintSpace space = builder.ToConstraintSpace();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h index b52ea5ca..38fb68e 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h
@@ -70,6 +70,9 @@ // LayoutResult::OutOfFlowPositionedDescendants. void Run(const LayoutBox* only_layout = nullptr); + // Handle the layout of any OOF elements in a fragmentation context. + void HandleFragmentation(); + private: // Information needed to position descendant within a containing block. // Geometry expressed here is complicated:
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc index 2b19605..7c61ae0 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part_test.cc
@@ -1022,25 +1022,17 @@ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:1000x40 offset:0,0 size:1000x40 - offset:0,0 size:492x10 - offset:0,0 size:30x10 - offset:0,0 size:30x10 - offset:0,0 size:5x10 - offset:508,0 size:492x10 - offset:0,0 size:30x10 - offset:0,0 size:30x10 - offset:0,0 size:5x10 - offset:0,10 size:1000x0 - offset:0,10 size:1000x0 - offset:0,10 size:1000x0 - offset:0,10 size:492x30 - offset:0,0 size:5x30 - offset:508,10 size:492x30 - offset:0,0 size:5x30 - offset:1016,10 size:492x30 - offset:0,0 size:5x30 - offset:1524,10 size:492x30 - offset:0,0 size:5x10 + offset:0,0 size:492x40 + offset:0,0 size:30x20 + offset:0,0 size:30x20 + offset:0,0 size:5x40 + offset:508,0 size:492x40 + offset:0,0 size:5x40 + offset:1016,0 size:492x40 + offset:0,0 size:5x40 + offset:0,40 size:1000x0 + offset:0,40 size:1000x0 + offset:0,40 size:1000x0 )DUMP"; EXPECT_EQ(expectation, dump); } @@ -1079,17 +1071,13 @@ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:1000x40 offset:0,0 size:1000x40 - offset:0,0 size:492x10 - offset:0,0 size:30x10 - offset:0,0 size:30x10 - offset:508,0 size:492x10 - offset:0,0 size:30x10 - offset:0,0 size:30x10 - offset:0,10 size:1000x0 - offset:0,10 size:492x30 - offset:0,5 size:5x25 - offset:508,10 size:492x30 - offset:0,0 size:5x25 + offset:0,0 size:492x37.5 + offset:0,0 size:30x20 + offset:0,0 size:30x20 + offset:0,25 size:5x12.5 + offset:508,0 size:492x37.5 + offset:0,0 size:5x37.5 + offset:0,37.5 size:1000x0 )DUMP"; EXPECT_EQ(expectation, dump); } @@ -1126,20 +1114,16 @@ String dump = DumpFragmentTree(GetElementById("container")); String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. - offset:unplaced size:1000x0 - offset:0,0 size:1000x0 - offset:0,0 size:492x0 + offset:unplaced size:1000x2 + offset:0,0 size:1000x2 + offset:0,0 size:492x2 offset:0,0 size:30x0 - offset:0,0 size:5x1 - offset:0,0 size:1000x0 - offset:0,0 size:1000x0 - offset:0,0 size:1000x0 - offset:0,0 size:492x0 - offset:0,0 size:5x1 - offset:508,0 size:492x0 - offset:0,0 size:5x1 - offset:1016,0 size:492x0 - offset:0,0 size:5x1 + offset:0,0 size:5x2 + offset:508,0 size:492x2 + offset:0,0 size:5x2 + offset:0,2 size:1000x0 + offset:0,2 size:1000x0 + offset:0,2 size:1000x0 )DUMP"; EXPECT_EQ(expectation, dump); } @@ -1177,20 +1161,18 @@ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:1000x40 offset:0,0 size:1000x40 - offset:0,0 size:492x0 - offset:0,0 size:30x0 - offset:0,0 size:1000x0 - offset:0,0 size:1000x0 - offset:0,0 size:1000x0 offset:0,0 size:492x40 + offset:0,0 size:30x0 offset:508,0 size:492x40 - offset:0,39 size:5x1 offset:1016,0 size:492x40 offset:0,0 size:5x40 offset:1524,0 size:492x40 offset:0,0 size:5x40 offset:2032,0 size:492x40 - offset:0,0 size:5x39 + offset:0,0 size:5x40 + offset:0,40 size:1000x0 + offset:0,40 size:1000x0 + offset:0,40 size:1000x0 )DUMP"; EXPECT_EQ(expectation, dump); } @@ -1228,17 +1210,12 @@ String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. offset:unplaced size:1000x40 offset:0,0 size:1000x40 - offset:0,0 size:492x15 - offset:0,0 size:30x15 - offset:0,0 size:10x15 - offset:508,0 size:492x15 - offset:0,0 size:30x15 - offset:0,0 size:10x15 - offset:0,15 size:1000x10 - offset:0,25 size:492x15 - offset:0,0 size:5x15 - offset:508,25 size:492x15 - offset:0,0 size:5x15 + offset:0,0 size:492x30 + offset:0,0 size:30x30 + offset:0,0 size:10x30 + offset:508,0 size:492x30 + offset:0,0 size:5x30 + offset:0,30 size:1000x10 )DUMP"; EXPECT_EQ(expectation, dump); } @@ -1390,16 +1367,13 @@ offset:0,0 size:500x100 offset:0,0 size:40x40 offset:0,40 size:500x60 - offset:10,10 size:232x10 - offset:0,0 size:55x10 - offset:0,0 size:5x10 - offset:258,10 size:232x10 - offset:0,0 size:55x10 - offset:0,0 size:5x10 - offset:10,20 size:480x0 - offset:10,20 size:480x0 - offset:10,20 size:480x0 - offset:10,20 size:232x40 + offset:10,10 size:232x20 + offset:0,0 size:55x20 + offset:0,0 size:5x20 + offset:10,30 size:480x0 + offset:10,30 size:480x0 + offset:10,30 size:480x0 + offset:10,30 size:232x40 offset:0,0 size:5x20 )DUMP"; EXPECT_EQ(expectation, dump); @@ -1444,21 +1418,18 @@ offset:0,0 size:1000x100 offset:0,0 size:500x100 offset:0,0 size:40x40 - offset:0,40 size:500x40 - offset:0,0 size:242x40 - offset:0,0 size:55x40 - offset:258,0 size:242x40 - offset:0,0 size:55x40 - offset:0,40 size:500x0 - offset:0,40 size:500x0 - offset:0,40 size:500x0 - offset:0,40 size:242x40 - offset:258,40 size:242x40 - offset:0,0 size:5x40 - offset:516,40 size:242x40 - offset:0,0 size:5x40 - offset:774,40 size:242x40 - offset:0,0 size:5x40 + offset:0,40 size:500x60 + offset:0,0 size:242x60 + offset:0,0 size:55x60 + offset:258,0 size:242x60 + offset:0,0 size:55x20 + offset:0,60 size:500x0 + offset:0,60 size:500x0 + offset:0,60 size:500x0 + offset:0,60 size:242x60 + offset:0,0 size:5x60 + offset:258,60 size:242x60 + offset:0,0 size:5x60 )DUMP"; EXPECT_EQ(expectation, dump); } @@ -1510,6 +1481,57 @@ EXPECT_EQ(expectation, dump); } +// Tests an OOF element with an inline containing block inside a multicol +// with a column spanner. +TEST_F(NGOutOfFlowLayoutPartTest, AbsposFragWithInlineCBAndSpanner) { + SetBodyInnerHTML( + R"HTML( + <style> + #multicol { + column-count:2; column-fill:auto; column-gap:16px; height:40px; + } + .rel { + position: relative; width:30px; + } + .abs { + position:absolute; top:80px; width:5px; height:120px; + } + </style> + <div id="container"> + <div id="multicol"> + <div> + <span class="rel"> + <div class="abs"></div> + </span> + </div> + <div style="column-span:all;"></div> + <div style="column-span:all;"></div> + <div style="column-span:all;"></div> + </div> + </div> + )HTML"); + String dump = DumpFragmentTree(GetElementById("container")); + + String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. + offset:unplaced size:1000x40 + offset:0,0 size:1000x40 + offset:0,0 size:492x40 + offset:0,0 size:492x0 + offset:0,0 size:0x0 + offset:508,0 size:492x40 + offset:1016,0 size:492x40 + offset:0,0 size:5x40 + offset:1524,0 size:492x40 + offset:0,0 size:5x40 + offset:2032,0 size:492x40 + offset:0,0 size:5x40 + offset:0,40 size:1000x0 + offset:0,40 size:1000x0 + offset:0,40 size:1000x0 +)DUMP"; + EXPECT_EQ(expectation, dump); +} + TEST_F(NGOutOfFlowLayoutPartTest, PositionedObjectsInMulticol) { SetBodyInnerHTML( R"HTML(
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 8a176f4..2e4a02b 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
@@ -45,7 +45,6 @@ #include "third_party/blink/renderer/core/paint/paint_timing_detector.h" #include "third_party/blink/renderer/core/paint/rounded_border_geometry.h" #include "third_party/blink/renderer/core/paint/scoped_paint_state.h" -#include "third_party/blink/renderer/core/paint/scoped_svg_paint_state.h" #include "third_party/blink/renderer/core/paint/scrollable_area_painter.h" #include "third_party/blink/renderer/core/paint/theme_painter.h" #include "third_party/blink/renderer/core/paint/url_metadata_utils.h" @@ -1656,14 +1655,7 @@ return; } - const LayoutObject* layout_object = child_fragment.GetLayoutObject(); if (child_fragment.IsInlineBox()) { - if (layout_object->IsSVGInline()) { - ScopedSVGPaintState paint_state(*layout_object, paint_info); - NGInlineBoxFragmentPainter(cursor, item, child_fragment) - .Paint(paint_info, paint_offset); - return; - } NGInlineBoxFragmentPainter(cursor, item, child_fragment) .Paint(paint_info, paint_offset); return; @@ -1671,7 +1663,7 @@ // Block-in-inline DCHECK(RuntimeEnabledFeatures::LayoutNGBlockInInlineEnabled()); - DCHECK(!layout_object->IsInline()); + DCHECK(!child_fragment.GetLayoutObject()->IsInline()); PaintInfo paint_info_for_descendants = paint_info.ForDescendants(); paint_info_for_descendants.SetIsInFragmentTraversal(); PaintBlockChild({&child_fragment, item.OffsetInContainerFragment()},
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 33de06c..1b10dc65 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -1567,7 +1567,8 @@ HashSet<QualifiedName> set_attributes; for (const Attribute& attr : attributes) { set_attributes.insert(attr.GetName()); - AXSparseSetterFunc callback = setter_map.at(attr.GetName()); + AXSparseSetterFunc callback = + setter_map.DeprecatedAtOrEmptyValue(attr.GetName()); if (callback) callback.Run(this, node_data, attr.Value()); @@ -1581,7 +1582,7 @@ if (set_attributes.Contains(attr)) continue; - AXSparseSetterFunc callback = setter_map.at(attr); + AXSparseSetterFunc callback = setter_map.DeprecatedAtOrEmptyValue(attr); if (callback) callback.Run(this, node_data, internals_attributes.at(attr)); @@ -5252,7 +5253,7 @@ value.Split(' ', role_vector); ax::mojom::blink::Role role = ax::mojom::blink::Role::kUnknown; for (const auto& child : role_vector) { - role = role_map->at(child); + role = role_map->DeprecatedAtOrEmptyValue(child); if (role != ax::mojom::blink::Role::kUnknown) return role; }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index f8ad056..abacc99 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -641,7 +641,7 @@ if (!layout_object) return nullptr; - AXID ax_id = layout_object_mapping_.at(layout_object); + AXID ax_id = layout_object_mapping_.DeprecatedAtOrEmptyValue(layout_object); DCHECK(!HashTraits<AXID>::IsDeletedValue(ax_id)); Node* node = layout_object->GetNode(); @@ -683,14 +683,17 @@ LayoutObject* layout_object = node->GetLayoutObject(); - AXID layout_id = layout_object ? layout_object_mapping_.at(layout_object) : 0; + AXID layout_id = + layout_object + ? layout_object_mapping_.DeprecatedAtOrEmptyValue(layout_object) + : 0; DCHECK(!HashTraits<AXID>::IsDeletedValue(layout_id)); if (layout_id) - return objects_.at(layout_id); + return objects_.DeprecatedAtOrEmptyValue(layout_id); - AXID node_id = node_object_mapping_.at(node); + AXID node_id = node_object_mapping_.DeprecatedAtOrEmptyValue(node); DCHECK(!HashTraits<AXID>::IsDeletedValue(node_id)); - return node_id ? objects_.at(node_id) : nullptr; + return node_id ? objects_.DeprecatedAtOrEmptyValue(node_id) : nullptr; } AXObject* AXObjectCacheImpl::Get(const Node* node) { @@ -699,10 +702,13 @@ LayoutObject* layout_object = node->GetLayoutObject(); - AXID layout_id = layout_object ? layout_object_mapping_.at(layout_object) : 0; + AXID layout_id = + layout_object + ? layout_object_mapping_.DeprecatedAtOrEmptyValue(layout_object) + : 0; DCHECK(!HashTraits<AXID>::IsDeletedValue(layout_id)); - AXID node_id = node_object_mapping_.at(node); + AXID node_id = node_object_mapping_.DeprecatedAtOrEmptyValue(node); DCHECK(!HashTraits<AXID>::IsDeletedValue(node_id)); if (!layout_id && !node_id) @@ -749,7 +755,7 @@ } if (layout_id) { - AXObject* result = objects_.at(layout_id); + AXObject* result = objects_.DeprecatedAtOrEmptyValue(layout_id); #if DCHECK_IS_ON() DCHECK(result) << "Had AXID for LayoutObject but no entry in objects_"; DCHECK(result->IsAXLayoutObject()); @@ -763,7 +769,7 @@ DCHECK(node_id); - AXObject* result = objects_.at(node_id); + AXObject* result = objects_.DeprecatedAtOrEmptyValue(node_id); #if DCHECK_IS_ON() DCHECK(result) << "Had AXID for Node but no entry in objects_"; DCHECK(result->IsAXNodeObject()); @@ -779,12 +785,13 @@ if (!inline_text_box) return nullptr; - AXID ax_id = inline_text_box_object_mapping_.at(inline_text_box); + AXID ax_id = + inline_text_box_object_mapping_.DeprecatedAtOrEmptyValue(inline_text_box); DCHECK(!HashTraits<AXID>::IsDeletedValue(ax_id)); if (!ax_id) return nullptr; - AXObject* result = objects_.at(ax_id); + AXObject* result = objects_.DeprecatedAtOrEmptyValue(ax_id); #if DCHECK_IS_ON() DCHECK(result) << "Had AXID for inline text box but no entry in objects_"; DCHECK(result->IsAXInlineTextBox()); @@ -819,12 +826,13 @@ if (!accessible_node) return nullptr; - AXID ax_id = accessible_node_mapping_.at(accessible_node); + AXID ax_id = + accessible_node_mapping_.DeprecatedAtOrEmptyValue(accessible_node); DCHECK(!HashTraits<AXID>::IsDeletedValue(ax_id)); if (!ax_id) return nullptr; - AXObject* result = objects_.at(ax_id); + AXObject* result = objects_.DeprecatedAtOrEmptyValue(ax_id); #if DCHECK_IS_ON() DCHECK(result) << "Had AXID for accessible_node but no entry in objects_"; DCHECK(result->IsVirtualObject()); @@ -1102,13 +1110,13 @@ // One of the above calls could have already created the planned object via a // recursive call to GetOrCreate(). If so, just return that object. - if (node_object_mapping_.at(node)) + if (node_object_mapping_.DeprecatedAtOrEmptyValue(node)) return Get(node); AXObject* new_obj = CreateFromNode(node); // Will crash later if we have two objects for the same node. - DCHECK(!node_object_mapping_.at(node)) + DCHECK(!node_object_mapping_.DeprecatedAtOrEmptyValue(node)) << "Already have an AXObject for " << node; const AXID ax_id = AssociateAXID(new_obj, use_axid); @@ -1215,7 +1223,7 @@ // Example: parent calls Init() => ComputeAccessibilityIsIgnored() => // CanSetFocusAttribute() => CanBeActiveDescendant() => // IsARIAControlledByTextboxWithActiveDescendant() => GetOrCreate(). - if (layout_object_mapping_.at(layout_object)) { + if (layout_object_mapping_.DeprecatedAtOrEmptyValue(layout_object)) { AXObject* result = Get(layout_object); DCHECK(result) << "Missing cached AXObject for " << layout_object; return result; @@ -1226,7 +1234,7 @@ DCHECK(new_obj) << "Could not create AXObject for " << layout_object; // Will crash later if we have two objects for the same layoutObject. - DCHECK(!layout_object_mapping_.at(layout_object)) + DCHECK(!layout_object_mapping_.DeprecatedAtOrEmptyValue(layout_object)) << "Already have an AXObject for " << layout_object; const AXID axid = AssociateAXID(new_obj, use_axid);
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h index 6091c2b..7b00d88 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -190,7 +190,9 @@ void OnTouchAccessibilityHover(const IntPoint&) override; - AXObject* ObjectFromAXID(AXID id) const { return objects_.at(id); } + AXObject* ObjectFromAXID(AXID id) const { + return objects_.DeprecatedAtOrEmptyValue(id); + } AXObject* Root(); // Used for objects without backing DOM nodes, layout objects, etc.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc index b68cb22..c1a325d 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
@@ -388,7 +388,8 @@ // Compare this to the current list of owned children, and exit early if // there are no changes. Vector<AXID> previously_owned_child_ids = - aria_owner_to_children_mapping_.at(owner->AXObjectID()); + aria_owner_to_children_mapping_.DeprecatedAtOrEmptyValue( + owner->AXObjectID()); // Only force the refresh if there was or will be owned children; otherwise, // there is nothing to refresh even for a new AXObject replacing an old owner.
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc b/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc index a9b0a45c..02d47dec 100644 --- a/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc +++ b/third_party/blink/renderer/modules/canvas/canvas2d/hit_region.cc
@@ -96,7 +96,7 @@ HitRegion* HitRegionManager::GetHitRegionByControl( const Element* control) const { if (control) - return hit_region_control_map_.at(control); + return hit_region_control_map_.DeprecatedAtOrEmptyValue(control); return nullptr; }
diff --git a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc index 5a3e2b0..5e77846 100644 --- a/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc +++ b/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.cc
@@ -34,6 +34,8 @@ const size_t kHardMaxCachedFonts = 250; const size_t kMaxCachedFonts = 25; const float kUMASampleProbability = 0.01; +// Max delay to fire context lost for context in iframes. +static const unsigned kMaxIframeContextLoseDelay = 100; class OffscreenFontCache { public: @@ -329,7 +331,9 @@ if (context_lost_mode_ == kSyntheticLostContext && Host()) { Host()->DiscardResourceProvider(); } - dispatch_context_lost_event_timer_.StartOneShot(base::TimeDelta(), FROM_HERE); + uint32_t delay = base::RandInt(1, kMaxIframeContextLoseDelay); + dispatch_context_lost_event_timer_.StartOneShot( + base::TimeDelta::FromMilliseconds(delay), FROM_HERE); } bool OffscreenCanvasRenderingContext2D::IsPaintable() const {
diff --git a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc index 66c9d96..32f429b 100644 --- a/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc +++ b/third_party/blink/renderer/modules/credentialmanager/credentials_container.cc
@@ -912,17 +912,30 @@ mojo_options->is_payment_credential_creation = true; - // Download instrument icon and prompt the user before creating the - // credential. - auto* payment_credential_remote = - CredentialManagerProxy::From(resolver->GetScriptState()) - ->PaymentCredential(); - payment_credential_remote->DownloadIconAndShowUserPrompt( - PaymentCredentialInstrument::New(options->instrument()->displayName(), - KURL(options->instrument()->icon())), - WTF::Bind(&DidDownloadPaymentCredentialIconAndShowUserPrompt, - std::make_unique<ScopedPromiseResolver>(resolver), - std::move(mojo_options), WrapPersistent(options))); + // SecurePaymentConfirmationAPIV3 skips downloading instrument icon and + // showing user prompt. + if (RuntimeEnabledFeatures::SecurePaymentConfirmationAPIV3Enabled()) { + auto* authenticator = + CredentialManagerProxy::From(resolver->GetScriptState()) + ->Authenticator(); + authenticator->MakeCredential( + std::move(mojo_options), + WTF::Bind(&OnMakePublicKeyCredentialForPaymentComplete, + std::make_unique<ScopedPromiseResolver>(resolver), + WrapPersistent(options))); + } else { + // Download instrument icon and prompt the user before creating the + // credential. + auto* payment_credential_remote = + CredentialManagerProxy::From(resolver->GetScriptState()) + ->PaymentCredential(); + payment_credential_remote->DownloadIconAndShowUserPrompt( + PaymentCredentialInstrument::New(options->instrument()->displayName(), + KURL(options->instrument()->icon())), + WTF::Bind(&DidDownloadPaymentCredentialIconAndShowUserPrompt, + std::make_unique<ScopedPromiseResolver>(resolver), + std::move(mojo_options), WrapPersistent(options))); + } } void CreatePublicKeyCredentialForPaymentCredential(
diff --git a/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc b/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc index e7764e2..2e96087 100644 --- a/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc +++ b/third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.cc
@@ -61,7 +61,8 @@ } bool CSSPaintImageGeneratorImpl::HasDocumentDefinition() const { - return paint_worklet_->GetDocumentDefinitionMap().at(name_); + return paint_worklet_->GetDocumentDefinitionMap().DeprecatedAtOrEmptyValue( + name_); } bool CSSPaintImageGeneratorImpl::GetValidDocumentDefinition(
diff --git a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc index a0d4e00..154d66b 100644 --- a/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc +++ b/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.cc
@@ -236,7 +236,7 @@ CSSPaintDefinition* PaintWorkletGlobalScope::FindDefinition( const String& name) { - return paint_definitions_.at(name); + return paint_definitions_.DeprecatedAtOrEmptyValue(name); } double PaintWorkletGlobalScope::devicePixelRatio() const {
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl b/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl index a15f3fde..d43f34aa 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl +++ b/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl
@@ -8,5 +8,5 @@ (boolean or MediaTrackConstraints) video = false; (boolean or MediaTrackConstraints) audio = false; // https://wicg.github.io/prefer-current-tab/#prefer-current-tab - [RuntimeEnabled = GetCurrentBrowsingContextMedia] boolean preferCurrentTab = false; + boolean preferCurrentTab = false; };
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index 715fb2c1..35df8de 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -2704,7 +2704,7 @@ MediaStreamTrack* RTCPeerConnection::GetTrack( MediaStreamComponent* component) const { - return tracks_.at(component); + return tracks_.DeprecatedAtOrEmptyValue(component); } RTCRtpSender* RTCPeerConnection::FindSenderForTrackAndStream(
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_container.cc b/third_party/blink/renderer/modules/service_worker/service_worker_container.cc index 29a82d5..f21a439 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_container.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
@@ -573,7 +573,8 @@ return nullptr; ServiceWorkerRegistration* registration = - service_worker_registration_objects_.at(info.registration_id); + service_worker_registration_objects_.DeprecatedAtOrEmptyValue( + info.registration_id); if (registration) { registration->Attach(std::move(info)); return registration; @@ -590,7 +591,8 @@ WebServiceWorkerObjectInfo info) { if (info.version_id == mojom::blink::kInvalidServiceWorkerVersionId) return nullptr; - ServiceWorker* worker = service_worker_objects_.at(info.version_id); + ServiceWorker* worker = + service_worker_objects_.DeprecatedAtOrEmptyValue(info.version_id); if (!worker) { const int64_t version_id = info.version_id; worker = ServiceWorker::Create(GetSupplementable()->GetExecutionContext(),
diff --git a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc index 39559c13..73fce14 100644 --- a/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc +++ b/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -707,7 +707,8 @@ WebServiceWorkerObjectInfo info) { if (info.version_id == mojom::blink::kInvalidServiceWorkerVersionId) return nullptr; - ::blink::ServiceWorker* worker = service_worker_objects_.at(info.version_id); + ::blink::ServiceWorker* worker = + service_worker_objects_.DeprecatedAtOrEmptyValue(info.version_id); if (!worker) { const int64_t version_id = info.version_id; worker = ::blink::ServiceWorker::Create(this, std::move(info));
diff --git a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc index 2d627f6..426e431 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.cc
@@ -218,7 +218,7 @@ AudioWorkletProcessorDefinition* AudioWorkletGlobalScope::FindDefinition( const String& name) { - return processor_definition_map_.at(name); + return processor_definition_map_.DeprecatedAtOrEmptyValue(name); } unsigned AudioWorkletGlobalScope::NumberOfRegisteredDefinitions() {
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index af284e4..a1c302b 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -540,7 +540,6 @@ "exported/web_font.cc", "exported/web_font_description.cc", "exported/web_http_body.cc", - "exported/web_http_load_info.cc", "exported/web_icon_sizes_parser.cc", "exported/web_image_generator.cc", "exported/web_media_player_client.cc",
diff --git a/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.cc b/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.cc index cfa2014..7d3f0f0 100644 --- a/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.cc +++ b/third_party/blink/renderer/platform/blob/blob_url_null_origin_map.cc
@@ -39,7 +39,8 @@ DCHECK_EQ(BlobURL::GetOrigin(blob_url), "null"); KURL blob_url_without_fragment = blob_url; blob_url_without_fragment.RemoveFragmentIdentifier(); - return blob_url_null_origin_map_.at(blob_url_without_fragment.GetString()); + return blob_url_null_origin_map_.DeprecatedAtOrEmptyValue( + blob_url_without_fragment.GetString()); } BlobURLOpaqueOriginNonceMap& BlobURLOpaqueOriginNonceMap::GetInstance() {
diff --git a/third_party/blink/renderer/platform/exported/web_http_load_info.cc b/third_party/blink/renderer/platform/exported/web_http_load_info.cc deleted file mode 100644 index f439af5..0000000 --- a/third_party/blink/renderer/platform/exported/web_http_load_info.cc +++ /dev/null
@@ -1,121 +0,0 @@ -/* - * Copyright (C) 2010 Google 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: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "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 THE COPYRIGHT - * OWNER 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/public/platform/web_http_load_info.h" - -#include "third_party/blink/public/platform/web_http_header_visitor.h" -#include "third_party/blink/public/platform/web_string.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_load_info.h" - -namespace blink { - -void WebHTTPLoadInfo::Initialize() { - private_ = base::AdoptRef(new ResourceLoadInfo()); -} - -void WebHTTPLoadInfo::Reset() { - private_.Reset(); -} - -void WebHTTPLoadInfo::Assign(const WebHTTPLoadInfo& r) { - private_ = r.private_; -} - -WebHTTPLoadInfo::WebHTTPLoadInfo(scoped_refptr<ResourceLoadInfo> value) - : private_(std::move(value)) {} - -WebHTTPLoadInfo::operator scoped_refptr<ResourceLoadInfo>() const { - return private_.Get(); -} - -int WebHTTPLoadInfo::HttpStatusCode() const { - DCHECK(!private_.IsNull()); - return private_->http_status_code; -} - -void WebHTTPLoadInfo::SetHTTPStatusCode(int status_code) { - DCHECK(!private_.IsNull()); - private_->http_status_code = status_code; -} - -WebString WebHTTPLoadInfo::HttpStatusText() const { - DCHECK(!private_.IsNull()); - return private_->http_status_text; -} - -void WebHTTPLoadInfo::SetHTTPStatusText(const WebString& status_text) { - DCHECK(!private_.IsNull()); - private_->http_status_text = status_text; -} - -static void AddHeader(HTTPHeaderMap* map, - const WebString& name, - const WebString& value) { - HTTPHeaderMap::AddResult result = map->Add(name, value); - // It is important that values are separated by '\n', not comma, otherwise - // Set-Cookie header is not parseable. - if (!result.is_new_entry) - result.stored_value->value = - result.stored_value->value + "\n" + String(value); -} - -void WebHTTPLoadInfo::AddRequestHeader(const WebString& name, - const WebString& value) { - DCHECK(!private_.IsNull()); - AddHeader(&private_->request_headers, name, value); -} - -void WebHTTPLoadInfo::AddResponseHeader(const WebString& name, - const WebString& value) { - DCHECK(!private_.IsNull()); - AddHeader(&private_->response_headers, name, value); -} - -WebString WebHTTPLoadInfo::RequestHeadersText() const { - DCHECK(!private_.IsNull()); - return private_->request_headers_text; -} - -void WebHTTPLoadInfo::SetRequestHeadersText(const WebString& headers_text) { - DCHECK(!private_.IsNull()); - private_->request_headers_text = headers_text; -} - -WebString WebHTTPLoadInfo::ResponseHeadersText() const { - DCHECK(!private_.IsNull()); - return private_->response_headers_text; -} - -void WebHTTPLoadInfo::SetResponseHeadersText(const WebString& headers_text) { - DCHECK(!private_.IsNull()); - private_->response_headers_text = headers_text; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc index a6d25f8d..e5e2f4c 100644 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
@@ -600,10 +600,6 @@ RuntimeEnabledFeatures::SetGetDisplayMediaEnabled(enable); } -void WebRuntimeFeatures::EnableGetCurrentBrowsingContextMedia(bool enable) { - RuntimeEnabledFeatures::SetGetCurrentBrowsingContextMediaEnabled(enable); -} - void WebRuntimeFeatures::EnableAllowSyncXHRInPageDismissal(bool enable) { RuntimeEnabledFeatures::SetAllowSyncXHRInPageDismissalEnabled(enable); }
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc index c7ff377..6cd9baa 100644 --- a/third_party/blink/renderer/platform/exported/web_url_request.cc +++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -235,14 +235,6 @@ resource_request_->SetReportUploadProgress(report_upload_progress); } -void WebURLRequest::SetReportRawHeaders(bool report_raw_headers) { - resource_request_->SetReportRawHeaders(report_raw_headers); -} - -bool WebURLRequest::ReportRawHeaders() const { - return resource_request_->ReportRawHeaders(); -} - mojom::blink::RequestContextType WebURLRequest::GetRequestContext() const { return resource_request_->GetRequestContext(); }
diff --git a/third_party/blink/renderer/platform/exported/web_url_response.cc b/third_party/blink/renderer/platform/exported/web_url_response.cc index 9b3b99f..d9910a3 100644 --- a/third_party/blink/renderer/platform/exported/web_url_response.cc +++ b/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -39,10 +39,8 @@ #include "services/network/public/mojom/ip_address_space.mojom-shared.h" #include "services/network/public/mojom/load_timing_info.mojom.h" #include "third_party/blink/public/platform/web_http_header_visitor.h" -#include "third_party/blink/public/platform/web_http_load_info.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_load_info.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -125,10 +123,6 @@ resource_response_->SetResourceLoadTiming(std::move(timing)); } -void WebURLResponse::SetHTTPLoadInfo(const WebHTTPLoadInfo& value) { - resource_response_->SetResourceLoadInfo(value); -} - base::Time WebURLResponse::ResponseTime() const { return resource_response_->ResponseTime(); }
diff --git a/third_party/blink/renderer/platform/loader/BUILD.gn b/third_party/blink/renderer/platform/loader/BUILD.gn index e8c87cf..dcae46c 100644 --- a/third_party/blink/renderer/platform/loader/BUILD.gn +++ b/third_party/blink/renderer/platform/loader/BUILD.gn
@@ -73,7 +73,6 @@ "fetch/resource_fetcher_properties.cc", "fetch/resource_fetcher_properties.h", "fetch/resource_finish_observer.h", - "fetch/resource_load_info.h", "fetch/resource_load_observer.h", "fetch/resource_load_priority.h", "fetch/resource_load_scheduler.cc",
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_load_info.h b/third_party/blink/renderer/platform/loader/fetch/resource_load_info.h deleted file mode 100644 index 2e50e2a..0000000 --- a/third_party/blink/renderer/platform/loader/fetch/resource_load_info.h +++ /dev/null
@@ -1,47 +0,0 @@ -/* - * Copyright (C) 2010 Google, 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. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_LOAD_INFO_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_LOAD_INFO_H_ - -#include "third_party/blink/renderer/platform/network/http_header_map.h" -#include "third_party/blink/renderer/platform/wtf/ref_counted.h" - -namespace blink { - -struct ResourceLoadInfo : RefCounted<ResourceLoadInfo> { - ResourceLoadInfo() : http_status_code(0) {} - - int http_status_code; - String http_status_text; - HTTPHeaderMap request_headers; - HTTPHeaderMap response_headers; - String request_headers_text; - String response_headers_text; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_LOAD_INFO_H_
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index 16e96fb8..db1aa6b 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -734,7 +734,7 @@ network::mojom::ReferrerPolicy new_referrer_policy, const WebString& new_method, const WebURLResponse& passed_redirect_response, - bool& report_raw_headers, + bool& has_devtools_request_id, std::vector<std::string>* removed_headers) { DCHECK(!passed_redirect_response.IsNull()); @@ -872,7 +872,7 @@ return false; } - report_raw_headers = new_request->ReportRawHeaders(); + has_devtools_request_id = new_request->GetDevToolsId().has_value(); return true; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.h b/third_party/blink/renderer/platform/loader/fetch/resource_loader.h index f38a55d..248ee73 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.h
@@ -133,7 +133,7 @@ network::mojom::ReferrerPolicy new_referrer_policy, const WebString& new_method, const WebURLResponse& passed_redirect_response, - bool& report_raw_headers, + bool& has_devtools_request_id, std::vector<std::string>* removed_headers) override; void DidSendData(uint64_t bytes_sent, uint64_t total_bytes_to_be_sent) override;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc index 02f375e7..3dc33eeb 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -88,7 +88,6 @@ http_method_(http_names::kGET), allow_stored_credentials_(true), report_upload_progress_(false), - report_raw_headers_(false), has_user_gesture_(false), has_text_fragment_token_(false), download_to_blob_(false),
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h index 3cecb9e..34e8eae 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -236,13 +236,6 @@ report_upload_progress_ = report_upload_progress; } - // Whether actual headers being sent/received should be collected and reported - // for the request. - bool ReportRawHeaders() const { return report_raw_headers_; } - void SetReportRawHeaders(bool report_raw_headers) { - report_raw_headers_ = report_raw_headers; - } - // True if request was user initiated. bool HasUserGesture() const { return has_user_gesture_; } void SetHasUserGesture(bool); @@ -561,7 +554,6 @@ HTTPHeaderMap http_header_fields_; bool allow_stored_credentials_ : 1; bool report_upload_progress_ : 1; - bool report_raw_headers_ : 1; bool has_user_gesture_ : 1; bool has_text_fragment_token_ : 1; bool download_to_blob_ : 1;
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_response.cc b/third_party/blink/renderer/platform/loader/fetch/resource_response.cc index 55f9103..286aaa18 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_response.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_response.cc
@@ -35,7 +35,6 @@ #include "services/network/public/cpp/cors/cors.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "third_party/blink/public/platform/web_url_response.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_load_info.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h" #include "third_party/blink/renderer/platform/network/http_names.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" @@ -484,15 +483,6 @@ resource_load_timing_ = std::move(resource_load_timing); } -scoped_refptr<ResourceLoadInfo> ResourceResponse::GetResourceLoadInfo() const { - return resource_load_info_.get(); -} - -void ResourceResponse::SetResourceLoadInfo( - scoped_refptr<ResourceLoadInfo> load_info) { - resource_load_info_ = std::move(load_info); -} - void ResourceResponse::SetCTPolicyCompliance(CTPolicyCompliance compliance) { ct_policy_compliance_ = compliance; }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_response.h b/third_party/blink/renderer/platform/loader/fetch/resource_response.h index e44c75e..dd75066 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_response.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_response.h
@@ -51,7 +51,6 @@ namespace blink { class ResourceLoadTiming; -struct ResourceLoadInfo; // A ResourceResponse is a "response" object used in blink. Conceptually // it is https://fetch.spec.whatwg.org/#concept-response, but it contains @@ -269,9 +268,6 @@ ResourceLoadTiming* GetResourceLoadTiming() const; void SetResourceLoadTiming(scoped_refptr<ResourceLoadTiming>); - scoped_refptr<ResourceLoadInfo> GetResourceLoadInfo() const; - void SetResourceLoadInfo(scoped_refptr<ResourceLoadInfo>); - HTTPVersion HttpVersion() const { return http_version_; } void SetHttpVersion(HTTPVersion version) { http_version_ = version; } @@ -663,7 +659,6 @@ absl::optional<SecurityDetails> security_details_; scoped_refptr<ResourceLoadTiming> resource_load_timing_; - scoped_refptr<ResourceLoadInfo> resource_load_info_; mutable CacheControlHeader cache_control_header_;
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc index 8584b3c..937e2c8 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.cc
@@ -365,7 +365,6 @@ dest->has_user_gesture = src.HasUserGesture(); dest->enable_load_timing = true; dest->enable_upload_progress = src.ReportUploadProgress(); - dest->report_raw_headers = src.ReportRawHeaders(); // TODO(ryansturm): Remove dest->previews_state once it is no // longer used in a network delegate. https://crbug.com/842233 dest->previews_state = static_cast<int>(src.GetPreviewsState());
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc index 0faebf4..8a2b2c6b 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/web_url_loader.cc
@@ -72,7 +72,6 @@ #include "third_party/blink/public/platform/url_conversion.h" #include "third_party/blink/public/platform/web_back_forward_cache_loader_helper.h" #include "third_party/blink/public/platform/web_blob_info.h" -#include "third_party/blink/public/platform/web_http_load_info.h" #include "third_party/blink/public/platform/web_request_peer.h" #include "third_party/blink/public/platform/web_resource_request_sender.h" #include "third_party/blink/public/platform/web_security_origin.h" @@ -387,13 +386,13 @@ WebURLLoader* loader_; KURL url_; - // Controls SetSecurityStyleAndDetails() in PopulateURLResponse(). Initially - // set to WebURLRequest::ReportRawHeaders() in Start() and gets updated in - // WillFollowRedirect() (by the InspectorNetworkAgent) while the new - // ReportRawHeaders() value won't be propagated to the browser process. + // This is set in Start() and is used by SetSecurityStyleAndDetails() to + // determine if security details should be added to the request for DevTools. // - // TODO(tyoshino): Investigate whether it's worth propagating the new value. - bool report_raw_headers_; + // Additionally, if there is a redirect, WillFollowRedirect() will update this + // for the new request. InspectorNetworkAgent will have the chance to attach a + // DevTools request id to that new request, and it will propagate here. + bool has_devtools_request_id_; WebURLLoaderClient* client_; std::unique_ptr<WebResourceLoadingTaskRunnerHandle> @@ -441,7 +440,7 @@ mojo::PendingRemote<mojom::KeepAliveHandle> keep_alive_handle, WebBackForwardCacheLoaderHelper back_forward_cache_loader_helper) : loader_(loader), - report_raw_headers_(false), + has_devtools_request_id_(false), client_(nullptr), freezable_task_runner_handle_(std::move(freezable_task_runner_handle)), unfreezable_task_runner_handle_( @@ -516,7 +515,7 @@ freezable_task_runner_handle_->DidChangeRequestPriority(request->priority); url_ = KURL(request->url); - report_raw_headers_ = request->report_raw_headers; + has_devtools_request_id_ = request->devtools_request_id.has_value(); // TODO(horo): Check credentials flag is unset when credentials mode is omit. // Check credentials flag is set when credentials mode is include. @@ -634,7 +633,8 @@ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); WebURLResponse response; - PopulateURLResponse(url_, *head, &response, report_raw_headers_, request_id_); + PopulateURLResponse(url_, *head, &response, has_devtools_request_id_, + request_id_); url_ = KURL(redirect_info.new_url); return client_->WillFollowRedirect( @@ -642,7 +642,7 @@ WebString::FromUTF8(redirect_info.new_referrer), ReferrerUtils::NetToMojoReferrerPolicy(redirect_info.new_referrer_policy), WebString::FromUTF8(redirect_info.new_method), response, - report_raw_headers_, removed_headers); + has_devtools_request_id_, removed_headers); } void WebURLLoader::Context::OnReceivedResponse( @@ -661,7 +661,8 @@ DCHECK(!head->headers || !head->headers->HasHeader("clear-site-data")); WebURLResponse response; - PopulateURLResponse(url_, *head, &response, report_raw_headers_, request_id_); + PopulateURLResponse(url_, *head, &response, has_devtools_request_id_, + request_id_); client_->DidReceiveResponse(response); @@ -859,29 +860,6 @@ response->SetLoadTiming(ToMojoLoadTiming(head.load_timing)); } - if (head.raw_request_response_info.get()) { - WebHTTPLoadInfo load_info; - - load_info.SetHTTPStatusCode( - head.raw_request_response_info->http_status_code); - load_info.SetHTTPStatusText(WebString::FromLatin1( - head.raw_request_response_info->http_status_text)); - - load_info.SetRequestHeadersText(WebString::FromLatin1( - head.raw_request_response_info->request_headers_text)); - load_info.SetResponseHeadersText(WebString::FromLatin1( - head.raw_request_response_info->response_headers_text)); - for (auto& header : head.raw_request_response_info->request_headers) { - load_info.AddRequestHeader(WebString::FromLatin1(header->key), - WebString::FromLatin1(header->value)); - } - for (auto& header : head.raw_request_response_info->response_headers) { - load_info.AddResponseHeader(WebString::FromLatin1(header->key), - WebString::FromLatin1(header->value)); - } - response->SetHTTPLoadInfo(load_info); - } - response->SetAuthChallengeInfo(head.auth_challenge_info); response->SetRequestIncludeCredentials(head.request_include_credentials); @@ -973,7 +951,7 @@ DCHECK(!context_->client()); context_->set_client(client); - const bool report_raw_headers = request->report_raw_headers; + const bool has_devtools_request_id = request->devtools_request_id.has_value(); context_->Start(std::move(request), std::move(url_request_extra_data), pass_response_pipe_to_client, no_mime_sniffing, timeout_interval, &sync_load_response, @@ -1007,7 +985,7 @@ } PopulateURLResponse(final_url, *sync_load_response.head, &response, - report_raw_headers, context_->request_id()); + has_devtools_request_id, context_->request_id()); encoded_data_length = sync_load_response.head->encoded_data_length; encoded_body_length = sync_load_response.head->encoded_body_length; if (sync_load_response.downloaded_blob) {
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc index 7a9edda..ad6359c 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/worker_main_script_loader.cc
@@ -19,7 +19,6 @@ #include "third_party/blink/renderer/platform/loader/fetch/fetch_context.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h" -#include "third_party/blink/renderer/platform/loader/fetch/resource_load_info.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_timing.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h"
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 844a8d6..c72615e 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1102,12 +1102,6 @@ status: "experimental", }, { - name: "GetCurrentBrowsingContextMedia", - origin_trial_feature_name: "GetCurrentBrowsingContextMedia", - depends_on: ["GetDisplayMedia"], - status: {"Android": "", "default": "experimental"}, - }, - { name: "GetDisplayMedia", status: { "Android": "experimental",
diff --git a/third_party/blink/renderer/platform/supplementable.h b/third_party/blink/renderer/platform/supplementable.h index 02c5ece..d699c99 100644 --- a/third_party/blink/renderer/platform/supplementable.h +++ b/third_party/blink/renderer/platform/supplementable.h
@@ -196,7 +196,8 @@ "Declare a const char array kSupplementName. See Supplementable.h for " "details."); return static_cast<SupplementType*>( - this->supplements_.at(SupplementType::kSupplementName)); + this->supplements_.DeprecatedAtOrEmptyValue( + SupplementType::kSupplementName)); } void ReattachThread() {
diff --git a/third_party/blink/renderer/platform/weborigin/scheme_registry.cc b/third_party/blink/renderer/platform/weborigin/scheme_registry.cc index b77d65e..b4d5cca1 100644 --- a/third_party/blink/renderer/platform/weborigin/scheme_registry.cc +++ b/third_party/blink/renderer/platform/weborigin/scheme_registry.cc
@@ -417,8 +417,9 @@ // get() returns 0 (PolicyAreaNone) if there is no entry in the map. // Thus by default, schemes do not bypass CSP. - return (GetURLSchemesRegistry().content_security_policy_bypassing_schemes.at( - scheme) & + return (GetURLSchemesRegistry() + .content_security_policy_bypassing_schemes + .DeprecatedAtOrEmptyValue(scheme) & policy_areas) == policy_areas; }
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc index 1e594b6..28268f3 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
@@ -225,12 +225,8 @@ cursor_control_handler_(std::make_unique<CursorControlHandler>()) { DCHECK(client); input_handler_->BindToClient(this); - cc::ScrollElasticityHelper* scroll_elasticity_helper = - input_handler_->CreateScrollElasticityHelper(); - if (scroll_elasticity_helper) { - elastic_overscroll_controller_ = - ElasticOverscrollController::Create(scroll_elasticity_helper); - } + + UpdateElasticOverscroll(); compositor_event_queue_ = std::make_unique<CompositorThreadEventQueue>(); scroll_predictor_ = base::FeatureList::IsEnabled(blink::features::kResamplingScrollEvents) @@ -533,6 +529,27 @@ DispatchSingleInputEvent(compositor_event_queue_->Pop(), now); } +void InputHandlerProxy::UpdateElasticOverscroll() { + bool can_use_elastic_overscroll = true; +#if defined(OS_ANDROID) + // On android, elastic overscroll introduces quite a bit of motion which can + // effect those sensitive to it. Disable when prefers_reduced_motion_ is + // disabled. + can_use_elastic_overscroll = !prefers_reduced_motion_; +#endif + if (!can_use_elastic_overscroll && elastic_overscroll_controller_) { + elastic_overscroll_controller_.reset(); + input_handler_->DestroyScrollElasticityHelper(); + } else if (can_use_elastic_overscroll && !elastic_overscroll_controller_) { + cc::ScrollElasticityHelper* scroll_elasticity_helper = + input_handler_->CreateScrollElasticityHelper(); + if (scroll_elasticity_helper) { + elastic_overscroll_controller_ = + ElasticOverscrollController::Create(scroll_elasticity_helper); + } + } +} + void InputHandlerProxy::InjectScrollbarGestureScroll( const WebInputEvent::Type type, const gfx::PointF& position_in_widget, @@ -1356,6 +1373,14 @@ elastic_overscroll_controller_->ReconcileStretchAndScroll(); } +void InputHandlerProxy::SetPrefersReducedMotion(bool prefers_reduced_motion) { + if (prefers_reduced_motion_ == prefers_reduced_motion) + return; + prefers_reduced_motion_ = prefers_reduced_motion; + + UpdateElasticOverscroll(); +} + void InputHandlerProxy::UpdateRootLayerStateForSynchronousInputHandler( const gfx::ScrollOffset& total_scroll_offset, const gfx::ScrollOffset& max_scroll_offset,
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc index 7845e70..603ee49 100644 --- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc +++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
@@ -135,6 +135,8 @@ cc::ScrollElasticityHelper* CreateScrollElasticityHelper() override { return nullptr; } + void DestroyScrollElasticityHelper() override {} + bool GetScrollOffsetForLayer(cc::ElementId element_id, gfx::ScrollOffset* offset) override { return false;
diff --git a/third_party/blink/renderer/platform/wtf/hash_map.h b/third_party/blink/renderer/platform/wtf/hash_map.h index b58e647..8c6f0bf 100644 --- a/third_party/blink/renderer/platform/wtf/hash_map.h +++ b/third_party/blink/renderer/platform/wtf/hash_map.h
@@ -157,6 +157,10 @@ const_iterator find(KeyPeekInType) const; bool Contains(KeyPeekInType) const; MappedPeekType at(KeyPeekInType) const; + // Deprecated variant of at(). Created for refactor described in + // https://crbug.com/1058527. Returns a reference to the mapped value or the + // empty value if no mapped value exists. + MappedPeekType DeprecatedAtOrEmptyValue(KeyPeekInType) const; // replaces value but not key if key is already present return value is a // pair of the iterator to the key location, and a boolean that's true if a @@ -586,6 +590,17 @@ typename Y> typename HashMap<T, U, V, W, X, Y>::MappedPeekType HashMap<T, U, V, W, X, Y>::at(KeyPeekInType key) const { + return DeprecatedAtOrEmptyValue(key); +} + +template <typename T, + typename U, + typename V, + typename W, + typename X, + typename Y> +typename HashMap<T, U, V, W, X, Y>::MappedPeekType +HashMap<T, U, V, W, X, Y>::DeprecatedAtOrEmptyValue(KeyPeekInType key) const { const ValueType* entry = impl_.Lookup(key); if (!entry) return MappedTraits::Peek(MappedTraits::EmptyValue());
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer.py b/third_party/blink/tools/blinkpy/w3c/test_importer.py index e0679e5..bf93eda 100644 --- a/third_party/blink/tools/blinkpy/w3c/test_importer.py +++ b/third_party/blink/tools/blinkpy/w3c/test_importer.py
@@ -40,7 +40,7 @@ # Sheriff calendar URL, used for getting the ecosystem infra sheriff to cc. ROTATIONS_URL = 'https://chrome-ops-rotation-proxy.appspot.com/current/grotation:chrome-ecosystem-infra' -SHERIFF_EMAIL_FALLBACK = 'smcgruer@google.com' +SHERIFF_EMAIL_FALLBACK = 'weizhong@google.com' RUBBER_STAMPER_BOT = 'rubber-stamper@appspot.gserviceaccount.com' _log = logging.getLogger(__file__) @@ -281,23 +281,33 @@ self.git_cl.run(['set-close']) return False - _log.info( - 'CQ appears to have passed; sending to the rubber-stamper bot for ' - 'CR+1 and commit.') - _log.info( - 'If the rubber-stamper bot rejects the CL, you either need to ' - 'modify the benign file patterns, or manually CR+1 and land the ' - 'import yourself if it touches code files. See https://chromium.' - 'googlesource.com/infra/infra/+/refs/heads/main/go/src/infra/' - 'appengine/rubber-stamper/README.md') - # `--send-mail` is required to take the CL out of WIP mode. - self.git_cl.run([ - 'upload', '-f', '--send-mail', '--enable-auto-submit', - '--reviewers', RUBBER_STAMPER_BOT - ]) + if self._need_sheriff_attention(): + _log.info( + 'CQ appears to have passed; sending to the sheriff for ' + 'CR+1 and commit. The sheriff has one hour to respond.') + self.git_cl.run([ + 'upload', '-f', '--send-mail', '--enable-auto-submit' + '--reviewers', self.sheriff_email() + ]) + timeout = 3600 + else: + _log.info( + 'CQ appears to have passed; sending to the rubber-stamper bot for ' + 'CR+1 and commit.') + _log.info( + 'If the rubber-stamper bot rejects the CL, you either need to ' + 'modify the benign file patterns, or manually CR+1 and land the ' + 'import yourself if it touches code files. See https://chromium.' + 'googlesource.com/infra/infra/+/refs/heads/main/go/src/infra/' + 'appengine/rubber-stamper/README.md') + self.git_cl.run([ + 'upload', '-f', '--send-mail', '--enable-auto-submit', + '--reviewers', RUBBER_STAMPER_BOT + ]) + timeout = 1800 - if self.git_cl.wait_for_closed_status(): + if self.git_cl.wait_for_closed_status(timeout_seconds=timeout): _log.info('Update completed.') return True @@ -463,6 +473,17 @@ self.finder.chromium_base()) return changed_files == [wpt_base_manifest] + def _need_sheriff_attention(self): + # Per the rules defined for the rubber-stamper, it can not auto approve + # a CL that has .bat, .sh or .py files. Request the sheriff on rotation + # to approve the CL. + changed_files = self.chromium_git.changed_files() + for cf in changed_files: + extension = self.fs.splitext(cf)[1] + if extension in ['.bat', '.sh', '.py']: + return True + return False + def _commit_message(self, chromium_commit_sha, import_commit_sha, @@ -538,9 +559,7 @@ '--bypass-hooks', '-f', '--message-file', - temp_path, - '--cc', - sheriff_email, + temp_path ]) self.fs.remove(temp_path)
diff --git a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py index 487d9d3..92f2e80e 100644 --- a/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py +++ b/third_party/blink/tools/blinkpy/w3c/test_importer_unittest.py
@@ -201,7 +201,8 @@ Build('cq-builder-a', 123): TryJobStatus( 'COMPLETED', 'SUCCESS'), }) - importer.git_cl.wait_for_closed_status = lambda: False + importer._need_sheriff_attention = lambda: False + importer.git_cl.wait_for_closed_status = lambda timeout_seconds: False success = importer.run_commit_queue_for_cl() self.assertFalse(success) self.assertLog([ @@ -289,7 +290,8 @@ Build('cq-builder-a', 123): TryJobStatus( 'COMPLETED', 'SUCCESS') }) - importer.git_cl.wait_for_closed_status = lambda: False + importer._need_sheriff_attention = lambda: False + importer.git_cl.wait_for_closed_status = lambda timeout_seconds: False success = importer.run_commit_queue_for_cl() # Since the CL is already merged, we absorb the error and treat it as success. self.assertTrue(success) @@ -542,6 +544,32 @@ RELATIVE_WEB_TESTS + 'external/' + BASE_MANIFEST_NAME] self.assertTrue(importer._only_wpt_manifest_changed()) + def test_need_sheriff_attention(self): + host = self.mock_host() + importer = self._get_test_importer(host) + importer.chromium_git.changed_files = lambda: [ + RELATIVE_WEB_TESTS + 'external/' + BASE_MANIFEST_NAME, + RELATIVE_WEB_TESTS + 'external/wpt/foo/x.html'] + self.assertFalse(importer._need_sheriff_attention()) + + importer.chromium_git.changed_files = lambda: [ + RELATIVE_WEB_TESTS + 'external/' + BASE_MANIFEST_NAME, + RELATIVE_WEB_TESTS + 'external/wpt/foo/x.html', + RELATIVE_WEB_TESTS + 'external/wpt/foo/y.sh'] + self.assertTrue(importer._need_sheriff_attention()) + + importer.chromium_git.changed_files = lambda: [ + RELATIVE_WEB_TESTS + 'external/' + BASE_MANIFEST_NAME, + RELATIVE_WEB_TESTS + 'external/wpt/foo/x.html', + RELATIVE_WEB_TESTS + 'external/wpt/foo/y.py'] + self.assertTrue(importer._need_sheriff_attention()) + + importer.chromium_git.changed_files = lambda: [ + RELATIVE_WEB_TESTS + 'external/' + BASE_MANIFEST_NAME, + RELATIVE_WEB_TESTS + 'external/wpt/foo/x.html', + RELATIVE_WEB_TESTS + 'external/wpt/foo/y.bat'] + self.assertTrue(importer._need_sheriff_attention()) + # TODO(crbug.com/800570): Fix orphan baseline finding in the presence of # variant tests. @unittest.skip('Finding orphaned baselines is broken')
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 2bd1b7f..b839ed5 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1069,6 +1069,7 @@ virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-063.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-065.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-066.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-071.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-073.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/overflow-clip-000.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-break/overflow-clip-001.html [ Pass ] @@ -1113,6 +1114,7 @@ virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-007.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-008.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-009.html [ Pass ] +virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-010.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-014.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-015.html [ Pass ] virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-span-all-017.html [ Pass ] @@ -1150,11 +1152,8 @@ virtual/layout_ng_block_frag/fast/multicol/vertical-rl/nested-columns.html [ Pass ] ### Tests failing with LayoutNGBlockFragmentation enabled: -crbug.com/1146973 virtual/layout_ng_block_frag/external/wpt/css/css-break/out-of-flow-in-multicolumn-009.html [ Failure ] -crbug.com/1206618 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/going-out-of-flow-after-spanner.html [ Failure ] crbug.com/1225630 virtual/layout_ng_block_frag/external/wpt/css/css-multicol/large-actual-column-count.html [ Skip ] crbug.com/1151880 virtual/layout_ng_block_frag/fast/multicol/dynamic/relpos-becomes-static-has-abspos.html [ Failure ] -crbug.com/1206618 virtual/layout_ng_block_frag/fast/multicol/dynamic/static-becomes-relpos-has-abspos.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-margin-at-row-boundary.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/float-margin-at-row-boundary-fixed-multicol-height.html [ Failure ] crbug.com/829028 virtual/layout_ng_block_frag/fast/multicol/forced-break-in-nested-columns.html [ Failure ] @@ -3824,6 +3823,7 @@ crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-063.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-065.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-066.html [ Failure ] +crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-071.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/out-of-flow-in-multicolumn-073.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/overflow-clip-000.html [ Failure ] crbug.com/829028 external/wpt/css/css-break/overflow-clip-001.html [ Failure ] @@ -4132,6 +4132,8 @@ crbug.com/1179585 virtual/layout_ng_svg_text/svg/custom/visibility-collapse.html [ Failure ] crbug.com/1179585 virtual/layout_ng_svg_text/svg/dynamic-updates/SVGTextElement-dom-lengthAdjust-attr.html [ Failure ] crbug.com/1179585 virtual/layout_ng_svg_text/svg/dynamic-updates/SVGTextElement-svgdom-lengthAdjust-prop.html [ Failure ] +crbug.com/1179585 virtual/layout_ng_svg_text/svg/filters/filter-on-filter-for-text.svg [ Failure ] +crbug.com/1179585 virtual/layout_ng_svg_text/svg/filters/filter-on-tspan.svg [ Failure ] crbug.com/1179585 virtual/layout_ng_svg_text/svg/stroke/non-scaling-stroke-text-decoration.html [ Failure ] crbug.com/1179585 virtual/layout_ng_svg_text/svg/stroke/non-scaling-stroke-text-decoration-dashed.html [ Failure ] crbug.com/1179585 virtual/layout_ng_svg_text/svg/text/bbox-with-glyph-overflow.html [ Failure ] @@ -7079,6 +7081,8 @@ crbug.com/1218431 [ Mac ] virtual/file-system-access-access-handle/external/wpt/file-system-access/sandboxed_FileSystemSyncAccessHandle-close.https.tentative.worker.html [ Failure Pass ] crbug.com/1218431 [ Mac ] virtual/file-system-access-access-handle/external/wpt/file-system-access/sandboxed_FileSystemSyncAccessHandle-truncate.https.tentative.worker.html [ Failure Pass ] +crbug.com/1017836 http/tests/devtools/network/warning-for-long-cookie.js [ Timeout ] + # Sheriff 2021-06-30 crbug.com/1216587 [ Win7 ] accessibility/scroll-window-sends-notification.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/WebGPUExpectations b/third_party/blink/web_tests/WebGPUExpectations index 604dabe..caa3d789 100644 --- a/third_party/blink/web_tests/WebGPUExpectations +++ b/third_party/blink/web_tests/WebGPUExpectations
@@ -134,6 +134,9 @@ # Crash when creating the bindgroup. Most likely because we are using an invalid VkImageView crbug.com/dawn/1043 [ Linux ] wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createBindGroup:texture,resource_state:* [ Crash Failure ] +# Flaky crash on shutdown +crbug.com/1236132 wpt_internal/webgpu/cts.html?q=webgpu:web_platform,canvas,readbackFromWebGPUCanvas:onscreenCanvas,uploadToWebGL:* [ RetryOnFailure Crash ] + # Failures because 1d, stencil8 and depth16unorm aren't implemented. crbug.com/dawn/129 wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createBindGroup:texture_must_have_correct_dimension:viewDimension="1d";* [ Failure ] crbug.com/dawn/129 wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createBindGroup:texture_must_have_correct_dimension:dimension="1d";* [ Failure ] @@ -201,6 +204,21 @@ wpt_internal/webgpu/cts.html?q=webgpu:api,validation,queue,copyToTexture,CopyExternalImageToTexture:destination_texture,dimension:dimension="1d";* [ Failure ] wpt_internal/webgpu/cts.html?q=webgpu:api,validation,queue,copyToTexture,CopyExternalImageToTexture:destination_texture,format:format="depth16unorm";* [ Failure ] wpt_internal/webgpu/cts.html?q=webgpu:api,validation,queue,copyToTexture,CopyExternalImageToTexture:destination_texture,format:format="stencil8";* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:array_layers:textureDimension="1d";* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:array_layers:viewDimension="1d";* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:aspect:format="depth16unorm";* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:aspect:format="stencil8";* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:dimension:textureDimension="1d";* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:format:textureFormat="depth16unorm";* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:format:textureFormat="stencil8";* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:format:viewFormat="depth16unorm";* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:format:viewFormat="stencil8";* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:mip_levels:textureDimension="1d";* [ Failure ] +wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:mip_levels:viewDimension="1d";* [ Failure ] + +# Dawn treats 0 and undefined as the same +crbug.com/dawn/1026 wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:mip_levels:mipLevelCount=0;* [ Failure ] +crbug.com/dawn/1026 wpt_internal/webgpu/cts.html?q=webgpu:api,validation,createView:array_layers:arrayLayerCount=0;* [ Failure ] crbug.com/1197369 wpt_internal/webgpu/cts.html?q=webgpu:api,validation,queue,copyToTexture,CopyExternalImageToTexture:source_image,crossOrigin:* [ Failure ] crbug.com/1197369 wpt_internal/webgpu/cts.html?q=webgpu:web_platform,copyToTexture,ImageBitmap:from_ImageData:alpha="premultiply";orientation="flipY";* [ Skip ] @@ -278,6 +296,13 @@ crbug.com/dawn/1011 [ Linux ] wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access_vertex:vertex_buffer_access:indexed=false;indirect=true;* [ Skip ] crbug.com/dawn/1011 [ Linux ] wpt_internal/webgpu/cts.html?q=webgpu:shader,execution,robust_access_vertex:vertex_buffer_access:indexed=true;indirect=false;* [ Skip ] +# Shared image synchronization +crbug.com/1236130 [ Linux ] wpt_internal/webgpu/cts.html?q=webgpu:web_platform,canvas,readbackFromWebGPUCanvas:drawTo2DCanvas:* [ Crash ] +crbug.com/1236130 [ Linux ] wpt_internal/webgpu/cts.html?q=webgpu:web_platform,canvas,readbackFromWebGPUCanvas:offscreenCanvas,snapshot:* [ Crash ] +crbug.com/1236130 [ Linux ] wpt_internal/webgpu/cts.html?q=webgpu:web_platform,canvas,readbackFromWebGPUCanvas:onscreenCanvas,snapshot:* [ Crash ] +# conflicts with previous expectation +# crbug.com/1236130 [ Linux ] wpt_internal/webgpu/cts.html?q=webgpu:web_platform,canvas,readbackFromWebGPUCanvas:onscreenCanvas,uploadToWebGL:* [ Crash ] + ### ### Windows (D3D12) specific ###
diff --git a/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations b/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations index a3449cab..285d818 100644 --- a/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations +++ b/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations
@@ -1173,7 +1173,6 @@ crbug.com/1050754 external/wpt/intersection-observer/iframe-no-root-with-wrapping-scroller.html [ Failure ] crbug.com/1050754 external/wpt/intersection-observer/iframe-no-root.html [ Failure ] crbug.com/1050754 external/wpt/intersection-observer/inline-client-rect.html [ Failure ] -crbug.com/1050754 external/wpt/intersection-observer/intersection-ratio-ib-split.html [ Failure ] crbug.com/1050754 external/wpt/intersection-observer/multiple-targets.html [ Failure ] crbug.com/1050754 external/wpt/intersection-observer/multiple-thresholds.html [ Failure ] crbug.com/1050754 external/wpt/intersection-observer/root-margin-root-element.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-015.html b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-015.html index 2bbcf8f..e2dec224 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-015.html +++ b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-015.html
@@ -24,8 +24,6 @@ <div id="multicol"> <div class="rel"> <div class="abs" style="top: 0px; height: 160px;"></div> - <div class="abs" style="top: 100px; height: 20px;"></div> </div> <div style="column-span:all; height: 20px; background: green;"></div> - <div style="height: 60px;"></div> </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-069.html b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-069.html new file mode 100644 index 0000000..7fdb32a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-069.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<title> + Out-of-flow positioned element affects column balancing. +</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<style> + .multicol { + column-count: 4; + column-gap: 0px; + width: 100px; + } + .abs { + position: absolute; + background-color: green; + height: 400px; + width: 25px; + } + #target { + background-color: red; + position: relative; + height: 100px; + width: 100px; + top: -100px; + z-index: -1; + } +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="multicol"> + <div style="position: relative;"> + <div class="abs"></div> + </div> +</div> +<div id="target"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-070.html b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-070.html new file mode 100644 index 0000000..1986ab81 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-070.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<title> + Out-of-flow positioned element with inline CB affects column balancing. +</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<style> + .multicol { + column-count: 4; + column-gap: 0px; + width: 100px; + } + .abs { + position: absolute; + background-color: green; + height: 400px; + width: 25px; + } + #target { + background-color: red; + position: relative; + height: 100px; + width: 100px; + top: -100px; + z-index: -1; + } +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="multicol"> + <div> + <span style="position: relative;"> + <div class="abs"></div> + </span> + </div> +</div> +<div id="target"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-071.html b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-071.html new file mode 100644 index 0000000..371f41a2 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-071.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<title> + Out-of-flow positioned element affects nested column balancing. +</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<style> + .multicol { + column-count: 2; + column-fill: auto; + column-gap: 0px; + } + #outer { + width: 100px; + } + #inner { + width: 50px; + } + .abs { + position: absolute; + background-color: green; + height: 400px; + width: 25px; + } + #target { + background-color: red; + position: relative; + height: 100px; + width: 100px; + top: -100px; + z-index: -1; + } +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="multicol" id="outer"> + <div class="multicol" id="inner"> + <div style="position: relative;"> + <div class="abs"></div> + </div> + </div> +</div> +<div id="target"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-072.html b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-072.html new file mode 100644 index 0000000..91f3da2c --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-break/out-of-flow-in-multicolumn-072.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<title> + Nested out-of-flow positioned element affects column balancing. +</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<style> + .multicol { + column-count: 4; + column-gap: 0px; + width: 100px; + } + .abs { + position: absolute; + background-color: green; + } + #target { + background-color: red; + position: relative; + height: 100px; + width: 100px; + top: -100px; + z-index: -1; + } +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="multicol"> + <div style="position: relative;"> + <div class="abs"> + <div class="abs" style="height: 400px; width: 25px;"></div> + </div> + </div> +</div> +<div id="target"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/image-nested-within-definite-column-flexbox.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/image-nested-within-definite-column-flexbox.html new file mode 100644 index 0000000..7bfeb4de --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/image-nested-within-definite-column-flexbox.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1233330"> +<link rel="match" href="../reference/ref-filled-green-100px-square-only.html"> +<p>Test passes if there is a filled green square.</p> +<div style="background: green; height: 100px; width: min-content; display:flex; flex-direction:column;"> + <div style="height:100%;"> + <img style="min-height: 100%;" src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='1px' height='1px'></svg>" /> + </div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/image-within-indefinite-row-flexbox.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/image-within-indefinite-row-flexbox.tentative.html deleted file mode 100644 index cb70568..0000000 --- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/image-within-indefinite-row-flexbox.tentative.html +++ /dev/null
@@ -1,9 +0,0 @@ -<!DOCTYPE html> -<link rel="help" href="https://github.com/web-platform-tests/wpt/issues/28805"> -<link rel="match" href="../reference/ref-filled-green-100px-square-only.html"> -<p>Test passes if there is a filled green square.</p> -<div style="display: flex; flex-direction: column; height: 100px; width: max-content; background: green;"> - <div style="display: flex; height: 50px; flex: 1; width: max-content; min-width: 0; min-height: 0;"> - <img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='100px' height='100px'></svg>" /> - </div> -</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/fixedpos-static-pos-with-viewport-cb-003.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/fixedpos-static-pos-with-viewport-cb-003.html new file mode 100644 index 0000000..fc29b5cb1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/fixedpos-static-pos-with-viewport-cb-003.html
@@ -0,0 +1,48 @@ +<!DOCTYPE html> +<title> + Nested fixedpos in a nested multicol with viewport containing block. +</title> +<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking"> +<link rel="match" href="../reference/ref-filled-green-100px-square.xht"> +<style> + .multicol { + column-count: 2; + column-fill: auto; + column-gap: 0px; + } + #outer { + height: 100px; + width: 100px; + margin-top: -100px; + margin-left: -50px; + } + #inner { + width: 50px; + height: 100px; + } + .rel { + position: relative; + } + .abs { + position: absolute; + width: 25px; + } + .fixed { + position: fixed; + width: 100px; + height: 100px; + } +</style> +<p>Test passes if there is a filled green square and <strong>no red</strong>.</p> +<div class="multicol" id="outer"> + <div class="multicol" id="inner"> + <div class="rel"> + <div style="height: 100px;"></div> + <div class="abs"> + <div style="height: 200px;"></div> + <div class="fixed" style="background: green;"></div> + </div> + </div> + </div> + <div class="fixed" style="background: red; z-index: -1; left: 8px;"></div> +</div>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-nested.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-nested.tentative.html new file mode 100644 index 0000000..70fcced --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-nested.tentative.html
@@ -0,0 +1,94 @@ +<!DOCTYPE html> +<html lang="en"> +<title>HTMLSelectMenuElement Test: nested selects</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-actions.js"></script> +<script src="/resources/testdriver-vendor.js"></script> + +<selectmenu id="selectMenu0"> + <popup slot="listbox" part="listbox"> + <selectmenu id="nested0"> + <option id="child1">one</option> + <option id="child2">two</option> + </selectmenu> + <option id="child3">three</option> + </popup> +</selectmenu> + +<selectmenu id="selectMenu1"> + <popup slot="listbox" part="listbox"> + <select> + <option>one</option> + <option>two</option> + </select> + <option>three</option> + </popup> +</selectmenu> + +<selectmenu id="selectMenu2"> + <div slot="button"> + <selectmenu id="nested2"> + <div slot="button" part="button" id="selectMenu2-button0">button0</div> + <option id="nested2-option1">one</option> + </selectmenu> + <div part="button" id="selectMenu2-button1">button1</div> + </div> + <option>two</option> +</selectmenu> + +<script> + function clickOn(element) { + const actions = new test_driver.Actions(); + return actions.pointerMove(0, 0, {origin: element}) + .pointerDown({button: actions.ButtonType.LEFT}) + .pointerUp({button: actions.ButtonType.LEFT}) + .send(); + } + + promise_test(async () => { + const selectMenu0 = document.getElementById("selectMenu0"); + const nested0 = document.getElementById("nested0"); + const child2 = document.getElementById("child2"); + assert_equals(selectMenu0.value, "three", "Options nested in another <selectmenu> should not get controller code from outer <selectmenu>"); + await clickOn(selectMenu0); + assert_true(selectMenu0.open); + assert_false(nested0.open); + + await clickOn(nested0); + assert_true(nested0.open); + + await clickOn(child2); + assert_false(nested0.open); + assert_equals(nested0.value, "two"); + assert_true(selectMenu0.open, "click on option in inner <selectmenu> should not close outer <selectmenu>"); + assert_equals(selectMenu0.value, "three", "click on option in inner <selectmenu> should not change value of outer <selectmenu>"); + }, "A <selectmenu> shouldn't apply controller code to parts nested in a <selectmenu> child"); + + promise_test(async () => { + const selectMenu1 = document.getElementById("selectMenu1"); + assert_equals(selectMenu0.value, "three"); + }, "A <selectmenu> shouldn't apply controller code to parts nested in a <select> child"); + + promise_test(async () => { + const selectMenu2 = document.getElementById("selectMenu2"); + const nested2 = document.getElementById("nested2"); + const button0 = document.getElementById("selectMenu2-button0"); + const button1 = document.getElementById("selectMenu2-button1"); + const nested2Option1 = document.getElementById("nested2-option1"); + assert_false(selectMenu2.open); + assert_false(nested2.open); + + await clickOn(button0); + assert_false(selectMenu2.open, "Clicking the button of a nested <selectmenu> should not open the outer <selectmenu>"); + assert_true(nested2.open, "Clicking the button of a nested <selectmenu> should open the outer <selectmenu>"); + + await clickOn(nested2Option1); + assert_false(nested2.open); + + await clickOn(button1); + assert_true(selectMenu2.open); + assert_false(nested2.open); + }, "A nested button part in a nested <selectmenu> shouldn't get controller code even if it comes first in document order"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-parts-structure.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-parts-structure.tentative.html index 448031eb..32c7a83 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-parts-structure.tentative.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-parts-structure.tentative.html
@@ -44,6 +44,23 @@ </div> </selectmenu> +<selectmenu id="selectMenu3"> + <div slot="button" id="selectMenu3-button-slot"> + <div part="button" id="selectMenu3-button0">button0</div> + </div> + <option>one</option> +</selectmenu> + +<selectmenu id="selectMenu4"> + <div slot="button" part="button" id="selectMenu4-button0">button0</div> + <div slot="listbox" id="selectMenu4-listbox-slot"> + <popup part="listbox" id="selectMenu4-listbox0"> + <option>one</option> + <option id="selectMenu4-option2">two</option> + </popup> + </div> +</selectmenu> + <script> function clickOn(element) { const actions = new test_driver.Actions(); @@ -109,4 +126,53 @@ await clickOn(selectMenu2Child4); assert_equals(selectMenu2.value, "four", "Clicking an <option> that is a descendant of a valid listbox part should update the value"); }, "To receive listbox part controller code, an element labeled as a listbox must not be a descendant of the button part in a flat tree traversal"); + + promise_test(async () => { + const selectMenu3 = document.getElementById("selectMenu3"); + const selectMenu3ButtonSlot = document.getElementById("selectMenu3-button-slot"); + const selectMenu3Button0 = document.getElementById("selectMenu3-button0"); + + assert_false(selectMenu3.open); + + let button1 = document.createElement("div"); + button1.innerText = "button1"; + button1.setAttribute("part", "button"); + selectMenu3ButtonSlot.appendChild(button1); + + await clickOn(button1); + assert_false(selectMenu3.open, "A button part should only get controller code if it's first in document order, even if added dynamically"); + + await clickOn(selectMenu3Button0); + assert_true(selectMenu3.open, "A button part should get controller code if it's first in document order"); + }, "Button controller code should be applied in flat tree traversal order regardless of dynamic insertion order"); + + promise_test(async () => { + const selectMenu4 = document.getElementById("selectMenu4"); + const selectMenu4Button0 = document.getElementById("selectMenu4-button0"); + const selectMenu4ListboxSlot = document.getElementById("selectMenu4-listbox-slot"); + const selectMenu4Option2 = document.getElementById("selectMenu4-option2"); + + assert_false(selectMenu4.open); + + let listbox2 = document.createElement("div"); + listbox2.innerHTML = ` + <option>three</option> + <option id="selectMenu4-option4">four</option> + `; + listbox2.setAttribute("part", "listbox"); + selectMenu4ListboxSlot.appendChild(listbox2); + + await clickOn(selectMenu4Button0); + assert_true(selectMenu4.open); + + const selectMenu4Option4 = document.getElementById("selectMenu4-option4"); + await clickOn(selectMenu4Option4); + assert_equals(selectMenu3.value, "one", "An option in a listbox should not get controller code if its listbox isn't first in document order, even if added dynamically"); + + await clickOn(selectMenu4Button0); + assert_true(selectMenu4.open); + + await clickOn(selectMenu4Option2); + assert_equals(selectMenu4.value, "two", "An option in a listbox should get controller code if its listbox is first in document order, even if another listbox was added dynamically"); +}, "Listbox controller code should be applied in flat tree traversal order regardless of dynamic insertion order"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-popup.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-popup.tentative-expected.txt index dcd2098..056f1af 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-popup.tentative-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-popup.tentative-expected.txt
@@ -2,5 +2,6 @@ PASS Opening the popup and clicking an option should change the selectmenu's value PASS With custom button and popup: opening the popup and clicking an option should change the selectmenu's value FAIL Clicking a popup with no listbox part does nothing assert_equals: expected false but got true +PASS Clicking a popup with a listbox that was removed does nothing Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-popup.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-popup.tentative.html index 7b085cd..156725d 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-popup.tentative.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-popup.tentative.html
@@ -29,6 +29,14 @@ <!-- Swap out the listbox part without providing a replacement --> <div slot="listbox"></div> </selectmenu> + +<selectmenu id="selectMenu3"> + <div slot="listbox"> + <popup part="listbox" id="selectMenu3-listbox"> + <option>one</option> + </popup> + </div> +</selectmenu> <script> function clickOn(element) { @@ -82,7 +90,19 @@ const selectMenu2 = document.getElementById("selectMenu2"); await clickOn(selectMenu2); assert_equals(selectMenu2.value, ""); + + // TODO(crbug.com/1234899) Fails because listbox pointer isn't cleared when default listbox is swapped out due to initial <slot> replacement assert_equals(selectMenu2.open, false); }, "Clicking a popup with no listbox part does nothing"); + + promise_test(async () => { + const selectMenu3 = document.getElementById("selectMenu3"); + const selectMenu3Listbox = document.getElementById("selectMenu3-listbox"); + selectMenu3Listbox.remove(); + + await clickOn(selectMenu3); + assert_equals(selectMenu3.value, ""); + assert_equals(selectMenu3.open, false); + }, "Clicking a popup with a listbox that was removed does nothing"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/intersection-observer/intersection-ratio-ib-split.html b/third_party/blink/web_tests/external/wpt/intersection-observer/intersection-ratio-ib-split.html index 1cba6da..ba5370e3 100644 --- a/third_party/blink/web_tests/external/wpt/intersection-observer/intersection-ratio-ib-split.html +++ b/third_party/blink/web_tests/external/wpt/intersection-observer/intersection-ratio-ib-split.html
@@ -18,6 +18,10 @@ <block></block> </inline> <script> + +// Account for rounding differences when viewport sizes can't cleanly divide. +const epsilon = 1; + promise_test(async function() { for (let element of document.querySelectorAll("inline, block")) { let entries = await new Promise(resolve => { @@ -28,10 +32,10 @@ assert_equals(entries[0].intersectionRatio, 1, element.nodeName + ": Should be fully intersecting"); function assert_rects_equal(r1, r2, label) { - assert_equals(r1.top, r2.top, label + ": top should be equal"); - assert_equals(r1.right, r2.right, label + ": right should be equal"); - assert_equals(r1.bottom, r2.bottom, label + ": bottom should be equal"); - assert_equals(r1.left, r2.left, label + ": left should be equal"); + assert_approx_equals(r1.top, r2.top, epsilon, label + ": top should be equal"); + assert_approx_equals(r1.right, r2.right, epsilon, label + ": right should be equal"); + assert_approx_equals(r1.bottom, r2.bottom, epsilon, label + ": bottom should be equal"); + assert_approx_equals(r1.left, r2.left, epsilon, label + ": left should be equal"); } assert_rects_equal(entries[0].boundingClientRect, element.getBoundingClientRect(), element.nodeName + ": boundingClientRect should match");
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-intercept-response-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-intercept-response-expected.txt new file mode 100644 index 0000000..c6d46dc --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-intercept-response-expected.txt
@@ -0,0 +1,5 @@ +Test interceptResponse=true parameter in request interceptor +Intercepted request +Intercepted response +Finished navigation +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-intercept-response.js b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-intercept-response.js new file mode 100644 index 0000000..c0bd55610 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-intercept-response.js
@@ -0,0 +1,30 @@ +(async function(testRunner) { + const {session, dp} = await testRunner.startBlank( + `Test interceptResponse=true parameter in request interceptor`); + + await dp.Runtime.enable(); + await dp.Network.enable(); + await dp.Fetch.enable({patterns: [{requestStage: 'Request'}, {requestStage: 'Response'}]}); + + function isResponse(params) { + return "responseErrorReason" in params || "responseStatusCode" in params; + } + + const navigatePromise = session.navigate(testRunner.url('./resources/hello-world.html')) + dp.Fetch.onRequestPaused(async event => { + const params = { + requestId: event.params.requestId, + }; + if (isResponse(event.params)) { + testRunner.log(`Intercepted response`); + } else { + testRunner.log(`Intercepted request`); + params.interceptResponse = true; + } + await dp.Fetch.continueRequest(params); + }); + + const result = await navigatePromise + testRunner.log('Finished navigation'); + testRunner.completeTest(); +})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-no-intercept-response-after-redirect-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-no-intercept-response-after-redirect-expected.txt new file mode 100644 index 0000000..bc91382 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-no-intercept-response-after-redirect-expected.txt
@@ -0,0 +1,9 @@ +Test interceptResponse parameter in redirected request interceptor +Intercepted request http://127.0.0.1:8000/inspector-protocol/resources/redirect1.php +Will skip next response +Intercepted request http://127.0.0.1:8000/inspector-protocol/resources/redirect2.php +Intercepted response 307 +Intercepted request http://127.0.0.1:8000/inspector-protocol/resources/final.html +Will skip next response +Finished navigation +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-no-intercept-response-after-redirect.js b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-no-intercept-response-after-redirect.js new file mode 100644 index 0000000..cb1481c --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-no-intercept-response-after-redirect.js
@@ -0,0 +1,34 @@ +(async function(testRunner) { + const {session, dp} = await testRunner.startBlank( + `Test interceptResponse parameter in redirected request interceptor`); + + await dp.Runtime.enable(); + await dp.Network.enable(); + await dp.Fetch.enable({patterns: [{requestStage: 'Request'}, {requestStage: 'Response'}]}); + + function isResponse(params) { + return "responseErrorReason" in params || "responseStatusCode" in params; + } + + const navigatePromise = session.navigate(testRunner.url('../resources/redirect1.php')) + let requestNumber = 0; + dp.Fetch.onRequestPaused(async event => { + const params = { + requestId: event.params.requestId, + }; + if (isResponse(event.params)) { + testRunner.log(`Intercepted response ${event.params.responseStatusCode}`); + } else { + testRunner.log(`Intercepted request ${event.params.request.url}`); + ++requestNumber; + params.interceptResponse = requestNumber === 2; + if (!params.interceptResponse) + testRunner.log(`Will skip next response`); + } + await dp.Fetch.continueRequest(params); + }); + + await navigatePromise + testRunner.log('Finished navigation'); + testRunner.completeTest(); +})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-skip-response-interception-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-skip-response-interception-expected.txt new file mode 100644 index 0000000..afd7d08 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-skip-response-interception-expected.txt
@@ -0,0 +1,4 @@ +Test interceptResponse=false parameter in request interceptor +Intercepted request +Finished navigation +
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-skip-response-interception.js b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-skip-response-interception.js new file mode 100644 index 0000000..2ad0f54 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/fetch/fetch-continue-skip-response-interception.js
@@ -0,0 +1,28 @@ +(async function(testRunner) { + const {session, dp} = await testRunner.startBlank( + `Test interceptResponse=false parameter in request interceptor`); + + await dp.Runtime.enable(); + await dp.Network.enable(); + await dp.Fetch.enable({patterns: [{requestStage: 'Request'}, {requestStage: 'Response'}]}); + + function isResponse(params) { + return "responseErrorReason" in params || "responseStatusCode" in params; + } + + const navigatePromise = session.navigate(testRunner.url('./resources/hello-world.html')) + dp.Fetch.onRequestPaused(async event => { + if (isResponse(event.params)) + testRunner.fail(`Unexpected Fetch.requestPaused event for response`); + else + testRunner.log(`Intercepted request`); + const {error} = await dp.Fetch.continueRequest({ + requestId: event.params.requestId, + interceptResponse: false + }); + }); + + const result = await navigatePromise + testRunner.log('Finished navigation'); + testRunner.completeTest(); +})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/disabled-cache-navigation-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/disabled-cache-navigation-expected.txt index b12c229..84a27a8 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/disabled-cache-navigation-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/disabled-cache-navigation-expected.txt
@@ -1,5 +1,16 @@ Tests that browser-initiated navigation honors Network.setCacheDisabled -Original navigation, should not be cached: 200 -Second navigation, should be cached: 304 cached: true -Navigation with cache disabled: 200 cached: false + +Original navigation, should not be cached: + responseReceived status: 200 + responseReceivedExtraInfo status: 200 + +Second navigation, should be cached: + responseReceived status: 200 + responseReceivedExtraInfo status: 304 + cached: true + +Navigation with cache disabled: + responseReceived status: 200 + responseReceivedExtraInfo status: 200 + cached: false
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/disabled-cache-navigation.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/disabled-cache-navigation.js index f08bc604..8a2823dd 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/disabled-cache-navigation.js +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/disabled-cache-navigation.js
@@ -1,29 +1,44 @@ (async function(testRunner) { var {page, session, dp} = await testRunner.startBlank( - `Tests that browser-initiated navigation honors Network.setCacheDisabled`); + `Tests that browser-initiated navigation honors Network.setCacheDisabled\n`); async function navigateAndGetResponse() { dp.Page.navigate({url: testRunner.url('resources/cached.php')}); - var response = (await dp.Network.onceResponseReceived()).params; + const [responseReceived, responseReceivedExtraInfo] = await Promise.all([ + dp.Network.onceResponseReceived(), + dp.Network.onceResponseReceivedExtraInfo()]); + var response = responseReceived.params; await dp.Network.onceLoadingFinished(); var content = (await dp.Network.getResponseBody({requestId: response.requestId})).result.body; if (typeof content != 'string' || !content.startsWith('<html>')) testRunner.fail(`Invalid response: ${content}`); - return {status: response.response.status, content: content}; + return { + status: response.response.status, + extraInfoStatus: responseReceivedExtraInfo.params.statusCode, + content: content + }; } await dp.Page.enable(); await dp.Network.enable(); let response = await navigateAndGetResponse(); - testRunner.log(`Original navigation, should not be cached: ${response.status}`); + testRunner.log(`Original navigation, should not be cached:`); + testRunner.log(` responseReceived status: ${response.status}`); + testRunner.log(` responseReceivedExtraInfo status: ${response.extraInfoStatus}\n`); await dp.Page.navigate({url: 'about:blank'}); let response2 = await navigateAndGetResponse(); - testRunner.log(`Second navigation, should be cached: ${response2.status} cached: ${response.content === response2.content}`); + testRunner.log(`Second navigation, should be cached:`); + testRunner.log(` responseReceived status: ${response2.status}`); + testRunner.log(` responseReceivedExtraInfo status: ${response2.extraInfoStatus}`); + testRunner.log(` cached: ${response.content === response2.content}\n`); await dp.Network.setCacheDisabled({cacheDisabled: true}); await dp.Page.navigate({url: 'about:blank'}); let response3 = await navigateAndGetResponse(); - testRunner.log(`Navigation with cache disabled: ${response3.status} cached: ${response3.content === response2.content}`); + testRunner.log(`Navigation with cache disabled:`); + testRunner.log(` responseReceived status: ${response3.status}`); + testRunner.log(` responseReceivedExtraInfo status: ${response3.extraInfoStatus}`); + testRunner.log(` cached: ${response3.content === response2.content}`); testRunner.completeTest(); })
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-headers-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-headers-expected.txt index ece6801..4170150 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-headers-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-headers-expected.txt
@@ -1,6 +1,12 @@ Tests that multiple HTTP headers with same name are correctly folded into one LF-separated line. -Pragma header of fetch of http://127.0.0.1:8000/inspector-protocol/network/resources/multiple-headers.php?fetch=1: value1 +Pragma header of fetch of http://127.0.0.1:8000/inspector-protocol/network/resources/multiple-headers.php?fetch=1: +Network.responseReceived: value1, value2 +Network.responseReceivedExtraInfo: value1 value2 -Pragma header of navigation to http://127.0.0.1:8000/inspector-protocol/network/resources/multiple-headers.php: value1 + +Pragma header of navigation to http://127.0.0.1:8000/inspector-protocol/network/resources/multiple-headers.php: +Network.responseReceived: value1 +value2 +Network.responseReceivedExtraInfo: value1 value2
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-headers.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-headers.js index 4c521342..dc60a82 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-headers.js +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/multiple-headers.js
@@ -8,8 +8,13 @@ await dp.Page.enable(); session.evaluate(`fetch("${url}?fetch=1").then(r => r.text())`); - const fetchResponse = (await dp.Network.onceResponseReceived()).params.response; - testRunner.log(`Pragma header of fetch of ${fetchResponse.url}: ${fetchResponse.headers['Access-Control-Pragma']}`); + const [fetchResponse, fetchResponseExtraInfo] = await Promise.all([ + dp.Network.onceResponseReceived(), + dp.Network.onceResponseReceivedExtraInfo()]); + testRunner.log(`Pragma header of fetch of ${fetchResponse.params.response.url}:`); + testRunner.log(`Network.responseReceived: ${fetchResponse.params.response.headers['Access-Control-Pragma']}`); + testRunner.log(`Network.responseReceivedExtraInfo: ${fetchResponseExtraInfo.params.headers['Access-Control-Pragma']}`); + testRunner.log(''); await dp.Network.onceLoadingFinished(); session.evaluate(` @@ -17,7 +22,11 @@ f.src = "${url}"; document.body.appendChild(f); `); - const navigationResponse = (await dp.Network.onceResponseReceived()).params.response; - testRunner.log(`Pragma header of navigation to ${navigationResponse.url}: ${navigationResponse.headers['Access-Control-Pragma']}`); + const [navigationResponse, navigationResponseExtraInfo] = await Promise.all([ + dp.Network.onceResponseReceived(), + dp.Network.onceResponseReceivedExtraInfo()]); + testRunner.log(`Pragma header of navigation to ${navigationResponse.params.response.url}:`); + testRunner.log(`Network.responseReceived: ${navigationResponse.params.response.headers['Access-Control-Pragma']}`); + testRunner.log(`Network.responseReceivedExtraInfo: ${navigationResponseExtraInfo.params.headers['Access-Control-Pragma']}`); testRunner.completeTest(); })
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/navigation-xfer-size.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/navigation-xfer-size.js index 8748851..5a36d83 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/navigation-xfer-size.js +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/navigation-xfer-size.js
@@ -9,15 +9,18 @@ iframe.src = '/inspector/network/resources/resource.php?gzip=1&size=8000'; document.body.appendChild(iframe); `); - const response = (await dp.Network.onceResponseReceived()).params.response; + let [response, responseExtraInfo] = await Promise.all([ + dp.Network.onceResponseReceived(), + dp.Network.onceResponseReceivedExtraInfo()]); + response = response.params.response; const encodedLength = (await dp.Network.onceLoadingFinished()).params.encodedDataLength; if (encodedLength > 2000) testRunner.log(`FAIL: encoded data length is suspiciously large (${encodedLength})`); - const headersLength = response.headersText.length; + const headersLength = responseExtraInfo.params.headersText.length; const contentLength = +response.headers['Content-Length']; if (headersLength + contentLength !== encodedLength) testRunner.log(`FAIL: headersLength (${headersLength}) + contentLength (${contentLength}) !== encodedLength (${encodedLength})`) testRunner.completeTest(); -}) \ No newline at end of file +})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation-expected.txt index 3c7cad8..6020433 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation-expected.txt
@@ -1,7 +1,9 @@ Tests that raw response headers are correctly reported after navigation. Fetching resource: -Response status: 200 +responseRecevied status: 200 +responseReceviedExtraInfo status: 200 Fetching same resource again: -Response status: 304 +responseRecevied status: 200 +responseReceviedExtraInfo status: 304
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation.js index c89c2c4..6fda805 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation.js +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-after-navigation.js
@@ -5,8 +5,11 @@ async function fetchAndLogResponseStatus() { session.evaluate(`fetch('http://devtools.test:8000/devtools/network/resources/resource.php?cached=1')`); - const response = (await dp.Network.onceResponseReceived()).params.response; - testRunner.log('Response status: ' + response.status); + const [responseReceived, responseReceivedExtraInfo] = await Promise.all([ + dp.Network.onceResponseReceived(), + dp.Network.onceResponseReceivedExtraInfo()]); + testRunner.log('responseRecevied status: ' + responseReceived.params.response.status); + testRunner.log('responseReceviedExtraInfo status: ' + responseReceivedExtraInfo.params.statusCode); } await dp.Page.enable(); @@ -20,4 +23,4 @@ await fetchAndLogResponseStatus(); testRunner.completeTest(); -}) \ No newline at end of file +})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-for-protected-document-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-for-protected-document-expected.txt index daf6459..0138125 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-for-protected-document-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-headers-for-protected-document-expected.txt
@@ -1,7 +1,7 @@ Tests that raw response headers are not reported in case of site isolation. <script src="http://127.0.0.1:8000/inspector-protocol/network/resources/cookie.pl"> -Set-Cookie: name=value +Set-Cookie: undefined <script src="http://devtools.oopif.test:8000/inspector-protocol/network/resources/cookie.pl"> Set-Cookie: undefined
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-response-headers-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-response-headers-expected.txt index fb71abb..fc14ca25 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-response-headers-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-response-headers-expected.txt
@@ -1,5 +1,8 @@ Tests that raw response headers are correctly reported in case of revalidation. -Response status: 304 Not Modified +Response status: 200 OK +ResponseExtraInfo status: 304 +ResponseExtraInfo status line: HTTP/1.1 304 Not Modified Response headers text present: true -Content-Length present: false +Content-Length present in blink headers: true +Content-Length present in ExtraInfo headers: false
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-response-headers.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-response-headers.js index 03aa16e..5083f61 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-response-headers.js +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/raw-response-headers.js
@@ -5,12 +5,17 @@ dp.Network.enable(); session.protocol.Page.reload(); - const response = (await dp.Network.onceResponseReceived()).params.response; + const [response, responseExtraInfo] = await Promise.all([ + dp.Network.onceResponseReceived(), + dp.Network.onceResponseReceivedExtraInfo()]); - const haveContentLength = Object.keys(response.headers).indexOf('Content-Length') >= 0; - testRunner.log(`Response status: ${response.status} ${response.statusText}`); - testRunner.log(`Response headers text present: ${!!response.headersText.length}`); - testRunner.log(`Content-Length present: ${haveContentLength}`); + testRunner.log(`Response status: ${response.params.response.status} ${response.params.response.statusText}`); + testRunner.log(`ResponseExtraInfo status: ${responseExtraInfo.params.statusCode}`); + const headersText = responseExtraInfo.params.headersText; + testRunner.log(`ResponseExtraInfo status line: ${headersText.substring(0, headersText.indexOf('\r'))}`); + testRunner.log(`Response headers text present: ${!!headersText}`); + testRunner.log(`Content-Length present in blink headers: ${Object.keys(response.params.response.headers).indexOf('Content-Length') >= 0}`); + testRunner.log(`Content-Length present in ExtraInfo headers: ${Object.keys(responseExtraInfo.params.headers).indexOf('Content-Length') >= 0}`); testRunner.completeTest(); -}) \ No newline at end of file +})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-interception-raw-headers-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-interception-raw-headers-expected.txt index cb338451..7de7fe039 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-interception-raw-headers-expected.txt +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-interception-raw-headers-expected.txt
@@ -4,7 +4,6 @@ Request interception enabled Page agent enabled Runtime agent enabled -Response.requestHeadersText present: true Connection raw header present: true Network.requestIntercepted ID 1 GET simple-iframe.html type: Document allowRequest ID 1
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-interception-raw-headers.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-interception-raw-headers.js index f5ab4e4..0d344084 100644 --- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-interception-raw-headers.js +++ b/third_party/blink/web_tests/http/tests/inspector-protocol/network/request-interception-raw-headers.js
@@ -16,13 +16,7 @@ document.body.appendChild(iframe); `); - await dp.Network.onResponseReceived(event => { - const response = event.params.response; - const haveRequestHeadersText = response.requestHeadersText; - const splitRawHeaders = response.requestHeadersText.split('\r\n'); - const connectionHeaderPresent = splitRawHeaders.filter(header => header.includes('Connection')); - - testRunner.log(`Response.requestHeadersText present: ${!!haveRequestHeadersText}`); - testRunner.log(`Connection raw header present: ${!!connectionHeaderPresent.length}`); + await dp.Network.onRequestWillBeSentExtraInfo(event => { + testRunner.log(`Connection raw header present: ${!!event.params.headers['Connection'].length}`); }); -}) \ No newline at end of file +})
diff --git a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/filters/filter-on-filter-for-text-expected.png b/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/filters/filter-on-filter-for-text-expected.png deleted file mode 100644 index 5246f64..0000000 --- a/third_party/blink/web_tests/platform/linux/virtual/layout_ng_svg_text/svg/filters/filter-on-filter-for-text-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/filters/filter-on-filter-for-text-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/filters/filter-on-filter-for-text-expected.png deleted file mode 100644 index b73270cb..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/filters/filter-on-filter-for-text-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/filters/filter-on-tspan-expected.png b/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/filters/filter-on-tspan-expected.png deleted file mode 100644 index 0d67598..0000000 --- a/third_party/blink/web_tests/platform/mac/virtual/layout_ng_svg_text/svg/filters/filter-on-tspan-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/filters/filter-on-filter-for-text-expected.png b/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/filters/filter-on-filter-for-text-expected.png deleted file mode 100644 index 7bb37b7..0000000 --- a/third_party/blink/web_tests/platform/win/virtual/layout_ng_svg_text/svg/filters/filter-on-filter-for-text-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-overflow-positioned-transform-001-expected.txt b/third_party/blink/web_tests/virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-overflow-positioned-transform-001-expected.txt index 8992ed79..57a731a 100644 --- a/third_party/blink/web_tests/virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-overflow-positioned-transform-001-expected.txt +++ b/third_party/blink/web_tests/virtual/layout_ng_block_frag/external/wpt/css/css-multicol/multicol-overflow-positioned-transform-001-expected.txt
@@ -1,6 +1,6 @@ This is a testharness.js-based test. PASS Check scrollWidth before and after transform chage -FAIL Check scrollHeight before and after transform chage assert_equals: expected 350 but got 100 -FAIL Check scrollWidth and scrollHeight before and after transform chage assert_equals: expected 250 but got 100 +PASS Check scrollHeight before and after transform chage +PASS Check scrollWidth and scrollHeight before and after transform chage Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/wpt_internal/webgpu/cts.html b/third_party/blink/web_tests/wpt_internal/webgpu/cts.html index 46bfd60..76ea0d99 100644 --- a/third_party/blink/web_tests/wpt_internal/webgpu/cts.html +++ b/third_party/blink/web_tests/wpt_internal/webgpu/cts.html
@@ -1351,13 +1351,12 @@ <meta name=variant content='?q=webgpu:api,validation,createTexture:texture_usage:dimension="1d";*'> <meta name=variant content='?q=webgpu:api,validation,createTexture:texture_usage:dimension="2d";*'> <meta name=variant content='?q=webgpu:api,validation,createTexture:texture_usage:dimension="3d";*'> -<meta name=variant content='?q=webgpu:api,validation,createView:creating_texture_view_on_a_2D_non_array_texture:*'> -<meta name=variant content='?q=webgpu:api,validation,createView:creating_texture_view_on_a_2D_array_texture:*'> -<meta name=variant content='?q=webgpu:api,validation,createView:Using_defaults_validates_the_same_as_setting_values_for_more_than_1_array_layer:*'> -<meta name=variant content='?q=webgpu:api,validation,createView:Using_defaults_validates_the_same_as_setting_values_for_only_1_array_layer:*'> -<meta name=variant content='?q=webgpu:api,validation,createView:creating_cube_map_texture_view:*'> -<meta name=variant content='?q=webgpu:api,validation,createView:creating_cube_map_texture_view_with_a_non_square_texture:*'> -<meta name=variant content='?q=webgpu:api,validation,createView:test_the_format_compatibility_rules_when_creating_a_texture_view:*'> +<meta name=variant content='?q=webgpu:api,validation,createView:format:*'> +<meta name=variant content='?q=webgpu:api,validation,createView:dimension:*'> +<meta name=variant content='?q=webgpu:api,validation,createView:aspect:*'> +<meta name=variant content='?q=webgpu:api,validation,createView:array_layers:*'> +<meta name=variant content='?q=webgpu:api,validation,createView:mip_levels:*'> +<meta name=variant content='?q=webgpu:api,validation,createView:cube_faces_square:*'> <meta name=variant content='?q=webgpu:api,validation,createView:texture_state:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,cmds,buffer_texture_copies:depth_stencil_format,copy_usage_and_aspect:*'> <meta name=variant content='?q=webgpu:api,validation,encoding,cmds,buffer_texture_copies:depth_stencil_format,copy_buffer_size:*'> @@ -1873,6 +1872,10 @@ <meta name=variant content='?q=webgpu:web_platform,canvas,context_creation:return_type:*'> <meta name=variant content='?q=webgpu:web_platform,canvas,getCurrentTexture:multiple_frames:*'> <meta name=variant content='?q=webgpu:web_platform,canvas,getSwapChainPreferredFormat:value:*'> +<meta name=variant content='?q=webgpu:web_platform,canvas,readbackFromWebGPUCanvas:onscreenCanvas,snapshot:*'> +<meta name=variant content='?q=webgpu:web_platform,canvas,readbackFromWebGPUCanvas:onscreenCanvas,uploadToWebGL:*'> +<meta name=variant content='?q=webgpu:web_platform,canvas,readbackFromWebGPUCanvas:offscreenCanvas,snapshot:*'> +<meta name=variant content='?q=webgpu:web_platform,canvas,readbackFromWebGPUCanvas:drawTo2DCanvas:*'> <meta name=variant content='?q=webgpu:web_platform,copyToTexture,ImageBitmap:from_ImageData:alpha="none";orientation="none";dstColorFormat="rgba8unorm";*'> <meta name=variant content='?q=webgpu:web_platform,copyToTexture,ImageBitmap:from_ImageData:alpha="none";orientation="none";dstColorFormat="rgba8unorm-srgb";*'> <meta name=variant content='?q=webgpu:web_platform,copyToTexture,ImageBitmap:from_ImageData:alpha="none";orientation="none";dstColorFormat="bgra8unorm";*'>
diff --git a/third_party/subresource-filter-ruleset/README.chromium b/third_party/subresource-filter-ruleset/README.chromium index d6859c5..9844e5f 100644 --- a/third_party/subresource-filter-ruleset/README.chromium +++ b/third_party/subresource-filter-ruleset/README.chromium
@@ -2,6 +2,7 @@ URL: https://easylist.to/easylist/easylist.txt Version: 202106071325 License: Creative Commons Attribution-ShareAlike 3.0 Unported +License Android Compatible: yes License File: LICENSE Security Critical: no
diff --git a/third_party/webgpu-cts/ts_sources.txt b/third_party/webgpu-cts/ts_sources.txt index cc86dbd..e6c3c46 100644 --- a/third_party/webgpu-cts/ts_sources.txt +++ b/third_party/webgpu-cts/ts_sources.txt
@@ -19,6 +19,7 @@ src/common/internal/params_utils.ts src/common/framework/fixture.ts src/common/framework/params_builder.ts +src/common/framework/resources.ts src/common/internal/test_group.ts src/common/framework/test_group.ts src/common/internal/test_suite_listing.ts @@ -207,10 +208,12 @@ src/webgpu/shader/validation/wgsl/basic.spec.ts src/webgpu/util/copy_to_texture.ts src/webgpu/util/texture/texel_data.spec.ts +src/webgpu/web_platform/util.ts src/webgpu/web_platform/canvas/configureSwapChain.spec.ts src/webgpu/web_platform/canvas/context_creation.spec.ts src/webgpu/web_platform/canvas/getCurrentTexture.spec.ts src/webgpu/web_platform/canvas/getSwapChainPreferredFormat.spec.ts +src/webgpu/web_platform/canvas/readbackFromWebGPUCanvas.spec.ts src/webgpu/web_platform/copyToTexture/ImageBitmap.spec.ts src/webgpu/web_platform/copyToTexture/canvas.spec.ts src/webgpu/web_platform/copyToTexture/video.spec.ts
diff --git a/tools/bisect_repackage/bisect_repackage.py b/tools/bisect_repackage/bisect_repackage.py index ac35986e..89dde70 100644 --- a/tools/bisect_repackage/bisect_repackage.py +++ b/tools/bisect_repackage/bisect_repackage.py
@@ -45,7 +45,7 @@ 'chrome_100_percent.pak', 'chrome_200_percent.pak', 'chromedriver', - 'crashpad_handler', + 'chrome_crashpad_handler', 'default_apps/', 'icudtl.dat', 'ClearKeyCdm/', @@ -97,7 +97,7 @@ CHROME_STRIP_LIST = { 'linux': [ 'chrome', - 'crashpad_handler', + 'chrome_crashpad_handler', 'nacl_helper' ] }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 3f8ae58..c8d842b 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -2516,6 +2516,13 @@ <int value="2" label="DIRECT"/> </enum> +<enum name="AndroidWebViewRenderProcessGoneResult"> + <int value="0" label="Java Exception thrown inside onRenderProcessGone()"/> + <int value="1" label="Renderer crash not handled"/> + <int value="2" label="Renderer kill (OOM or update) not handled"/> + <int value="3" label="Crash was handled for all WebViews"/> +</enum> + <enum name="AndroidWebViewSafeModeResult"> <int value="0" label="Success"/> <int value="1" label="Unknown error"/> @@ -14219,6 +14226,7 @@ <int value="19" label="Go to URL"/> <int value="20" label="Copy link to text"/> <int value="21" label="Search Image with Google Lens"/> + <int value="22" label="Search part of page with Google Lens"/> </enum> <enum name="ContextMenuOptionIOS"> @@ -25928,6 +25936,7 @@ <int value="882" label="WindowCaptureAllowedByOrigins"/> <int value="883" label="TabCaptureAllowedByOrigins"/> <int value="884" label="SameOriginTabCaptureAllowedByOrigins"/> + <int value="885" label="AssistantVoiceMatchEnabledDuringOobe"/> </enum> <enum name="EnterprisePolicyDeviceIdValidity"> @@ -33797,7 +33806,7 @@ <int value="3716" label="OBSOLETE_CSSPseudoHostCompoundList"/> <int value="3717" label="OBSOLETE_CSSPseudoHostContextCompoundList"/> <int value="3718" label="OBSOLETE_CSSPseudoHostDynamicSpecificity"/> - <int value="3719" label="GetCurrentBrowsingContextMedia"/> + <int value="3719" label="OBSOLETE_GetCurrentBrowsingContextMedia"/> <int value="3720" label="MouseEventRelativePositionForInlineElement"/> <int value="3721" label="V8SharedArrayBufferConstructedWithoutIsolation"/> <int value="3722" label="V8HTMLVideoElement_GetVideoPlaybackQuality_Method"/> @@ -64254,7 +64263,7 @@ <enum name="PciePeripheralConnectivityResult"> <!-- This must be kept current with PciePeripheralConnectivityResults - located in ash/components/pcie_peripheral/pcie_peripheral_manager.cc --> + located in ash/components/pcie_peripheral/pcie_peripheral_manager.h --> <int value="0" label="TBT-supported peripheral connected and allowed"/> <int value="1" label="TBT-only peripheral connected and blocked by Pciguard"/> @@ -64262,6 +64271,8 @@ label="TBT-only peripheral connected and blocked due to guest session"/> <int value="3" label="Alt-mode fallback due to Pciguard"/> <int value="4" label="Alt-mode fallback in guest session"/> + <int value="5" label="Peripheral blocked"/> + <int value="6" label="Billboard device"/> </enum> <enum name="PdfCompositionStatus"> @@ -70954,6 +70965,7 @@ <int value="112" label="IDC_CONTENT_CONTEXT_COPYLINKTOTEXT"/> <int value="113" label="IDC_CONTENT_CONTEXT_SEARCHLENSFORIMAGE"/> <int value="114" label="IDC_CONTENT_CONTEXT_REMOVELINKTOTEXT"/> + <int value="115" label="IDC_CONTENT_CONTEXT_LENS_REGION_SEARCH"/> </enum> <enum name="ReopenTabPromoStepAtDismissal">
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index 006d82b6..47dab0d 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -3678,6 +3678,19 @@ </summary> </histogram> +<histogram name="Android.WebView.OnRenderProcessGoneResult" + enum="AndroidWebViewRenderProcessGoneResult" expires_after="2022-08-03"> + <owner>ntfschr@chromium.org</owner> + <owner>src/android_webview/OWNERS</owner> + <summary> + This captures two pieces of information about renderer crashes: did the app + developer handle the renderer crash to recover, and if not, what type of + crash was this? This is recorded once each time the renderer process dies + unexpectedly, and is logged after we have notified the app via the + onRenderProcessGone() callback. + </summary> +</histogram> + <histogram name="Android.WebView.PageTimeSpent.{Scheme}" units="ms" expires_after="2022-07-01"> <owner>mvanouwerkerk@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml index aad4e57..24dd6825 100644 --- a/tools/metrics/histograms/metadata/blink/histograms.xml +++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -1765,9 +1765,9 @@ </histogram> <histogram name="Blink.JavaJsBridge.MethodInvocationError" - enum="JavaJsBridgeMethodInvocationError" expires_after="2021-09-11"> - <owner>timvolodine@chromium.org</owner> + enum="JavaJsBridgeMethodInvocationError" expires_after="2022-03-11"> <owner>torne@chromium.org</owner> + <owner>src/android_webview/OWNERS</owner> <summary>Records the Java/JS bridge method invocation errors.</summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml index bad61dc..b77325d 100644 --- a/tools/metrics/histograms/metadata/extensions/histograms.xml +++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -1987,7 +1987,7 @@ </histogram> <histogram name="Extensions.Functions.ExtensionServiceWorkerCalls" - enum="ExtensionFunctions" expires_after="2021-08-09"> + enum="ExtensionFunctions" expires_after="2022-08-09"> <owner>lazyboy@chromium.org</owner> <owner>dbertoni@chromium.org</owner> <owner>rdevlin.cronin@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml index 7007086..ac36a20 100644 --- a/tools/metrics/histograms/metadata/media/histograms.xml +++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -3968,6 +3968,9 @@ name="Media.Ui.GetCurrentBrowsingContextMedia.ExplicitSelection.UserInteraction" enum="GetCurrentBrowsingContextMediaExplicitSelectionUserInteraction" expires_after="2022-01-01"> + <obsolete> + Removed in July 2021. + </obsolete> <owner>eladalon@chromium.org</owner> <owner>guidou@chromium.org</owner> <owner>agpalak@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index 60eb976..cf4258d 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -3668,6 +3668,22 @@ <histogram name="Conversions.ExtraReportDelay" units="ms" expires_after="2021-12-19"> + <obsolete> + Replaced with Conversions.ExtraReportDelay2, which has a greater range. + </obsolete> + <owner>johnidel@chromium.org</owner> + <owner>csharrison@chromium.org</owner> + <summary> + Records the "extra" non-scheduled time it took to send a + particular conversion report. This is primarily due to a report's scheduled + report time taking place while the browser is closed. Recorded when a + conversion report is sent. + </summary> +</histogram> + +<histogram name="Conversions.ExtraReportDelay2" units="ms" + expires_after="2021-12-19"> + <owner>apaseltiner@chromium.org</owner> <owner>johnidel@chromium.org</owner> <owner>csharrison@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml index 986d3db..d2393ef 100644 --- a/tools/metrics/histograms/metadata/password/histograms.xml +++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -2882,7 +2882,7 @@ </histogram> <histogram name="PasswordProtection.VisualFeatureExtractionDuration" units="ms" - expires_after="2021-08-05"> + expires_after="2022-08-03"> <owner>drubery@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index 0511906..a038892 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -838,7 +838,7 @@ </histogram> <histogram name="SafeBrowsing.FileTypeUpdate.DynamicUpdateResult" - enum="SBFileTypeUpdateResult" expires_after="2021-12-19"> + enum="SBFileTypeUpdateResult" expires_after="2022-08-15"> <owner>drubery@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -852,7 +852,7 @@ </histogram> <histogram name="SafeBrowsing.FileTypeUpdate.DynamicUpdateVersion" - units="FileTypePolicies Version" expires_after="2021-08-09"> + units="FileTypePolicies Version" expires_after="2022-08-15"> <owner>drubery@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -866,7 +866,7 @@ </histogram> <histogram name="SafeBrowsing.FileTypeUpdate.ResourceBundleResult" - enum="SBFileTypeUpdateResult" expires_after="2021-08-15"> + enum="SBFileTypeUpdateResult" expires_after="2022-08-15"> <owner>drubery@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -879,7 +879,7 @@ </histogram> <histogram name="SafeBrowsing.FileTypeUpdate.ResourceBundleVersion" - units="FileTypePolicies Version" expires_after="2021-08-15"> + units="FileTypePolicies Version" expires_after="2022-08-15"> <owner>drubery@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/sb_client/histograms.xml b/tools/metrics/histograms/metadata/sb_client/histograms.xml index 598905e..f1f4615f 100644 --- a/tools/metrics/histograms/metadata/sb_client/histograms.xml +++ b/tools/metrics/histograms/metadata/sb_client/histograms.xml
@@ -525,7 +525,7 @@ </histogram> <histogram name="SBClientPhishing.DOMFeatureTimeout" units="units" - expires_after="M94"> + expires_after="2022-08-03"> <owner>drubery@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -717,7 +717,7 @@ </histogram> <histogram name="SBClientPhishing.RequestSatisfiedFromCache" enum="BooleanHit" - expires_after="M94"> + expires_after="2022-08-03"> <owner>drubery@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -805,7 +805,7 @@ </histogram> <histogram name="SBClientPhishing.TermFeatureTotalTime" units="ms" - expires_after="2021-08-22"> + expires_after="2022-08-03"> <owner>drubery@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary> @@ -829,7 +829,7 @@ </histogram> <histogram name="SBClientPhishing.URLFeatureTime" units="ms" - expires_after="M94"> + expires_after="2022-08-03"> <owner>drubery@chromium.org</owner> <owner>chrome-safebrowsing-alerts@google.com</owner> <summary>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index 4e2244f..4e6d5ca 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -14460,6 +14460,20 @@ </metric> </event> +<event name="RenderViewContextMenu.Used"> + <owner>juanmojica@google.com</owner> + <owner>benwgold@google.com</owner> + <summary> + Metric recorded when a context menu item is selected. This is currently only + recorded for Lens context menu items. + </summary> + <metric name="SelectedMenuItem" enum="RenderViewContextMenuItem"> + <summary> + The menu item selected by the user on the context menu. + </summary> + </metric> +</event> + <event name="Responsiveness.UserInteraction"> <owner>hbsong@chromium.org</owner> <summary>
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index 592d70c..a62cb4a 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -5,8 +5,8 @@ UNSCHEDULED_blink_perf.performance_apis,yoavweiss@chromium.org,Blink>PerformanceAPIs,https://bit.ly/blink-perf-benchmarks,all UNSCHEDULED_blink_perf.service_worker,"shimazu@chromium.org, falken@chromium.org, ting.shao@intel.com",Blink>ServiceWorker,https://bit.ly/blink-perf-benchmarks, UNSCHEDULED_loading.mbi,blink-isolation-dev@chromium.org,Blink>Internals>Modularization,https://bit.ly/loading-benchmarks,many_agents -UNSCHEDULED_v8.loading_desktop,"mythria@chromium.org, tmrts@chromium.org, almuthanna@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2016,2018,2019,2020,emerging_market,health_check,international,javascript_heavy" -UNSCHEDULED_v8.loading_mobile,"mythria@chromium.org, tmrts@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2016,2018,2019,2020,emerging_market,health_check,international,javascript_heavy" +UNSCHEDULED_v8.loading_desktop,"cbruni@chromium.org, tmrts@chromium.org, almuthanna@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2016,2018,2019,2020,emerging_market,health_check,international,javascript_heavy" +UNSCHEDULED_v8.loading_mobile,"cbruni@chromium.org, leszeks@chromium.org, tmrts@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2016,2018,2019,2020,emerging_market,health_check,international,javascript_heavy" base_perftests,"skyostil@chromium.org, gab@chromium.org",Internals>SequenceManager,https://chromium.googlesource.com/chromium/src/+/HEAD/base/README.md#performance-testing, blink_perf.accessibility,dmazzoni@chromium.org,Blink>Accessibility,https://bit.ly/blink-perf-benchmarks,all blink_perf.bindings,"jbroman@chromium.org, yukishiino@chromium.org, haraken@chromium.org",Blink>Bindings,https://bit.ly/blink-perf-benchmarks,all @@ -77,11 +77,11 @@ tab_switching.typical_25,vovoy@chromium.org,OS>Performance,,"2016,tabs_switching" tracing.tracing_with_background_memory_infra,ssid@chromium.org,,, tracing_perftests,"eseckler@chromium.org, oysteine@chromium.org",Speed>Tracing,, -v8.browsing_desktop,"mythria@chromium.org, tmrts@chromium.org, almuthanna@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2016,2018,2019,2020,2021,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,wasm,webgl" -v8.browsing_desktop-future,"mythria@chromium.org, tmrts@chromium.org, almuthanna@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2016,2018,2019,2020,2021,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,wasm,webgl" -v8.browsing_mobile,"mythria@chromium.org, tmrts@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2018,2019,2021,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy" -v8.browsing_mobile-future,"mythria@chromium.org, tmrts@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2018,2019,2021,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy" -v8.runtime_stats.top_25,"mythria@chromium.org, ulan@chromium.org",Blink>JavaScript,,"cold,hot,warm" +v8.browsing_desktop,"cbruni@chromium.org, tmrts@chromium.org, almuthanna@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2016,2018,2019,2020,2021,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,wasm,webgl" +v8.browsing_desktop-future,"cbruni@chromium.org, tmrts@chromium.org, almuthanna@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2016,2018,2019,2020,2021,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,wasm,webgl" +v8.browsing_mobile,"cbruni@chromium.org, leszeks@chromium.org, tmrts@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2018,2019,2021,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy" +v8.browsing_mobile-future,"cbruni@chromium.org, leszeks@chromium.org, tmrts@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2018,2019,2021,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy" +v8.runtime_stats.top_25,"cbruni@chromium.org, leszeks@chromium.org",Blink>JavaScript,,"cold,hot,warm" views_perftests,tapted@chromium.org,Internals>Views,, wasmpspdfkit,ahaas@chromium.org,Blink>JavaScript>WebAssembly,, webrtc,"qiangchen@chromium.org, mbonadei@chromium.org",Blink>WebRTC,http://bit.ly/webrtc-benchmark,"datachannel,getusermedia,insertableStreams,pauseplay,sdp,smoothness,stress,videoConstraints"
diff --git a/tools/perf/benchmarks/v8.py b/tools/perf/benchmarks/v8.py index 637e4f3..1b1caee9 100644 --- a/tools/perf/benchmarks/v8.py +++ b/tools/perf/benchmarks/v8.py
@@ -12,7 +12,7 @@ from telemetry.web_perf import timeline_based_measurement -@benchmark.Info(emails=['mythria@chromium.org','ulan@chromium.org'], +@benchmark.Info(emails=['cbruni@chromium.org', 'leszeks@chromium.org'], component='Blink>JavaScript') class V8Top25RuntimeStats(perf_benchmark.PerfBenchmark): """Runtime Stats benchmark for a 25 top V8 web pages.
diff --git a/tools/perf/benchmarks/v8_browsing.py b/tools/perf/benchmarks/v8_browsing.py index 5c6a1d80..b4f0eba 100644 --- a/tools/perf/benchmarks/v8_browsing.py +++ b/tools/perf/benchmarks/v8_browsing.py
@@ -21,7 +21,7 @@ @benchmark.Info(emails=[ - 'mythria@chromium.org', 'tmrts@chromium.org', 'almuthanna@chromium.org' + 'cbruni@chromium.org', 'tmrts@chromium.org', 'almuthanna@chromium.org' ], component='Blink>JavaScript', documentation_url='https://bit.ly/system-health-v8-benchmarks') @@ -39,7 +39,9 @@ return 'v8.browsing_desktop' -@benchmark.Info(emails=['mythria@chromium.org', 'tmrts@chromium.org'], +@benchmark.Info(emails=[ + 'cbruni@chromium.org', 'leszeks@chromium.org', 'tmrts@chromium.org' +], component='Blink>JavaScript', documentation_url='https://bit.ly/system-health-v8-benchmarks') class V8MobileBrowsingBenchmark( @@ -58,7 +60,7 @@ @benchmark.Info(emails=[ - 'mythria@chromium.org', 'tmrts@chromium.org', 'almuthanna@chromium.org' + 'cbruni@chromium.org', 'tmrts@chromium.org', 'almuthanna@chromium.org' ], component='Blink>JavaScript', documentation_url='https://bit.ly/system-health-v8-benchmarks') @@ -81,7 +83,9 @@ return 'v8.browsing_desktop-future' -@benchmark.Info(emails=['mythria@chromium.org', 'tmrts@chromium.org'], +@benchmark.Info(emails=[ + 'cbruni@chromium.org', 'leszeks@chromium.org', 'tmrts@chromium.org' +], component='Blink>JavaScript', documentation_url='https://bit.ly/system-health-v8-benchmarks') class V8FutureMobileBrowsingBenchmark(_V8BrowsingBenchmark):
diff --git a/tools/perf/benchmarks/v8_loading.py b/tools/perf/benchmarks/v8_loading.py index 864aef9e..f8b18be 100644 --- a/tools/perf/benchmarks/v8_loading.py +++ b/tools/perf/benchmarks/v8_loading.py
@@ -20,7 +20,7 @@ @benchmark.Info(emails=[ - 'mythria@chromium.org', 'tmrts@chromium.org', 'almuthanna@chromium.org' + 'cbruni@chromium.org', 'tmrts@chromium.org', 'almuthanna@chromium.org' ], component='Blink>JavaScript', documentation_url='https://bit.ly/system-health-v8-benchmarks') @@ -41,7 +41,9 @@ return 'UNSCHEDULED_v8.loading_desktop' -@benchmark.Info(emails=['mythria@chromium.org', 'tmrts@chromium.org'], +@benchmark.Info(emails=[ + 'cbruni@chromium.org', 'leszeks@chromium.org', 'tmrts@chromium.org' +], component='Blink>JavaScript', documentation_url='https://bit.ly/system-health-v8-benchmarks') class V8MobileLoadingBenchmark(_V8LoadingBenchmark):
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index e864501..763fff0 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": "3e1287fc3d95f3f9aa1c82fae2c45b16af78d8dd", - "remote_path": "perfetto_binaries/trace_processor_shell/win/f94e497acc562fab07b1cbe20e973c8e150900ec/trace_processor_shell.exe" + "hash": "f0284bbb5f297b609fef13bf60ef912d879c8831", + "remote_path": "perfetto_binaries/trace_processor_shell/win/b846a827ab0b47d0299bc3776d1fb5c067c50d94/trace_processor_shell.exe" }, "mac": { "hash": "e7000eeeefed60f263b77eea1156606a18304379", - "remote_path": "perfetto_binaries/trace_processor_shell/mac/d3e40bdbdc699f7c0812d9d152e0ccddb13891ad/trace_processor_shell" + "remote_path": "perfetto_binaries/trace_processor_shell/mac/a6966e3445f5dc2a0d9f735b8c689c5078e4c33e/trace_processor_shell" }, "linux_arm64": { "hash": "5074025a2898ec41a872e70a5719e417acb0a380", "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell" }, "linux": { - "hash": "672ed966e2e8072a7d6322367ac35c5fedd1ff9f", - "remote_path": "perfetto_binaries/trace_processor_shell/linux/6c633ff46becc2341908e7843360e0790fac81fe/trace_processor_shell" + "hash": "2eecc03d143f80c0e3d9084175dca1cf81fd6de6", + "remote_path": "perfetto_binaries/trace_processor_shell/linux/b846a827ab0b47d0299bc3776d1fb5c067c50d94/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/tracing/flag_utils.py b/tools/tracing/flag_utils.py index 50b06f5..1f0cf08a 100644 --- a/tools/tracing/flag_utils.py +++ b/tools/tracing/flag_utils.py
@@ -12,87 +12,215 @@ import webbrowser import subprocess +sys.path.insert( + 0, + os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'third_party', + 'catapult', 'systrace')) +from systrace import util + +_DEFAULT_CHROME_CATEGORIES = '_DEFAULT_CHROME_CATEGORIES' + + +def GeneralOptions(parser): + """Build option group for general options. + + Args: + parser: OptionParser object for parsing the command-line. + + Returns: + Option group that contains general options. + """ + general_options = optparse.OptionGroup(parser, 'General Options') + + general_options.add_option('-o', + '--output', + help=('Save trace output to file. ' + 'Defaults to trace_file + ' + '"_symbolized_trace."'), + dest='output_file') + general_options.add_option('-v', + '--verbose', + help='Increase output verbosity.', + action='count', + dest='verbosity') + general_options.add_option('--view', + help='Open resulting trace file in a ' + 'browser.', + action='store_true') + + return general_options + + +def ProfileOptions(parser): + """Build option group for profiling chrome. + + Args: + parser: OptionParser object for parsing the command-line. + + Returns: + Option group that contains profiling chrome options. + """ + profile_options = optparse.OptionGroup(parser, 'Profile Chrome Options') + browsers = sorted(util.get_supported_browsers().keys()) + + profile_options.add_option('-b', + '--browser', + help='Select among installed browsers. ' + 'One of ' + ', '.join(browsers) + + '. "stable" is used by ' + 'default.', + type='choice', + choices=browsers, + default='stable') + profile_options.add_option('-t', + '--time', + help=('Stops tracing after N seconds. ' + 'Default is 5 seconds'), + default=5, + metavar='N', + type='int', + dest='trace_time') + profile_options.add_option('-e', + '--serial', + help='adb device serial number.', + type='string', + default=util.get_default_serial(), + dest='device_serial_number') + profile_options.add_option('-f', + '--trace_format', + help='Format of saved trace: proto, json, html.' + ' Default is proto.', + default='proto', + dest='trace_format') + profile_options.add_option('-p', + '--platform', + help='Device platform. Only Android is supported.', + default='android', + dest='platform') + profile_options.add_option('--buf-size', + help='Use a trace buffer size ' + ' of N KB.', + type='int', + metavar='N', + dest='trace_buf_size') + profile_options.add_option( + '--enable_profiler', + help='Comma-separated string of ' + 'profiling options to use. Supports options for memory or ' + 'cpu or both. Ex: --enable_profiler=memory ' + 'or --enable_profiler=memory,cpu. ', + dest='enable_profiler') + profile_options.add_option('--chrome_categories', + help='Chrome tracing ' + 'categories to record.', + type='string', + default=_DEFAULT_CHROME_CATEGORIES) + profile_options.add_option( + '-s', + '--symbolize', + help='Symbolizes recorded trace profile, if specified.', + action='store_true', + dest='symbolize') + profile_options.add_option('--compress', + help='Compress the resulting trace ' + 'with gzip. ', + action='store_true') + + # This is kept for backwards compatibility. Help is suppressed because this + # should be specified through the newer |trace_format| flag. + profile_options.add_option('--json', + help=optparse.SUPPRESS_HELP, + dest='write_json') + + return profile_options + def SymbolizeOptions(parser): """Build option group for proto trace symbolization. Args: - parser: OptionParser object for parsing the command line. + parser: OptionParser object for parsing the command-line. Returns: Option group that contains symbolization options. """ symbolization_options = optparse.OptionGroup(parser, 'Symbolization Options') + symbolization_options.add_option( - '--trace_processor_path', + '--breakpad_output_dir', + help='Optional path to empty directory to store fetched trace symbols ' + 'and extracted breakpad symbol files for official builds. Useful ' + 'for symbolizing multiple traces from the same Chrome build. Use ' + '--local_breakpad_dir when you already have breakpad files fetched. ' + 'Automatically uses temporary directory if flag not specified.', + dest='breakpad_output_dir') + symbolization_options.add_option( + '--local_breakpad_dir', + help='Optional path to local directory containing breakpad symbol files ' + 'used to symbolize the given trace. Breakpad files should be named ' + 'with module id in upper case hexadecimal and ".breakpad" ' + 'suffix. Ex: 12EFA32BE.breakpad', + dest='local_breakpad_dir') + symbolization_options.add_option( + '--local_build_dir', + help='Optional path to a local build directory containing symbol files.', + dest='local_build_dir') + symbolization_options.add_option( + '--dump_syms', + help=('Path to dump_syms binary. Searches the given build ' + 'directory for the binary, if not provided.'), + dest='dump_syms_path') + symbolization_options.add_option( + '--symbolizer', + help=('Path to the trace_to_text binary for symbolization. Defaults to ' + '"third_party/perfetto/tools/traceconv". traceconv is the same as ' + 'trace_to_text, except that tracevonv finds a prebuilt ' + 'trace_to_text binary to use.'), + default='third_party/perfetto/tools/traceconv', + dest='symbolizer_path') + symbolization_options.add_option( + '--trace_processor', help=('Optional path to trace processor binary. ' 'Automatically downloads binary if flag not specified.'), dest='trace_processor_path') symbolization_options.add_option( - '--local_build_dir', - help=('Path to a local build directory where symbols can be found. ' - 'Ignored if not provided.'), - dest='local_build_dir') - symbolization_options.add_option( - '--dump_syms_path', - help=('Optional path to dump_syms binary. Searches the given build ' - 'directory for the binary, if not provided.'), - dest='dump_syms_path') - symbolization_options.add_option( - '--breakpad_output_dir', - help=('Optional path to empty directory to store fetched trace symbols ' - 'for official builds. This can be used if you need to symbolize ' - 'traces from the same application multiple times. ' - 'Automatically uses temporary directory if flag not specified.'), - dest='breakpad_output_dir') - symbolization_options.add_option( - '--local_breakpad_dir', - help=('Optional path to local directory with breakpad symbol files. ' - 'These files will be used to symbolize a given trace file. Files ' - 'should be named with the build id of the chrome build in upper ' - 'case hexadecimal and a ".breakpad" suffix. ' - 'Ex: <module_id>.breakpad. Assumes that no local directory exists ' - 'if the flag is not specified.'), - dest='local_breakpad_dir') - symbolization_options.add_option( - '--output_file', - help=('Optional path to the file to write symbolized trace to. ' - 'Defaults to trace_file + "symbolized_trace."'), - dest='output_file') - symbolization_options.add_option( '--cloud_storage_bucket', - help=('Optional bucket in cloud storage where symbols reside. ' + help=('Optional cloud storage bucket to where symbol files reside. ' 'Defaults to "chrome-unsigned".'), - dest='cloud_storage_bucket', - default='chrome-unsigned') - symbolization_options.add_option( - '--symbolizer_path', - help=('Optional path to the trace_to_text binary to be called for ' - 'symbolization. Defaults to ' - '"third_party/perfetto/tools/traceconv". traceconv is the same as ' - 'trace_to_text, except that tracevonv finds a prebuilt ' - 'trace_to_text binary to use.'), - dest='symbolizer_path', - default='third_party/perfetto/tools/traceconv') + default='chrome-unsigned', + dest='cloud_storage_bucket') return symbolization_options -def AddLoggingOptions(parser): - """Add options for logging to |parser|. +def SetupProfilingCategories(options): + """Sets --chrome_categories flag. + + Uses the --enable_profile flag to modify the --chrome_categories flag for + specific profiling options. Args: - parser: OptionParser object for parsing the command line. - - Returns: - Input |parser| with added logging options. + The command-line options given. """ - parser.add_option('-v', - '--verbose', - help='Increase output verbosity.', - action='count', - dest='verbosity') - return parser + if options.enable_profiler is None: + return + + if options.chrome_categories is None: + options.chrome_categories = '' + profile_options = options.enable_profiler.split(',') + # Add to the --chrome_categories flag. + if 'cpu' in profile_options: + if options.chrome_categories: + options.chrome_categories += ',' + options.chrome_categories += 'disabled-by-default-cpu_profiler' + if 'memory' in profile_options: + if options.chrome_categories: + options.chrome_categories += ',disabled-by-default-memory-infra' + else: + # If heap profiling is enabled and no categories are provided, it is + # usually not helpful to include other information in traces. '-*' + # disables other default categories so that only memory data is recorded. + options.chrome_categories += 'disabled-by-default-memory-infra,-*' def SetupLogging(verbosity):
diff --git a/tools/tracing/profile_chrome_startup b/tools/tracing/profile_chrome_startup index db260ee..5e9791f 100755 --- a/tools/tracing/profile_chrome_startup +++ b/tools/tracing/profile_chrome_startup
@@ -17,16 +17,13 @@ import flag_utils import display_in_browser + sys.path.insert(0, os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, 'third_party', 'catapult', 'systrace')) from systrace import util from profile_chrome import chrome_startup_tracing_agent -from profile_chrome import flags - - -_DEFAULT_CHROME_CATEGORIES = '_DEFAULT_CHROME_CATEGORIES' def _CreateOptionParser(): @@ -36,91 +33,48 @@ 'http://dev.chromium.org' '/developers/how-tos/trace-event-profiling-' 'tool for detailed instructions for ' - 'profiling.', conflict_handler='resolve') - parser = flag_utils.AddLoggingOptions(parser) - parser = util.get_main_options(parser) + 'profiling.', usage='%prog [options]', + prog='tools/tracing/profile_chrome_startup', + conflict_handler='resolve') - browsers = sorted(util.get_supported_browsers().keys()) - parser.add_option('--enable_profiler', help='Comma-separated string of ' - 'profiling options to use. Supports options for memory or ' - 'cpu or both. Ex: --enable_profiler=memory ' - 'or --enable_profiler=memory,cpu. ', - dest='enable_profiler') - parser.add_option('--browser', help='Select among installed browsers. ' - 'One of ' + ', '.join(browsers) + ', "stable" is used by ' - 'default.', type='choice', choices=browsers, - default='stable') - parser.add_option('--compress', help='Compress the resulting trace ' - 'with gzip. ', action='store_true') - parser.add_option('--time', help='Stops tracing after N seconds, 0 to ' - 'manually stop (startup trace ends after at most 5s).', - default=5, metavar='N', type='int', dest='trace_time') - parser.add_option('--chrome_categories', help='Chrome tracing ' - 'categories to record.', default=_DEFAULT_CHROME_CATEGORIES, - type='string') - parser.add_option('--platform', help='Device to system profile.', - dest='platform', default='android') - + parser.add_option_group(flag_utils.GeneralOptions(parser)) + parser.add_option_group(flag_utils.ProfileOptions(parser)) parser.add_option_group(chrome_startup_tracing_agent.add_options(parser)) - parser.add_option_group(flags.OutputOptions(parser)) - # TODO(rhuckleberry): Clean up flags. Move the tracing flags into an option - # group in flag_utils. Move catapult flags.py flags into flag_utils and stop - # calling flags.py. Rename |AddLoggingOptions| in flag_utils to a more - # general name to hold the view and output file flags. Add flag for whether - # we should symbolize the trace or not. parser.add_option_group(flag_utils.SymbolizeOptions(parser)) return parser -def _SetProfilingCategories(options): - """Sets --chrome_categories flag. - Uses the --enable_profile flag to modify the --chrome_categories flag for - specific profiling options. - - Args: - The command-line options given. - """ - if options.enable_profiler is None: - return - - if options.chrome_categories is None: - options.chrome_categories = '' - profile_options = options.enable_profiler.split(',') - # Add to the --chrome_categories flag. - if 'cpu' in profile_options: - if options.chrome_categories: - options.chrome_categories += ',' - options.chrome_categories += 'disabled-by-default-cpu_profiler' - if 'memory' in profile_options: - if options.chrome_categories: - options.chrome_categories += ',disabled-by-default-memory-infra' - else: - # If heap profiling is enabled and no categories are provided, it is - # usually not helpful to include other information in traces. '-*' - # disables other default categories so that only memory data is recorded. - options.chrome_categories += 'disabled-by-default-memory-infra,-*' +def _SetupFlags(options): + flag_utils.SetupProfilingCategories(options) + flag_utils.SetupLogging(options.verbosity) def main(): parser = _CreateOptionParser() options, _ = parser.parse_args() - _SetProfilingCategories(options) - flag_utils.SetupLogging(options.verbosity) + _SetupFlags(options) # Run Tracing trace_file = None if options.platform.lower() == 'android': + # TODO(rhuckleberry): Fix manual tracing. Setting flag --time=0 stalls and fails + # to download the collected trace. trace_file = adb_profile_chrome_startup.ProfileChrome(options) else: raise Exception('Platform "%s" is not supported. ' - 'Specify platform with the --platform flag.' % (options.platform)) + 'Specify platform with the --platform flag.' + % (options.platform)) + + print('Wrote unsymbolized trace to {path}'.format( + path=os.path.abspath(trace_file))) # Symbolize Trace - if options.trace_format is None or options.trace_format.lower() != 'proto': - raise Exception('Symbolization is currently only supported for protos.') - symbolize_trace.SymbolizeTrace(trace_file=trace_file, options=options) + if options.symbolize: + if options.trace_format is None or options.trace_format.lower() != 'proto': + raise Exception('Symbolization is currently only supported for protos.') + symbolize_trace.SymbolizeTrace(trace_file=trace_file, options=options) if options.view: display_in_browser.DisplayInBrowser(options.output_file, options)
diff --git a/tools/tracing/symbol_fetcher.py b/tools/tracing/symbol_fetcher.py index 3e93c05..5dc69e1 100644 --- a/tools/tracing/symbol_fetcher.py +++ b/tools/tracing/symbol_fetcher.py
@@ -41,9 +41,6 @@ Exception: if failed to extract trace OS name or version number, or they are not supported or recognized. """ - # TODO(rhuckleberry): Cache symbols so we do not have to download symbols - # from GCS for every trace. - metadata.Initialize() if metadata.os_name is None: raise Exception('Failed to extract trace OS name: ' + metadata.trace_file)
diff --git a/tools/tracing/symbolize_trace b/tools/tracing/symbolize_trace index 66c06161..e4fee037 100755 --- a/tools/tracing/symbolize_trace +++ b/tools/tracing/symbolize_trace
@@ -15,23 +15,16 @@ import flag_utils import display_in_browser -sys.path.insert(0, os.path.join(os.path.dirname(__file__), - os.pardir, os.pardir, 'third_party', - 'catapult', 'systrace')) - -from profile_chrome import flags - def _CreateOptionParser(): parser = optparse.OptionParser(description=('Symbolizes proto perfetto trace.' ' Takes a proto trace file as input.'), - usage='%prog <proto_trace_file> [options] ', + usage='%prog [options] <proto_trace_file>', prog='tools/tracing/symbolize_trace', conflict_handler='resolve') - parser = flag_utils.AddLoggingOptions(parser) + parser.add_option_group(flag_utils.GeneralOptions(parser)) parser.add_option_group(flag_utils.SymbolizeOptions(parser)) - parser.add_option_group(flags.OutputOptions(parser)) return parser @@ -44,7 +37,8 @@ # Argument error checking trace_file = None if not args: - raise Exception('Proto trace file argument is required.') + raise Exception('Proto trace file argument is required. Please pass the ' + 'trace file to symbolize.') elif len(args) > 1: raise Exception('Too many arguments passed. Pass only one proto trace file.') else:
diff --git a/tools/tracing/symbolize_trace.py b/tools/tracing/symbolize_trace.py index 33acdc1..e753fc5 100644 --- a/tools/tracing/symbolize_trace.py +++ b/tools/tracing/symbolize_trace.py
@@ -35,6 +35,8 @@ Exception: if breakpad_output_dir is not empty or if path to local breakpad directory is invalid. """ + print('Symbolizing file') + need_cleanup = False if options.local_breakpad_dir is None: # Ensure valid |breakpad_output_dir| @@ -68,6 +70,8 @@ _Symbolize(trace_file, options.symbolizer_path, options.breakpad_output_dir, options.output_file) + print('Symbolized trace saved to: ' + os.path.abspath(options.output_file)) + # Cleanup if need_cleanup: logging.debug('Cleaning up symbol files.') @@ -149,8 +153,9 @@ with open(output_file, 'w') as f: f.write(trace_data) f.write(symbol_data) - logging.debug('Symbolized %s(%d bytes) with %d bytes of symbol data', - trace_file, len(trace_data), len(symbol_data)) + logging.info('Symbolized %s(%d bytes) with %d bytes of symbol data', + os.path.abspath(trace_file), len(trace_data), + len(symbol_data)) def _RunSymbolizer(cmd, env, stdout):
diff --git a/tools/traffic_annotation/summary/grouping.xml b/tools/traffic_annotation/summary/grouping.xml index e5bf2b18..f91c34c 100644 --- a/tools/traffic_annotation/summary/grouping.xml +++ b/tools/traffic_annotation/summary/grouping.xml
@@ -70,9 +70,6 @@ <traffic_annotation unique_id="pdf_plugin_placeholder"/> <traffic_annotation unique_id="predictive_prefetch"/> <traffic_annotation unique_id="navigation_predictor_srp_prefetch"/> - <traffic_annotation unique_id="cloud_print_privet_register"/> - <traffic_annotation unique_id="cloud_print_search"/> - <traffic_annotation unique_id="privet_http_impl"/> <traffic_annotation unique_id="render_view_context_menu"/> <traffic_annotation unique_id="media_router_global_media_controls_image"/> <traffic_annotation unique_id="omnibox_navigation_observer"/>
diff --git a/ui/accessibility/BUILD.gn b/ui/accessibility/BUILD.gn index 42d1928f..dfe9385a 100644 --- a/ui/accessibility/BUILD.gn +++ b/ui/accessibility/BUILD.gn
@@ -88,6 +88,10 @@ ] deps = [ "//build:chromeos_buildflags" ] + + if (is_chromeos_ash) { + deps += [ "//ash/constants" ] + } } #if (is_win) {
diff --git a/ui/accessibility/DEPS b/ui/accessibility/DEPS index 3f90904d..103d728 100644 --- a/ui/accessibility/DEPS +++ b/ui/accessibility/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+ash/constants", "+mojo/public", "+third_party/cld_3", "+third_party/iaccessible2",
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc index 290d38f8..f6b96e9 100644 --- a/ui/accessibility/accessibility_features.cc +++ b/ui/accessibility/accessibility_features.cc
@@ -8,6 +8,10 @@ #include "build/build_config.h" #include "build/chromeos_buildflags.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "ash/constants/ash_features.h" +#endif + namespace features { // Enable recognizing "aria-virtualcontent" as a valid aria property. @@ -155,6 +159,12 @@ ::features::kExperimentalAccessibilityDictationOffline); } +bool IsDictationOfflineAvailableAndEnabled() { + return base::FeatureList::IsEnabled( + ash::features::kOnDeviceSpeechRecognition) && + IsExperimentalAccessibilityDictationOfflineEnabled(); +} + const base::Feature kEnhancedNetworkVoices{"EnhancedNetworkVoices", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/ui/accessibility/accessibility_features.h b/ui/accessibility/accessibility_features.h index 28174e76..23f8220 100644 --- a/ui/accessibility/accessibility_features.h +++ b/ui/accessibility/accessibility_features.h
@@ -133,6 +133,8 @@ // Returns true if experimental accessibility offline dictation is enabled. AX_BASE_EXPORT bool IsExperimentalAccessibilityDictationOfflineEnabled(); +AX_BASE_EXPORT bool IsDictationOfflineAvailableAndEnabled(); + // Enables high-quality, network-based voices in Select-to-speak. AX_BASE_EXPORT extern const base::Feature kEnhancedNetworkVoices;
diff --git a/ui/base/clipboard/clipboard.cc b/ui/base/clipboard/clipboard.cc index 73fae6a..1916e5c 100644 --- a/ui/base/clipboard/clipboard.cc +++ b/ui/base/clipboard/clipboard.cc
@@ -10,6 +10,7 @@ #include "base/check.h" #include "base/containers/contains.h" +#include "base/json/json_reader.h" #include "base/memory/ptr_util.h" #include "base/notreached.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -137,6 +138,33 @@ void Clipboard::ClearLastModifiedTime() {} +std::map<std::string, std::string> Clipboard::ExtractCustomPlatformNames( + ClipboardBuffer buffer, + const DataTransferEndpoint* data_dst) const { + // Read the JSON metadata payload. + std::map<std::string, std::string> custom_format_names; + if (IsFormatAvailable(ui::ClipboardFormatType::WebCustomFormatMap(), buffer, + data_dst)) { + std::string custom_format_json; + // Read the custom format map. + ReadData(ui::ClipboardFormatType::WebCustomFormatMap(), data_dst, + &custom_format_json); + if (!custom_format_json.empty()) { + absl::optional<base::Value> json_val = + base::JSONReader::Read(custom_format_json); + if (json_val.has_value()) { + for (const auto it : json_val->DictItems()) { + std::string custom_format_name; + if (it.second.GetAsString(&custom_format_name)) { + custom_format_names.emplace(it.first, custom_format_name); + } + } + } + } + } + return custom_format_names; +} + Clipboard::Clipboard() = default; Clipboard::~Clipboard() = default; @@ -203,6 +231,11 @@ &(params[1].front()), params[1].size()); break; + case PortableFormat::kWebCustomFormatMap: + WriteData(ClipboardFormatType::WebCustomFormatMap(), + &(params[0].front()), params[0].size()); + break; + default: NOTREACHED(); } @@ -211,7 +244,7 @@ void Clipboard::DispatchPlatformRepresentations( std::vector<Clipboard::PlatformRepresentation> platform_representations) { for (const auto& representation : platform_representations) { - WriteData(ClipboardFormatType::GetCustomPlatformType(representation.format), + WriteData(ClipboardFormatType::CustomPlatformType(representation.format), reinterpret_cast<const char*>(representation.data.data()), representation.data.size()); }
diff --git a/ui/base/clipboard/clipboard.h b/ui/base/clipboard/clipboard.h index 0d3c825..85009c94 100644 --- a/ui/base/clipboard/clipboard.h +++ b/ui/base/clipboard/clipboard.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include <stdint.h> +#include <map> #include <memory> #include <string> #include <vector> @@ -265,6 +266,15 @@ // Resets the clipboard last modified time to Time::Time(). virtual void ClearLastModifiedTime(); + // Reads the web custom format map (which is in JSON format) from the + // clipboard if it's available. Parses the JSON string that has the mapping of + // MIME type to custom format name and fetches the list of custom MIME types. + // e.g. on Windows, the mapping is represented as "text/html":"Web Custom + // Format(0-99)". + std::map<std::string, std::string> ExtractCustomPlatformNames( + ClipboardBuffer buffer, + const DataTransferEndpoint* data_dst) const; + protected: // PortableFormat designates the type of data to be stored in the clipboard. // This designation is shared across all OSes. The system-specific designation @@ -291,6 +301,7 @@ kData, // Arbitrary block of bytes. kSvg, kFilenames, + kWebCustomFormatMap, }; // TODO (https://crbug.com/994928): Rename ObjectMap-related types. @@ -314,6 +325,7 @@ // kWebkit none empty vector // kData format char array // data byte array + // kWebCustomFormatMap char array using ObjectMapParam = std::vector<char>; using ObjectMapParams = std::vector<ObjectMapParam>; using ObjectMap = base::flat_map<PortableFormat, ObjectMapParams>;
diff --git a/ui/base/clipboard/clipboard_format_type.h b/ui/base/clipboard/clipboard_format_type.h index 8269509..e3ca57b66 100644 --- a/ui/base/clipboard/clipboard_format_type.h +++ b/ui/base/clipboard/clipboard_format_type.h
@@ -82,19 +82,19 @@ static const ClipboardFormatType& MozUrlType(); #endif - // Gets the ClipboardFormatType corresponding to an arbitrary format string, - // registering it with the system if needed. Due to Windows/Linux - // limitations, please place limits on the amount of GetType calls with unique - // |format_string| arguments, when ingesting |format_string| from - // untrusted sources, such as renderer processes. In Windows, a failure will - // return an invalid format with Deserialize()'ed value of "0". - // The custom format name is transformed to the appropriate custom platform - // type name. - static ClipboardFormatType GetCustomPlatformType( + // For custom formats we hardcode the web custom format prefix and the index. + // Due to Windows/Linux limitations, please place limits on the amount of + // `WebCustomFormatName` calls with unique `index` argument. + static std::string WebCustomFormatName(int index); + // Gets the ClipboardFormatType corresponding to a format string, + // registering it with the system if needed. + static ClipboardFormatType CustomPlatformType( const std::string& format_string); - // Returns a custom MIME type from custom format name. - // e.g. On Windows, "Web Text HTML" is returned as "text/html". - std::string GetCustomPlatformName() const; + // Returns the web custom format map that has the mapping of MIME types to + // custom format names. + static const ClipboardFormatType& WebCustomFormatMap(); + // Returns the web custom format map name. + static std::string WebCustomFormatMapName(); // ClipboardFormatType can be used in a set on some platforms. bool operator<(const ClipboardFormatType& other) const;
diff --git a/ui/base/clipboard/clipboard_format_type_android.cc b/ui/base/clipboard/clipboard_format_type_android.cc index f515c2764..7af255b 100644 --- a/ui/base/clipboard/clipboard_format_type_android.cc +++ b/ui/base/clipboard/clipboard_format_type_android.cc
@@ -4,6 +4,9 @@ #include "ui/base/clipboard/clipboard_format_type.h" +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "ui/base/clipboard/clipboard_constants.h" namespace ui { @@ -38,15 +41,29 @@ return data_ == other.data_; } -// TODO(crbug.com/106449): Support custom formats. -ClipboardFormatType ClipboardFormatType::GetCustomPlatformType( +// static +std::string ClipboardFormatType::WebCustomFormatName(int index) { + return base::StrCat({"application/web;type=\"custom/format", + base::NumberToString(index), "\""}); +} + +// static +std::string ClipboardFormatType::WebCustomFormatMapName() { + return "application/web;type=\"custom/formatmap\""; +} + +// static +ClipboardFormatType ClipboardFormatType::CustomPlatformType( const std::string& format_string) { + DCHECK(base::IsStringASCII(format_string)); return ClipboardFormatType::Deserialize(format_string); } -// TODO(crbug.com/106449): Support custom formats. -std::string ClipboardFormatType::GetCustomPlatformName() const { - return Serialize(); +// static +const ClipboardFormatType& ClipboardFormatType::WebCustomFormatMap() { + static base::NoDestructor<ClipboardFormatType> type( + ClipboardFormatType::WebCustomFormatMapName()); + return *type; } // Various predefined ClipboardFormatTypes.
diff --git a/ui/base/clipboard/clipboard_format_type_aura.cc b/ui/base/clipboard/clipboard_format_type_aura.cc index ec943ee6..078fa98 100644 --- a/ui/base/clipboard/clipboard_format_type_aura.cc +++ b/ui/base/clipboard/clipboard_format_type_aura.cc
@@ -4,6 +4,9 @@ #include "ui/base/clipboard/clipboard_format_type.h" +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "ui/base/clipboard/clipboard_constants.h" namespace ui { @@ -41,15 +44,29 @@ return data_ == other.data_; } -// TODO(crbug.com/106449): Support custom formats. -ClipboardFormatType ClipboardFormatType::GetCustomPlatformType( +// static +ClipboardFormatType ClipboardFormatType::CustomPlatformType( const std::string& format_string) { + DCHECK(base::IsStringASCII(format_string)); return ClipboardFormatType::Deserialize(format_string); } -// TODO(crbug.com/106449): Support custom formats. -std::string ClipboardFormatType::GetCustomPlatformName() const { - return Serialize(); +// static +std::string ClipboardFormatType::WebCustomFormatName(int index) { + return base::StrCat({"application/web;type=\"custom/format", + base::NumberToString(index), "\""}); +} + +// static +std::string ClipboardFormatType::WebCustomFormatMapName() { + return "application/web;type=\"custom/formatmap\""; +} + +// static +const ClipboardFormatType& ClipboardFormatType::WebCustomFormatMap() { + static base::NoDestructor<ClipboardFormatType> type( + ClipboardFormatType::WebCustomFormatMapName()); + return *type; } // Various predefined ClipboardFormatTypes.
diff --git a/ui/base/clipboard/clipboard_format_type_mac.mm b/ui/base/clipboard/clipboard_format_type_mac.mm index 4c91729..f370fc87 100644 --- a/ui/base/clipboard/clipboard_format_type_mac.mm +++ b/ui/base/clipboard/clipboard_format_type_mac.mm
@@ -6,6 +6,9 @@ #import <Cocoa/Cocoa.h> +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h" #include "ui/base/clipboard/clipboard_constants.h" @@ -58,15 +61,27 @@ } // static -// TODO(crbug.com/106449): Support custom formats. -ClipboardFormatType ClipboardFormatType::GetCustomPlatformType( - const std::string& format_string) { - return ClipboardFormatType::Deserialize(format_string); +std::string ClipboardFormatType::WebCustomFormatName(int index) { + return base::StrCat({"com.web.custom.format", base::NumberToString(index)}); } -// TODO(crbug.com/106449): Support custom formats. -std::string ClipboardFormatType::GetCustomPlatformName() const { - return Serialize(); +// static +std::string ClipboardFormatType::WebCustomFormatMapName() { + return "com.web.custom.format.map"; +} + +// static +const ClipboardFormatType& ClipboardFormatType::WebCustomFormatMap() { + static base::NoDestructor<ClipboardFormatType> type( + base::SysUTF8ToNSString(ClipboardFormatType::WebCustomFormatMapName())); + return *type; +} + +// static +ClipboardFormatType ClipboardFormatType::CustomPlatformType( + const std::string& format_string) { + DCHECK(base::IsStringASCII(format_string)); + return ClipboardFormatType::Deserialize(format_string); } // Various predefined ClipboardFormatTypes.
diff --git a/ui/base/clipboard/clipboard_format_type_win.cc b/ui/base/clipboard/clipboard_format_type_win.cc index 316959a..b700f40e 100644 --- a/ui/base/clipboard/clipboard_format_type_win.cc +++ b/ui/base/clipboard/clipboard_format_type_win.cc
@@ -58,74 +58,32 @@ } // static -ClipboardFormatType ClipboardFormatType::GetCustomPlatformType( - const std::string& format_string) { - // For unsanitized custom formats, we add `Web ` prefix and capitalize the - // first letter of each word in the format. e.g. `text/custom` format would be - // converted to `Web Text Custom`. Similarly for `text/html` or any other - // standard formats, the pickled version would be prefixed with `Web ` and - // first letter capitalized. e.g. text/html would be converted to `Web Text - // Html`. - // For security reasons we also check for valid ascii codepoints. - constexpr int kMinNameSize = 3; // Formats need to have at least 3 chars. - if (!base::IsStringASCII(format_string) || - format_string.size() < kMinNameSize) { - return ClipboardFormatType(); - } - - size_t index = format_string.find('/'); - if (index == std::string::npos || index == 0 || - index == format_string.size() - 1) - return ClipboardFormatType(); - base::StringPiece first_part = - base::StringPiece(format_string).substr(0, index); - base::StringPiece second_part = - base::StringPiece(format_string).substr(index + 1); - std::string web_custom_format_string = base::StrCat( - {"Web ", base::ToUpperASCII(first_part.substr(0, 1)), - first_part.substr(1), " ", base::ToUpperASCII(second_part.substr(0, 1)), - second_part.substr(1)}); - return ClipboardFormatType(::RegisterClipboardFormat( - base::ASCIIToWide(web_custom_format_string).c_str())); +std::string ClipboardFormatType::WebCustomFormatName(int index) { + return base::StrCat({"Web Custom Format", base::NumberToString(index)}); } // static -std::string ClipboardFormatType::GetCustomPlatformName() const { - constexpr size_t kMaxFormatSize = 1024; - static base::NoDestructor<std::vector<wchar_t>> name_buffer(kMaxFormatSize); - int name_size = GetClipboardFormatName(data_.cfFormat, name_buffer->data(), - kMaxFormatSize); - // Custom formats should have at least 7 characters. e.g. "Web x y" - constexpr int kMinNameSize = 7; - if (!name_size || name_size < kMinNameSize) { - // Input format doesn't exist or is predefined. - return std::string(); - } +std::string ClipboardFormatType::WebCustomFormatMapName() { + return "Web Custom Format Map"; +} - std::string format_name_in_clipboard = - base::WideToASCII(std::wstring(name_buffer->data(), name_size)); +// static +ClipboardFormatType ClipboardFormatType::CustomPlatformType( + const std::string& format_string) { + // Once these formats are registered, `RegisterClipboardFormat` just returns + // the `cfFormat` associated with it and doesn't register a new format. + DCHECK(base::IsStringASCII(format_string)); + return ClipboardFormatType( + ::RegisterClipboardFormat(base::ASCIIToWide(format_string).c_str())); +} - // For security reasons we also check for valid ascii codepoints. - if (!base::IsStringASCII(format_name_in_clipboard)) - return std::string(); - // For unsanitized custom formats (prefixed with Web) we extract the strings - // and convert it into standard representation. e.g. `Web Text Custom` format - // would be converted to `text/custom`. - if (format_name_in_clipboard.substr(0, 4) == "Web ") { - base::StringPiece format_name = - base::StringPiece(format_name_in_clipboard).substr(4); - size_t space_index = format_name.find(" "); - - if (space_index == std::string::npos) - return std::string(); - if (format_name.size() < (space_index + 2)) - return std::string(); - - return base::StrCat( - {base::ToLowerASCII(format_name.substr(0, space_index)), "/", - base::ToLowerASCII(format_name.substr(space_index + 1))}); - } - return format_name_in_clipboard; +// static +const ClipboardFormatType& ClipboardFormatType::WebCustomFormatMap() { + static base::NoDestructor<ClipboardFormatType> format( + ::RegisterClipboardFormat( + base::ASCIIToWide(ClipboardFormatType::WebCustomFormatMapName()) + .c_str())); + return *format; } std::string ClipboardFormatType::GetName() const {
diff --git a/ui/base/clipboard/clipboard_test_template.h b/ui/base/clipboard/clipboard_test_template.h index d434f59..e75861f2 100644 --- a/ui/base/clipboard/clipboard_test_template.h +++ b/ui/base/clipboard/clipboard_test_template.h
@@ -809,11 +809,11 @@ EXPECT_EQ(payload1, unpickled_string1); } +// TODO(crbug.com/106449): Implement custom formats on other platforms. +#if defined(OS_WIN) TYPED_TEST(ClipboardTest, DataTest) { const std::string kFormatString = "chromium/x-test-format"; const std::u16string kFormatString16 = u"chromium/x-test-format"; - const ClipboardFormatType kFormat = - ClipboardFormatType::GetCustomPlatformType(kFormatString); const std::string payload = "test string"; base::span<const uint8_t> payload_span( reinterpret_cast<const uint8_t*>(payload.data()), payload.size()); @@ -824,55 +824,28 @@ mojo_base::BigBuffer(payload_span)); } - ASSERT_TRUE(this->clipboard().IsFormatAvailable( - kFormat, ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr)); + std::map<std::string, std::string> custom_format_names = + this->clipboard().ExtractCustomPlatformNames(ClipboardBuffer::kCopyPaste, + /* data_dst = */ nullptr); + EXPECT_TRUE(custom_format_names.find(kFormatString) != + custom_format_names.end()); std::string output; - this->clipboard().ReadData(kFormat, /* data_dst = */ nullptr, &output); + this->clipboard().ReadData(ClipboardFormatType::CustomPlatformType( + custom_format_names[kFormatString]), + /* data_dst = */ nullptr, &output); EXPECT_EQ(payload, output); } -#if defined(OS_WIN) -TYPED_TEST(ClipboardTest, CustomFormatTypeAndNameTest) { - const std::string kFormatString1 = "a/bc"; - const std::string kFormatString2 = "/abc"; - const std::string kFormatString3 = "abc/"; - const std::string kFormatString4 = "a/"; - const std::string kFormatString5 = "/a"; - const std::string kFormatString6 = "a/c"; - ClipboardFormatType format = - ClipboardFormatType::GetCustomPlatformType(kFormatString1); - EXPECT_EQ("a/bc", format.GetCustomPlatformName()); - format = ClipboardFormatType::GetCustomPlatformType(kFormatString2); - EXPECT_EQ("", format.GetCustomPlatformName()); - format = ClipboardFormatType::GetCustomPlatformType(kFormatString3); - EXPECT_EQ("", format.GetCustomPlatformName()); - format = ClipboardFormatType::GetCustomPlatformType(kFormatString4); - EXPECT_EQ("", format.GetCustomPlatformName()); - format = ClipboardFormatType::GetCustomPlatformType(kFormatString5); - EXPECT_EQ("", format.GetCustomPlatformName()); - format = ClipboardFormatType::GetCustomPlatformType(kFormatString6); - EXPECT_EQ("a/c", format.GetCustomPlatformName()); -} -#endif - -// crbug.com/1224904: Flaky on Mac. -#if (!defined(USE_AURA) || defined(OS_WIN) || defined(USE_OZONE) || \ - defined(USE_X11)) && \ - !BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OS_MAC) TYPED_TEST(ClipboardTest, MultipleDataTest) { const std::string kFormatString1 = "chromium/x-test-format1"; const std::u16string kFormatString116 = u"chromium/x-test-format1"; - const ClipboardFormatType kFormat1 = - ClipboardFormatType::GetCustomPlatformType(kFormatString1); const std::string payload1("test string1"); base::span<const uint8_t> payload_span1( reinterpret_cast<const uint8_t*>(payload1.data()), payload1.size()); const std::string kFormatString2 = "chromium/x-test-format2"; const std::u16string kFormatString216 = u"chromium/x-test-format2"; - const ClipboardFormatType kFormat2 = - ClipboardFormatType::GetCustomPlatformType(kFormatString2); const std::string payload2("test string2"); base::span<const uint8_t> payload_span2( reinterpret_cast<const uint8_t*>(payload2.data()), payload2.size()); @@ -890,36 +863,42 @@ EXPECT_THAT(this->clipboard().ReadAvailablePlatformSpecificFormatNames( ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr), Contains(kFormatString116)); - EXPECT_TRUE(this->clipboard().IsFormatAvailable( - kFormat1, ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr)); + std::string custom_format_json; + this->clipboard().ReadData(ClipboardFormatType::WebCustomFormatMap(), + /* data_dst = */ nullptr, &custom_format_json); + std::map<std::string, std::string> custom_format_names = + this->clipboard().ExtractCustomPlatformNames(ClipboardBuffer::kCopyPaste, + /* data_dst = */ nullptr); + EXPECT_TRUE(custom_format_names.find(kFormatString1) != + custom_format_names.end()); std::string output1; - this->clipboard().ReadData(kFormat1, /* data_dst = */ nullptr, &output1); + this->clipboard().ReadData(ClipboardFormatType::CustomPlatformType( + custom_format_names[kFormatString1]), + /* data_dst = */ nullptr, &output1); EXPECT_EQ(payload1, output1); // Check format 2. EXPECT_THAT(this->clipboard().ReadAvailablePlatformSpecificFormatNames( ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr), Contains(kFormatString216)); - EXPECT_TRUE(this->clipboard().IsFormatAvailable( - kFormat2, ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr)); + EXPECT_TRUE(custom_format_names.find(kFormatString2) != + custom_format_names.end()); std::string output2; - this->clipboard().ReadData(kFormat2, /* data_dst = */ nullptr, &output2); + this->clipboard().ReadData(ClipboardFormatType::CustomPlatformType( + custom_format_names[kFormatString2]), + /* data_dst = */ nullptr, &output2); EXPECT_EQ(payload2, output2); } TYPED_TEST(ClipboardTest, DataAndPortableFormatTest) { const std::string kFormatString1 = "chromium/x-test-format1"; const std::u16string kFormatString116 = u"chromium/x-test-format1"; - const ClipboardFormatType kFormat1 = - ClipboardFormatType::GetCustomPlatformType(kFormatString1); const std::string payload1("test string1"); base::span<const uint8_t> payload_span1( reinterpret_cast<const uint8_t*>(payload1.data()), payload1.size()); const std::string kFormatString2 = "text/plain"; const std::u16string kFormatString216 = u"text/plain"; - const ClipboardFormatType kFormat2 = - ClipboardFormatType::GetCustomPlatformType(kFormatString2); const std::string payload2("test string2"); base::span<const uint8_t> payload_span2( reinterpret_cast<const uint8_t*>(payload2.data()), payload2.size()); @@ -937,20 +916,30 @@ EXPECT_THAT(this->clipboard().ReadAvailablePlatformSpecificFormatNames( ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr), Contains(kFormatString116)); - EXPECT_TRUE(this->clipboard().IsFormatAvailable( - kFormat1, ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr)); + std::string custom_format_json; + this->clipboard().ReadData(ClipboardFormatType::WebCustomFormatMap(), + /* data_dst = */ nullptr, &custom_format_json); + std::map<std::string, std::string> custom_format_names = + this->clipboard().ExtractCustomPlatformNames(ClipboardBuffer::kCopyPaste, + /* data_dst = */ nullptr); + EXPECT_TRUE(custom_format_names.find(kFormatString1) != + custom_format_names.end()); std::string output1; - this->clipboard().ReadData(kFormat1, /* data_dst = */ nullptr, &output1); + this->clipboard().ReadData(ClipboardFormatType::CustomPlatformType( + custom_format_names[kFormatString1]), + /* data_dst = */ nullptr, &output1); EXPECT_EQ(payload1, output1); // Check format 2. EXPECT_THAT(this->clipboard().ReadAvailablePlatformSpecificFormatNames( ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr), Contains(kFormatString216)); - EXPECT_TRUE(this->clipboard().IsFormatAvailable( - kFormat2, ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr)); + EXPECT_TRUE(custom_format_names.find(kFormatString2) != + custom_format_names.end()); std::string output2; - this->clipboard().ReadData(kFormat2, /* data_dst = */ nullptr, &output2); + this->clipboard().ReadData(ClipboardFormatType::CustomPlatformType( + custom_format_names[kFormatString2]), + /* data_dst = */ nullptr, &output2); EXPECT_EQ(payload2, output2); } #endif @@ -1050,40 +1039,20 @@ mojo_base::BigBuffer(text_span)); } - const std::vector<std::u16string> raw_types = - this->clipboard().ReadAvailablePlatformSpecificFormatNames( - ClipboardBuffer::kCopyPaste, /* data_dst = */ nullptr); + std::string custom_format_json; + this->clipboard().ReadData(ClipboardFormatType::WebCustomFormatMap(), + /* data_dst = */ nullptr, &custom_format_json); + std::map<std::string, std::string> custom_format_names = + this->clipboard().ExtractCustomPlatformNames(ClipboardBuffer::kCopyPaste, + /* data_dst = */ nullptr); - EXPECT_THAT(raw_types, Contains(ASCIIToUTF16(kFormatString))); - -#if defined(OS_WIN) - // Custom format is only available on Windows. - EXPECT_TRUE(this->clipboard().IsFormatAvailable( - ClipboardFormatType::GetCustomPlatformType(kFormatString), - ClipboardBuffer::kCopyPaste, - /* data_dst = */ nullptr)); -#else - // TODO(crbug.com/106449): Support custom formats on other platforms. - EXPECT_TRUE(this->clipboard().IsFormatAvailable( - ClipboardFormatType::PlainTextType(), ClipboardBuffer::kCopyPaste, - /* data_dst = */ nullptr)); - std::string text_result; - this->clipboard().ReadAsciiText(ClipboardBuffer::kCopyPaste, - /* data_dst = */ nullptr, &text_result); - EXPECT_EQ(text_result, text); - // Windows will automatically convert CF_TEXT to its UNICODE version. - EXPECT_TRUE(this->clipboard().IsFormatAvailable( - ClipboardFormatType::PlainTextType(), ClipboardBuffer::kCopyPaste, - /* data_dst = */ nullptr)); - std::u16string text_result16; - this->clipboard().ReadText(ClipboardBuffer::kCopyPaste, - /* data_dst = */ nullptr, &text_result16); - EXPECT_EQ(text_result16, base::ASCIIToUTF16(text)); -#endif // defined(OS_WIN) + EXPECT_TRUE(custom_format_names.find(kFormatString) != + custom_format_names.end()); std::string platform_specific_result; - this->clipboard().ReadData( - ClipboardFormatType::GetCustomPlatformType(kFormatString), - /* data_dst = */ nullptr, &platform_specific_result); + this->clipboard().ReadData(ClipboardFormatType::CustomPlatformType( + custom_format_names[kFormatString]), + /* data_dst = */ nullptr, + &platform_specific_result); EXPECT_EQ(platform_specific_result, kPlatformSpecificText); } #endif // defined(OS_WIN) || defined(USE_X11)
diff --git a/ui/base/clipboard/clipboard_win.cc b/ui/base/clipboard/clipboard_win.cc index 2e5645c..9422954 100644 --- a/ui/base/clipboard/clipboard_win.cc +++ b/ui/base/clipboard/clipboard_win.cc
@@ -354,13 +354,16 @@ if (!clipboard.Acquire(GetClipboardWindow())) return {}; + // Check if we have any custom formats in the clipboard. + std::map<std::string, std::string> custom_format_names = + ExtractCustomPlatformNames(buffer, data_dst); + for (const auto& items : custom_format_names) { + types.push_back(base::ASCIIToUTF16(items.first)); + } UINT cf_format = 0; cf_format = ::EnumClipboardFormats(cf_format); while (cf_format) { std::string type_name = ClipboardFormatType(cf_format).GetName(); - // Search for custom types if we couldn't find a standard format. - if (type_name.empty()) - type_name = ClipboardFormatType(cf_format).GetCustomPlatformName(); if (!type_name.empty()) types.push_back(base::ASCIIToUTF16(type_name)); cf_format = ::EnumClipboardFormats(cf_format);
diff --git a/ui/base/clipboard/scoped_clipboard_writer.cc b/ui/base/clipboard/scoped_clipboard_writer.cc index 6b7858f1..153f169 100644 --- a/ui/base/clipboard/scoped_clipboard_writer.cc +++ b/ui/base/clipboard/scoped_clipboard_writer.cc
@@ -6,8 +6,10 @@ #include <memory> #include <utility> +#include "base/json/json_writer.h" #include "base/pickle.h" #include "base/strings/utf_string_conversions.h" +#include "base/values.h" #include "net/base/escape.h" #include "ui/base/clipboard/clipboard_format_type.h" #include "ui/base/clipboard/clipboard_metrics.h" @@ -25,6 +27,19 @@ ScopedClipboardWriter::~ScopedClipboardWriter() { static constexpr size_t kMaxRepresentations = 1 << 12; DCHECK(platform_representations_.size() < kMaxRepresentations); + // If the metadata format type is not empty then create a JSON payload and + // write to the clipboard. + if (!registered_formats_.empty()) { + std::string custom_format_json; + base::Value registered_formats_value(base::Value::Type::DICTIONARY); + for (const auto& item : registered_formats_) + registered_formats_value.SetStringKey(item.first, item.second); + base::JSONWriter::Write(registered_formats_value, &custom_format_json); + Clipboard::ObjectMapParams parameters; + parameters.push_back(Clipboard::ObjectMapParam(custom_format_json.begin(), + custom_format_json.end())); + objects_[Clipboard::PortableFormat::kWebCustomFormatMap] = parameters; + } if (!objects_.empty() || !platform_representations_.empty()) { Clipboard::GetForCurrentThread()->WritePortableAndPlatformRepresentations( buffer_, objects_, std::move(platform_representations_), @@ -171,15 +186,39 @@ void ScopedClipboardWriter::WriteData(const std::u16string& format, mojo_base::BigBuffer data) { RecordWrite(ClipboardFormatMetric::kData); - platform_representations_.push_back( - {base::UTF16ToASCII(format), std::move(data)}); + // Windows / X11 clipboards enter an unrecoverable state after registering + // some amount of unique formats, and there's no way to un-register these + // formats. For these clipboards, use a conservative limit to avoid + // registering too many formats, as: + // (1) Other native applications may also register clipboard formats. + // (2) Malicious sites can write more than the hard limit defined on + // Windows(16k). (3) Chrome also registers other clipboard formats. + // + // There will be a custom format map which contains a JSON payload that will + // have a mapping of custom format MIME type to web custom format. + // There can only be 100 custom format per write and it will be + // registered when the web authors request for a custom format. + static constexpr int kMaxRegisteredFormats = 100; + if (counter_ >= kMaxRegisteredFormats) + return; + std::string format_in_ascii = base::UTF16ToASCII(format); + if (registered_formats_.find(format_in_ascii) == registered_formats_.end()) { + std::string web_custom_format_string = + ClipboardFormatType::WebCustomFormatName(counter_); + registered_formats_[format_in_ascii] = web_custom_format_string; + counter_++; + platform_representations_.push_back( + {web_custom_format_string, std::move(data)}); + } } void ScopedClipboardWriter::Reset() { objects_.clear(); platform_representations_.clear(); + registered_formats_.clear(); bitmap_.reset(); confidential_ = false; + counter_ = 0; } } // namespace ui
diff --git a/ui/base/clipboard/scoped_clipboard_writer.h b/ui/base/clipboard/scoped_clipboard_writer.h index d47028af..879acd4 100644 --- a/ui/base/clipboard/scoped_clipboard_writer.h +++ b/ui/base/clipboard/scoped_clipboard_writer.h
@@ -8,6 +8,7 @@ #include <string> #include "base/component_export.h" +#include "base/containers/flat_map.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/data_transfer_policy/data_transfer_endpoint.h" @@ -94,6 +95,9 @@ Clipboard::ObjectMap objects_; std::vector<Clipboard::PlatformRepresentation> platform_representations_; + // Keeps track of the unique custom formats registered in the clipboard. + base::flat_map<std::string, std::string> registered_formats_; + int counter_ = 0; // The type is set at construction, and can be changed before committing. const ClipboardBuffer buffer_;
diff --git a/ui/base/clipboard/test/test_clipboard.cc b/ui/base/clipboard/test/test_clipboard.cc index 7f5a7c25..0790339 100644 --- a/ui/base/clipboard/test/test_clipboard.cc +++ b/ui/base/clipboard/test/test_clipboard.cc
@@ -142,11 +142,15 @@ const auto& data = store.data; std::vector<std::u16string> types; types.reserve(data.size()); + std::map<std::string, std::string> custom_format_names = + ExtractCustomPlatformNames(buffer, data_dst); + for (const auto& item : custom_format_names) + types.push_back(base::UTF8ToUTF16(item.first)); for (const auto& it : data) { std::string format_type = it.first.GetName(); - if (format_type.empty()) - format_type = it.first.GetCustomPlatformName(); - types.push_back(base::UTF8ToUTF16(format_type)); + if (!format_type.empty()) { + types.push_back(base::UTF8ToUTF16(format_type)); + } } return types; @@ -314,6 +318,7 @@ std::unique_ptr<DataTransferEndpoint> data_src) { Clear(buffer); default_store_buffer_ = buffer; + DispatchPlatformRepresentations(std::move(platform_representations)); for (const auto& kv : objects) DispatchPortableRepresentation(kv.first, kv.second);
diff --git a/ui/base/mojom/window_open_disposition.mojom b/ui/base/mojom/window_open_disposition.mojom index 3bab2371..6944331 100644 --- a/ui/base/mojom/window_open_disposition.mojom +++ b/ui/base/mojom/window_open_disposition.mojom
@@ -29,3 +29,13 @@ // NEW_FOREGROUND_TAB when no existing tab is found. SWITCH_TO_TAB, }; + +// Click information needed to determine user's desired window disposition using +// ui::DispositionFromClick(). +struct ClickModifiers { + bool middle_button; + bool alt_key; + bool ctrl_key; + bool meta_key; + bool shift_key; +};
diff --git a/ui/compositor/overscroll/scroll_input_handler.cc b/ui/compositor/overscroll/scroll_input_handler.cc index 15f1a6a0..e5acb17 100644 --- a/ui/compositor/overscroll/scroll_input_handler.cc +++ b/ui/compositor/overscroll/scroll_input_handler.cc
@@ -88,6 +88,8 @@ void ScrollInputHandler::ReconcileElasticOverscrollAndRootScroll() {} +void ScrollInputHandler::SetPrefersReducedMotion(bool prefers_reduced_motion) {} + void ScrollInputHandler::UpdateRootLayerStateForSynchronousInputHandler( const gfx::ScrollOffset& total_scroll_offset, const gfx::ScrollOffset& max_scroll_offset,
diff --git a/ui/compositor/overscroll/scroll_input_handler.h b/ui/compositor/overscroll/scroll_input_handler.h index d5c750b..57b84ec 100644 --- a/ui/compositor/overscroll/scroll_input_handler.h +++ b/ui/compositor/overscroll/scroll_input_handler.h
@@ -29,6 +29,7 @@ void WillShutdown() override; void Animate(base::TimeTicks time) override; void ReconcileElasticOverscrollAndRootScroll() override; + void SetPrefersReducedMotion(bool prefers_reduced_motion) override; void UpdateRootLayerStateForSynchronousInputHandler( const gfx::ScrollOffset& total_scroll_offset, const gfx::ScrollOffset& max_scroll_offset,
diff --git a/ui/display/BUILD.gn b/ui/display/BUILD.gn index a7a8a47..bdee16a8 100644 --- a/ui/display/BUILD.gn +++ b/ui/display/BUILD.gn
@@ -29,6 +29,8 @@ "display_switches.h", "display_transform.cc", "display_transform.h", + "display_util.cc", + "display_util.h", "scoped_display_for_new_windows.cc", "scoped_display_for_new_windows.h", "screen.cc",
diff --git a/content/browser/renderer_host/display_util.cc b/ui/display/display_util.cc similarity index 64% rename from content/browser/renderer_host/display_util.cc rename to ui/display/display_util.cc index 12fbed7..3a32f1c1 100644 --- a/content/browser/renderer_host/display_util.cc +++ b/ui/display/display_util.cc
@@ -2,19 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "content/browser/renderer_host/display_util.h" +#include "ui/display/display_util.h" #include "build/build_config.h" -#include "content/browser/renderer_host/render_widget_host_view_base.h" #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/gfx/icc_profile.h" -namespace content { +namespace display { // static -void DisplayUtil::DisplayToScreenInfo(display::ScreenInfo* screen_info, - const display::Display& display) { +void DisplayUtil::DisplayToScreenInfo(ScreenInfo* screen_info, + const Display& display) { screen_info->rect = display.bounds(); // TODO(husky): Remove any Android system controls from availableRect. screen_info->available_rect = display.work_area(); @@ -50,7 +49,7 @@ // TODO(crbug.com/1194700 and crbug.com/1182855): Use cross-process screen // info caches, not local-process info, for child frames and Mac's shim. - auto* screen = display::Screen::GetScreen(); + auto* screen = Screen::GetScreen(); // Some tests are run with no Screen initialized. screen_info->is_extended = screen && screen->GetNumDisplays() > 1; screen_info->is_primary = @@ -60,28 +59,27 @@ } // static -void DisplayUtil::GetDefaultScreenInfo(display::ScreenInfo* screen_info) { +void DisplayUtil::GetDefaultScreenInfo(ScreenInfo* screen_info) { return GetNativeViewScreenInfo(screen_info, nullptr); } // static -void DisplayUtil::GetNativeViewScreenInfo(display::ScreenInfo* screen_info, +void DisplayUtil::GetNativeViewScreenInfo(ScreenInfo* screen_info, gfx::NativeView native_view) { // Some tests are run with no Screen initialized. - display::Screen* screen = display::Screen::GetScreen(); + Screen* screen = Screen::GetScreen(); if (!screen) { - *screen_info = display::ScreenInfo(); + *screen_info = ScreenInfo(); return; } - display::Display display = native_view - ? screen->GetDisplayNearestView(native_view) - : screen->GetPrimaryDisplay(); + Display display = native_view ? screen->GetDisplayNearestView(native_view) + : screen->GetPrimaryDisplay(); DisplayToScreenInfo(screen_info, display); } // static -display::mojom::ScreenOrientation DisplayUtil::GetOrientationTypeForMobile( - const display::Display& display) { +mojom::ScreenOrientation DisplayUtil::GetOrientationTypeForMobile( + const Display& display) { int angle = display.PanelRotationAsDegree(); const gfx::Rect& bounds = display.bounds(); @@ -94,30 +92,26 @@ switch (angle) { case 0: - return natural_portrait - ? display::mojom::ScreenOrientation::kPortraitPrimary - : display::mojom::ScreenOrientation::kLandscapePrimary; + return natural_portrait ? mojom::ScreenOrientation::kPortraitPrimary + : mojom::ScreenOrientation::kLandscapePrimary; case 90: - return natural_portrait - ? display::mojom::ScreenOrientation::kLandscapePrimary - : display::mojom::ScreenOrientation::kPortraitSecondary; + return natural_portrait ? mojom::ScreenOrientation::kLandscapePrimary + : mojom::ScreenOrientation::kPortraitSecondary; case 180: - return natural_portrait - ? display::mojom::ScreenOrientation::kPortraitSecondary - : display::mojom::ScreenOrientation::kLandscapeSecondary; + return natural_portrait ? mojom::ScreenOrientation::kPortraitSecondary + : mojom::ScreenOrientation::kLandscapeSecondary; case 270: - return natural_portrait - ? display::mojom::ScreenOrientation::kLandscapeSecondary - : display::mojom::ScreenOrientation::kPortraitPrimary; + return natural_portrait ? mojom::ScreenOrientation::kLandscapeSecondary + : mojom::ScreenOrientation::kPortraitPrimary; default: NOTREACHED(); - return display::mojom::ScreenOrientation::kPortraitPrimary; + return mojom::ScreenOrientation::kPortraitPrimary; } } // static -display::mojom::ScreenOrientation DisplayUtil::GetOrientationTypeForDesktop( - const display::Display& display) { +mojom::ScreenOrientation DisplayUtil::GetOrientationTypeForDesktop( + const Display& display) { static int primary_landscape_angle = -1; static int primary_portrait_angle = -1; @@ -133,13 +127,13 @@ if (is_portrait) { return primary_portrait_angle == angle - ? display::mojom::ScreenOrientation::kPortraitPrimary - : display::mojom::ScreenOrientation::kPortraitSecondary; + ? mojom::ScreenOrientation::kPortraitPrimary + : mojom::ScreenOrientation::kPortraitSecondary; } return primary_landscape_angle == angle - ? display::mojom::ScreenOrientation::kLandscapePrimary - : display::mojom::ScreenOrientation::kLandscapeSecondary; + ? mojom::ScreenOrientation::kLandscapePrimary + : mojom::ScreenOrientation::kLandscapeSecondary; } -} // namespace content +} // namespace display
diff --git a/content/browser/renderer_host/display_util.h b/ui/display/display_util.h similarity index 77% rename from content/browser/renderer_host/display_util.h rename to ui/display/display_util.h index 520dad6..6a02e80b 100644 --- a/content/browser/renderer_host/display_util.h +++ b/ui/display/display_util.h
@@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CONTENT_BROWSER_RENDERER_HOST_DISPLAY_UTIL_H_ -#define CONTENT_BROWSER_RENDERER_HOST_DISPLAY_UTIL_H_ +#ifndef UI_DISPLAY_DISPLAY_UTIL_H_ +#define UI_DISPLAY_DISPLAY_UTIL_H_ -#include "content/common/content_export.h" #include "ui/display/display.h" +#include "ui/display/display_export.h" #include "ui/display/screen_info.h" #include "ui/gfx/native_widget_types.h" -namespace content { +namespace display { -class CONTENT_EXPORT DisplayUtil { +class DISPLAY_EXPORT DisplayUtil { public: static void DisplayToScreenInfo(display::ScreenInfo* screen_info, const display::Display& display); @@ -31,6 +31,6 @@ const display::Display& display); }; -} // namespace content +} // namespace display -#endif // CONTENT_BROWSER_RENDERER_HOST_DISPLAY_UTIL_H_ +#endif // UI_DISPLAY_DISPLAY_UTIL_H_
diff --git a/ui/events/ozone/evdev/event_device_info.cc b/ui/events/ozone/evdev/event_device_info.cc index bf56271..6dc22e9 100644 --- a/ui/events/ozone/evdev/event_device_info.cc +++ b/ui/events/ozone/evdev/event_device_info.cc
@@ -39,10 +39,12 @@ {0x045e, 0x082f}, // Microsoft Bluetooth Mouse {0x045e, 0x0b05}, // Xbox One Elite Series 2 gamepad {0x046d, 0x4069}, // Logitech MX Master 2S (Unifying) // nocheck + {0x046d, 0x4072}, // Logitech MX Anywhere 2 (Unifying) {0x046d, 0xb00d}, // Logitech T630 Ultrathin {0x046d, 0xb011}, // Logitech M558 {0x046d, 0xb016}, // Logitech M535 {0x046d, 0xb019}, // Logitech MX Master 2S (Bluetooth) // nocheck + {0x046d, 0xb01f}, // Logitech MX Anywhere 2 (Bluetooth) {0x046d, 0xb503}, // Logitech Spotlight Presentation Remote (Bluetooth) {0x046d, 0xc093}, // Logitech M500s {0x046d, 0xc53e}, // Logitech Spotlight Presentation Remote (USB dongle) @@ -55,6 +57,7 @@ {0x1038, 0x1830}, // SteelSeries Rival 3 Wireless (USB dongle) {0x1050, 0x0010}, // Yubico.com Yubikey {0x1050, 0x0407}, // Yubico.com Yubikey 4 OTP+U2F+CCID + {0x17ef, 0x6123}, // Lenovo USB-C Wired Compact Mouse {0x1b1c, 0x1b94}, // Corsair Katar Pro Wireless (USB dongle) {0x1bae, 0x1b1c}, // Corsair Katar Pro Wireless (Bluetooth) {0x1bcf, 0x08a0}, // Kensington Pro Fit Full-size
diff --git a/ui/file_manager/file_manager/background/js/crostini.js b/ui/file_manager/file_manager/background/js/crostini.js index 66ad8be..012cb82 100644 --- a/ui/file_manager/file_manager/background/js/crostini.js +++ b/ui/file_manager/file_manager/background/js/crostini.js
@@ -234,6 +234,13 @@ return false; } + // Cannot share root of Shared with me since it represents 2 dirs: + // `.files-by-id` and `.shortcut-targets-by-id`. + if (root === VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME && + entry.fullPath === '/') { + return false; + } + return CrostiniImpl.VALID_ROOT_TYPES_FOR_SHARE.has(root); } } @@ -263,6 +270,7 @@ [VolumeManagerCommon.RootType.DRIVE, 'MyDrive'], [VolumeManagerCommon.RootType.SHARED_DRIVES_GRAND_ROOT, 'TeamDrive'], [VolumeManagerCommon.RootType.SHARED_DRIVE, 'TeamDrive'], + [VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME, 'SharedWithMe'], [VolumeManagerCommon.RootType.CROSTINI, 'Crostini'], [VolumeManagerCommon.RootType.ARCHIVE, 'Archive'], [VolumeManagerCommon.RootType.SMB, 'SMB'],
diff --git a/ui/file_manager/file_manager/background/js/crostini_unittest.m.js b/ui/file_manager/file_manager/background/js/crostini_unittest.m.js index 33a63f9..1f2ba6a 100644 --- a/ui/file_manager/file_manager/background/js/crostini_unittest.m.js +++ b/ui/file_manager/file_manager/background/js/crostini_unittest.m.js
@@ -176,13 +176,14 @@ const allowed = [ 'downloads', 'removable', 'android_files', 'drive', - 'shared_drives_grand_root', 'team_drive' + 'shared_drives_grand_root', 'team_drive', 'drive_shared_with_me' ]; for (const type of allowed) { volumeManagerRootType = type; // TODO(crbug.com/958840): Sharing Play files root is disallowed until // we can ensure it will not also share Downloads. - if (type === 'android_files') { + // We don't share 'Shared with me' root since it is fake. + if (['android_files', 'drive_shared_with_me'].includes(type)) { assertFalse(crostini.canSharePath('vm', root, true)); assertFalse(crostini.canSharePath('vm', root, false)); } else {
diff --git a/ui/views/animation/animation_builder.cc b/ui/views/animation/animation_builder.cc index 29e596a..2247d61 100644 --- a/ui/views/animation/animation_builder.cc +++ b/ui/views/animation/animation_builder.cc
@@ -4,6 +4,7 @@ #include "ui/views/animation/animation_builder.h" +#include "base/containers/contains.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animation_sequence.h" #include "ui/compositor/layer_animator.h" @@ -89,6 +90,16 @@ return *this; } +void AnimationBuilder::OnStarted(base::OnceClosure callback) {} + +void AnimationBuilder::OnEnded(base::OnceClosure callback) {} + +void AnimationBuilder::OnWillRepeat(base::RepeatingClosure callback) {} + +void AnimationBuilder::OnAborted(base::OnceClosure callback) {} + +void AnimationBuilder::OnScheduled(base::OnceClosure callback) {} + void AnimationBuilder::CreateNewEntry(const AnimationKey& key) { auto new_sequence = std::make_unique<ui::LayerAnimationSequence>(); new_sequence->set_is_repeating(is_sequence_repeating_); @@ -106,4 +117,41 @@ animation_sequences_[key].back()->AddElement(std::move(element)); } +AnimationBuilder::AnimationBuilderObserver::AnimationBuilderObserver() = + default; + +AnimationBuilder::AnimationBuilderObserver::~AnimationBuilderObserver() { + Reset(); +} + +void AnimationBuilder::AnimationBuilderObserver::ObserveAnimationSequence( + ui::LayerAnimationSequence* sequence) { + DCHECK(!base::Contains(sequences_, sequence, + &base::WeakPtr<ui::LayerAnimationSequence>::get)); + sequence->AddObserver(this); + sequences_.emplace_back(sequence->AsWeakPtr()); +} + +void AnimationBuilder::AnimationBuilderObserver::OnLayerAnimationStarted( + ui::LayerAnimationSequence* sequence) {} + +void AnimationBuilder::AnimationBuilderObserver::OnLayerAnimationEnded( + ui::LayerAnimationSequence* sequence) {} + +void AnimationBuilder::AnimationBuilderObserver::OnLayerAnimationWillRepeat( + ui::LayerAnimationSequence* sequence) {} + +void AnimationBuilder::AnimationBuilderObserver::OnLayerAnimationAborted( + ui::LayerAnimationSequence* sequence) {} + +void AnimationBuilder::AnimationBuilderObserver::OnLayerAnimationScheduled( + ui::LayerAnimationSequence* sequence) {} + +void AnimationBuilder::AnimationBuilderObserver::Reset() { + for (auto& sequence : sequences_) { + if (sequence.get()) + sequence.get()->RemoveObserver(this); + } +} + } // namespace views
diff --git a/ui/views/animation/animation_builder.h b/ui/views/animation/animation_builder.h index d2611ee..2091ac9 100644 --- a/ui/views/animation/animation_builder.h +++ b/ui/views/animation/animation_builder.h
@@ -10,15 +10,14 @@ #include <utility> #include <vector> +#include "base/callback_forward.h" +#include "base/scoped_observation.h" #include "ui/compositor/layer_animation_element.h" +#include "ui/compositor/layer_animation_observer.h" +#include "ui/compositor/layer_animation_sequence.h" #include "ui/views/view.h" #include "ui/views/views_export.h" -namespace ui { -class LayerAnimationSequence; -class LayerAnimationElement; -} // namespace ui - namespace views { // This AnimationBuilder API is currently in the experimental phase and only @@ -41,12 +40,50 @@ AnimationBuilder& NewSequence(); AnimationBuilder& EndSequence(); + // Called when the animation starts. + void OnStarted(base::OnceClosure callback); + // Called when the animation ends. Not called if animation is aborted. + void OnEnded(base::OnceClosure callback); + // Called when a sequence repetition ends and will repeat. Not called if + // sequence is aborted. + void OnWillRepeat(base::RepeatingClosure callback); + // Called if animation is aborted for any reason. Should never do anything + // that may cause another animation to be started. + void OnAborted(base::OnceClosure callback); + // Called when the animation is scheduled. + void OnScheduled(base::OnceClosure callback); + private: // We may want to change this to our own struct. using AnimationKey = std::pair<View*, ui::LayerAnimationElement::AnimatableProperty>; + class AnimationBuilderObserver : ui::LayerAnimationObserver { + public: + AnimationBuilderObserver(); + AnimationBuilderObserver(const AnimationBuilderObserver&) = delete; + AnimationBuilderObserver& operator=(const AnimationBuilderObserver&) = + delete; + ~AnimationBuilderObserver() override; + + void ObserveAnimationSequence(ui::LayerAnimationSequence* sequence); + + void OnLayerAnimationStarted(ui::LayerAnimationSequence* sequence) override; + void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override; + void OnLayerAnimationWillRepeat( + ui::LayerAnimationSequence* sequence) override; + void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override; + void OnLayerAnimationScheduled( + ui::LayerAnimationSequence* sequence) override; + + private: + void Reset(); + + std::vector<base::WeakPtr<ui::LayerAnimationSequence>> sequences_; + }; + void CreateNewEntry(const AnimationKey& key); + void AddAnimation(const AnimationKey& key, std::unique_ptr<ui::LayerAnimationElement> element); @@ -57,6 +94,8 @@ base::TimeDelta duration_ = base::TimeDelta::FromSeconds(1); bool is_sequence_repeating_ = false; + + std::unique_ptr<AnimationBuilderObserver> animation_observer_; }; } // namespace views
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/PageInfoControllerDelegateImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/PageInfoControllerDelegateImpl.java index 3eb342b..ec90806f 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/PageInfoControllerDelegateImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/PageInfoControllerDelegateImpl.java
@@ -104,7 +104,7 @@ @Override @Nullable public PageInfoSubpageController createHistoryController( - PageInfoMainController mainController, PageInfoRowView rowView, String host) { + PageInfoMainController mainController, PageInfoRowView rowView) { return null; }